Skip to content

Commit

Permalink
feat: clone preview as getting-started (wpengine#117)
Browse files Browse the repository at this point in the history
* refactor: clone preview folder as getting-started

We plan to then simplify the preview example in
a future PR.

getting-started will serve as the full framework
demo from this point on.

* chore: remove dev-lerna script for preview example

We only want packages/headless and
examples/getting-started to build when doing
`npm run dev` from the project root.

Otherwise Next spins examples/preview and
examples/getting-started up and there's a port
collision on 3000.

An alternative is to spin up examples on different
ports, but this seems excessive, particularly if
the examples folder grows.

* docs: update install steps to use getting-started
  • Loading branch information
nickcernis authored Feb 3, 2021
1 parent 4f235b1 commit b009ab8
Show file tree
Hide file tree
Showing 42 changed files with 11,377 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Eager to try out the Headless Framework? Here's how you can get started:
1. Create a WordPress site if you haven't already. We recommend using [Local](https://localwp.com/)!
2. Download, upload, and activate the `wpe-headless` plugin. [(Plugin Download)](https://wp-product-info.wpesvc.net/v1/plugins/wpe-headless?download)
3. Install [WP GraphQL](https://wordpress.org/plugins/wp-graphql/) on the WordPress site if it's not already installed.
4. Create a new Next.js app from our [example project](https://github.com/wpengine/headless-framework/tree/canary/examples/preview): `npx create-next-app -e https://github.com/wpengine/headless-framework/tree/canary --example-path examples/preview --use-npm`
4. Create a new Next.js app from our [getting-started project](https://github.com/wpengine/headless-framework/tree/canary/examples/getting-started): `npx create-next-app -e https://github.com/wpengine/headless-framework/tree/canary --example-path examples/getting-started --use-npm`
6. `cp .env.local.sample .env.local`
7. Populate `WORDPRESS_URL` in `.env.local` with the full URL to your WordPress site, including the `http://` or `https://` prefix.
8. Populate `WPE_HEADLESS_SECRET` in `.env.local` with the secret key found at Settings → Headless in your WordPress admin area.
Expand Down
13 changes: 13 additions & 0 deletions examples/getting-started/.env.local.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Either WORDPRESS_URL or NEXT_PUBLIC_WORDPRESS_URL need to be populated. Not both!
#
# (Recommended) Setting WORDPRESS_URL instead of NEXT_PUBLIC_WORDPRESS_URL will limit requests to the WordPress backend
# to only come from the Node.js server.
#
# Setting NEXT_PUBLIC_WORDPRESS_URL instead of WORDPRESS_URL will allow requests to come from the client-side which may
# reduce site performance and put extra load on the WordPress backend.

WORDPRESS_URL=http://yourwpsite.com
# NEXT_PUBLIC_WORDPRESS_URL=http://yourwpsite.com

# Plugin secret found in WordPress Settings->Headless
WPE_HEADLESS_SECRET=YOUR_PLUGIN_SECRET
55 changes: 55 additions & 0 deletions examples/getting-started/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports = {
env: {
browser: true,
es6: true,
node: true,
amd: true,
},
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'airbnb-typescript',
'airbnb/hooks',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
ecmaFeatures: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
jsx: true,
},
},
plugins: ['react', 'react-hooks', 'simple-import-sort'],
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
'import/no-extraneous-dependencies': 0,
'@typescript-eslint/unbound-method': 0,
'no-void': 0,
'import/named': 0,
'import/prefer-default-export': 0,
'react/jsx-closing-bracket-location': 0,
'react/jsx-wrap-multilines': [
'error',
{ declaration: false, assignment: false },
],
'react/require-default-props': 0,
'jsx-a11y/anchor-is-valid': 0,
},
settings: {
react: {
createClass: 'createReactClass', // Regex for Component Factory to use,
// default to "createReactClass"
pragma: 'React', // Pragma to use, default to "React"
version: '17.0', // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
},
},
};
65 changes: 65 additions & 0 deletions examples/getting-started/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
Dockerfile eol=lf
*.sh eol=lf

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary

###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
8 changes: 8 additions & 0 deletions examples/getting-started/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules

.next
.env
.env.*
!.env*.sample

wpe.json
10 changes: 10 additions & 0 deletions examples/getting-started/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
arrowParens: 'always',
jsxBracketSameLine: true,
singleQuote: true,
tabWidth: 2,
semi: true,
trailingComma: 'all',
endOfLine: 'lf',
useTabs: false,
};
23 changes: 23 additions & 0 deletions examples/getting-started/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Headless WordPress Previews Example

[Preview Documentation](../../docs/previews/README.md)

# Configuration

## WordPress

Install the latest plugin for this project and [WPGraphQL](https://wordpress.org/plugins/wp-graphql/)

## Example Project

The framework expects a few environment variables. Copy `.env.local.sample` to `.env.local` and fill out the variables
accordingly.

## Run it

```bash
npm i
npm run dev
```

[http://localhost:3000]()
4 changes: 4 additions & 0 deletions examples/getting-started/assets/logos/mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions examples/getting-started/assets/logos/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions examples/getting-started/components/CTA.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import styles from 'scss/components/CTA.module.scss';
import Heading, { HeadingProps } from './Heading';

interface Props {
title: string;
buttonText?: string;
buttonURL?: string;
children?: React.ReactNode;
headingLevel?: HeadingProps['level'];
}

function CTA({
title = 'Get in touch',
buttonText,
buttonURL,
children,
headingLevel = 'h1',
}: Props): JSX.Element {
return (
<section className={styles.cta}>
<div className={styles.wrap}>
<Heading level={headingLevel} className={styles.title}>
{title}
</Heading>
<div className={styles.intro}>
<div className={styles.children}>{children}</div>
{buttonText && buttonURL && (
<div className={styles['button-wrap']}>
<a href={buttonURL} className="button">
{buttonText}
</a>
</div>
)}
</div>
</div>
</section>
);
}

export default CTA;
20 changes: 20 additions & 0 deletions examples/getting-started/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import styles from 'scss/components/Footer.module.scss';

interface Props {
copyrightHolder?: string;
}

function Footer({ copyrightHolder = 'Company Name' }: Props): JSX.Element {
const year = new Date().getFullYear();

return (
<footer className={styles.main}>
<div className={styles.wrap}>
<p>{${year} ${copyrightHolder}. All rights reserved.`}</p>
</div>
</footer>
);
}

export default Footer;
78 changes: 78 additions & 0 deletions examples/getting-started/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import { WPHead } from '@wpengine/headless';
import styles from 'scss/components/Header.module.scss';
import Link from 'next/link';
import Head from 'next/head';

interface Props {
title?: string;
description?: string;
}

function Header({
title = 'Headless by WP Engine',
description,
}: Props): JSX.Element {
// TODO: accept a `menuItems` prop to receive menu items from WordPress.
const menuItems = [
{ title: 'Home', href: '/' },
{ title: 'About', href: '/about/' },
{
title: 'GitHub',
href: 'https://github.com/wpengine/headless-framework',
class: 'button',
},
];

return (
<>
<Head>
<title>{/* Title is required here but replaced by WPHead. */}</title>
{/* Add extra elements to <head> here. */}
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="anonymous"
/>
<link
rel="preload"
as="style"
href="https://fonts.googleapis.com/css2?display=swap&amp;family=Public%20Sans%3Aital%2Cwght%400%2C100..900%3B1%2C100..900&amp;subset=latin%2Clatin-ext"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?display=swap&amp;family=Public%20Sans%3Aital%2Cwght%400%2C100..900%3B1%2C100..900&amp;subset=latin%2Clatin-ext"
type="text/css"
media="all"
/>
</Head>
<WPHead />
<header>
<div className={styles.wrap}>
<div className={styles['title-wrap']}>
<p className={styles['site-title']}>
<Link href="/">
<a>{title}</a>
</Link>
</p>
{description && <p className={styles.description}>{description}</p>}
</div>
<div className={styles.menu}>
<ul>
{menuItems &&
menuItems.map((item) => (
<li key={`${item.title}$-menu`}>
<Link href={item.href}>
<a className={item?.class}>{item.title}</a>
</Link>
</li>
))}
</ul>
</div>
</div>
</header>
</>
);
}

export default Header;
21 changes: 21 additions & 0 deletions examples/getting-started/components/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

// HeadingProps constrains headings to levels h1-h6.
interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
level: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
}

// Heading allows components to pass a heading level via props.
function Heading({
level = 'h1',
children,
className,
}: HeadingProps): JSX.Element {
const H = ({ ...props }: React.HTMLAttributes<HTMLHeadingElement>) =>
React.createElement(level, props, children);

return <H className={className}>{children}</H>;
}

export default Heading;
export type { HeadingProps };
Loading

0 comments on commit b009ab8

Please sign in to comment.