├── .editoconfig
├── .eslintrc.json
├── .gitignore
├── .nvmrc
├── .prettierignore
├── .prettierrc
├── LICENSE
├── README.md
├── config.js
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── gatsby
├── createCategories.js
├── createPages.js
├── createPosts.js
├── createTags.js
└── createUsers.js
├── img
├── screenshot-demo.gatsby-wpgraphql-blog-example.netlify.com.png
└── screenshot-demo.wpgraphql.com.png
├── package-lock.json
├── package.json
├── src
├── components
│ ├── CategoriesWidget
│ │ └── index.js
│ ├── HomepageLayout
│ │ └── index.js
│ ├── PostEntry
│ │ └── index.js
│ ├── PostEntryMeta
│ │ └── index.js
│ ├── RecentCommentsWidget
│ │ └── index.js
│ ├── RecentPostsWidget
│ │ └── index.js
│ ├── Seo
│ │ └── index.js
│ ├── SiteHeader
│ │ └── index.js
│ ├── SiteLayout.js
│ ├── SiteMenu
│ │ └── index.js
│ └── style.css
├── images
│ ├── gatsby-astronaut.png
│ ├── gatsby-icon.png
│ ├── gatsby-logo.png
│ └── wpgraphql-logo.png
├── layouts
│ └── SiteLayout
│ │ └── index.js
├── pages
│ └── 404.js
├── templates
│ ├── blog.js
│ ├── categoriesArchive.js
│ ├── category.js
│ ├── page.js
│ ├── post.js
│ ├── tag.js
│ ├── tagsArchive.js
│ └── user.js
└── utils
│ └── index.js
└── yarn.lock
/.editoconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "google",
5 | "eslint:recommended",
6 | "plugin:flowtype/recommended",
7 | "plugin:react/recommended",
8 | "prettier",
9 | "prettier/flowtype",
10 | "prettier/react"
11 | ],
12 | "plugins": ["flowtype", "prettier", "react"],
13 | "parserOptions": {
14 | "ecmaVersion": 2016,
15 | "sourceType": "module",
16 | "ecmaFeatures": {
17 | "jsx": true
18 | }
19 | },
20 | "env": {
21 | "browser": true,
22 | "es6": true,
23 | "node": true,
24 | "jest": true
25 | },
26 | "globals": {
27 | "before": true,
28 | "spyOn": true,
29 | "__PATH_PREFIX__": true
30 | },
31 | "rules": {
32 | "arrow-body-style": [
33 | "error",
34 | "as-needed",
35 | { "requireReturnForObjectLiteral": true }
36 | ],
37 | "consistent-return": ["error"],
38 | "no-console": "off",
39 | "no-inner-declarations": "off",
40 | "prettier/prettier": "error",
41 | "quotes": ["error", "backtick"],
42 | "react/display-name": "off",
43 | "react/jsx-key": "warn",
44 | "react/no-unescaped-entities": "warn",
45 | "react/prop-types": "off",
46 | "require-jsdoc": "off",
47 | "valid-jsdoc": "off"
48 | },
49 | "overrides": [
50 | {
51 | "files": [
52 | "packages/**/gatsby-browser.js",
53 | "packages/gatsby/cache-dir/**/*"
54 | ],
55 | "env": {
56 | "browser": true
57 | },
58 | "globals": {
59 | "___loader": false,
60 | "___emitter": false
61 | }
62 | },
63 | {
64 | "files": ["**/cypress/integration/**/*", "**/cypress/support/**/*"],
65 | "globals": {
66 | "cy": false,
67 | "Cypress": false
68 | }
69 | }
70 | ],
71 | "settings": {
72 | "react": {
73 | "version": "16.4.2"
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # dotenv environment variables file
55 | .env
56 |
57 | # gatsby files
58 | .cache/
59 | public
60 |
61 | # Mac files
62 | .DS_Store
63 | .idea
64 |
65 | # Yarn
66 | yarn-error.log
67 | .pnp/
68 | .pnp.js
69 | # Yarn Integrity file
70 | .yarn-integrity
71 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 10.15.1
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.min.js
2 | **/node_modules/**
3 | flow-typed
4 |
5 | # webfont demo styles
6 | **/specimen_files
7 |
8 | # built sites
9 | benchmarks/**/public
10 | e2e-tests/**/public
11 | examples/**/public
12 | integration-tests/**/public
13 | www/public
14 |
15 | # cache-dirs
16 | **/.cache
17 |
18 | # ignore built packages
19 | packages/**/*.js
20 | !packages/gatsby/cache-dir/**/*.js
21 | !packages/*/src/**/*.js
22 | packages/gatsby/cache-dir/commonjs/**/*.js
23 |
24 | # fixtures
25 | **/__testfixtures__/**
26 | **/__tests__/fixtures/**
27 |
28 | infrastructure
29 |
30 | # coverage
31 | coverage
32 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": false,
4 | "tabWidth": 2,
5 | "trailingComma": "es5"
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 gatsbyjs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEPRECATED
2 | ----
3 | This repository serves as an example of how to build a Gatsby site using WordPress as the CMS, WPGraphQL as the API and Gatsby Source GraphQL as the data source.
4 |
5 | This example repo should no longer be considered "the best" way to use Gatsby and GraphQL anymore. Instead of using Gatsby Source GraphQL, we recommend using [Gatsby Source WordPress Experimental](https://github.com/gatsbyjs/gatsby-source-wordpress-experimental), which will soon become the official Gatsby Source WordPress.
6 |
7 | You can read more about why previous versions of Gatsby Source WordPress and Gatsby Source GraphQL are not ideal, and why Gatsby is investing in the new Gatsby Source WordPress Experimental plugin in this WPTavern article: https://wptavern.com/new-gatsby-source-wordpress-plugin-now-in-beta
8 |
9 | ----
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Gatsby + WPGraphQL Blog Example
21 |
22 |
23 | This is an example Gatsby site using WPGraphQL as the source.
24 |
25 | ## WordCamp Talk
26 | This repo was created specifically for showcasing the capabilities of WPGraphQL and how it can be used in many ways. One particular use is with GatsbyJS. The WordCamp talk this repo was created for can be seen here: https://wordpress.tv/2019/03/08/jason-bahl-building-static-sites-with-wordpress-gatsby-and-wpgraphql/
27 |
28 | ## Setup
29 |
30 | Quick video showing setup of the Gatsby site locally: https://www.youtube.com/watch?v=QkIuuZ5gZNk
31 |
32 | ## WordPress Source
33 |
34 | The WordPress where the content is managed lives here: [https://demo.wpgraphql.com](https://demo.wpgraphql.com)
35 |
36 | 
37 |
38 |
39 | ## Gatsby Site
40 |
41 | The Live Gatsby site is at: [https://gatsby-wpgraphql-blog-example.netlify.com/](https://gatsby-wpgraphql-blog-example.netlify.com/)
42 |
43 | 
44 |
45 | ### Features
46 |
47 | Below are features of the Gatsby site that are all sourced via WPGraphQL Queries, so the data is
48 | managed in WordPress, but is pulled into the Gatsby site and rendered there:
49 |
50 | - :white_check_mark: Menus
51 | - :white_check_mark: Pages
52 | - :white_check_mark: Paginated Blogroll/homepage
53 | - :white_check_mark: Single Posts
54 | - :white_check_mark: Authors
55 | - :white_check_mark: Categories
56 | - :white_check_mark: Tags
57 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | wordPressUrl: `https://demo.wpgraphql.com`,
3 | }
4 |
5 | export default config
6 |
--------------------------------------------------------------------------------
/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's Browser APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/browser-apis/
5 | */
6 |
7 | // You can delete this file if you're not using it
8 |
--------------------------------------------------------------------------------
/gatsby-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | siteMetadata: {
3 | title: `Gatsby WPGraphQL Source Demo`,
4 | description: `Gatsby demo site with WPGraphQL as the source.`,
5 | author: `@wpgraphql`,
6 | wordPressUrl: `https://wpgraphqldemo.wpengine.com`,
7 | },
8 | plugins: [
9 | // Include Ant Design component library.
10 | {
11 | resolve: `gatsby-plugin-antd`,
12 | options: {
13 | style: true,
14 | },
15 | },
16 | {
17 | resolve: `gatsby-plugin-less`,
18 | options: {
19 | javascriptEnabled: true,
20 | modifyVars: {
21 | // DEFAULTS FOR ANT DESIGN
22 | // Full list of variables can be found here:
23 | // https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
24 | // @primary-color: #1890ff;
25 | "layout-header-background": `#0e2339`,
26 | // primary color for all components
27 | "primary-color": `#1890ff`,
28 | // @link-color: #1890ff;
29 | "link-color": `#1890ff`,
30 | // @success-color: #52c41a;
31 | "success-color": `#52c41a`,
32 | // @warning-color: #faad14;
33 | "warning-color": `#faad14`,
34 | // @error-color: #f5222d;
35 | "error-color": `#f5222d`,
36 | // @font-size-base: 14px;
37 | // major text font size
38 | "font-size-base": `16px`,
39 | // @heading-color: rgba(0, 0, 0, .85);
40 | "heading-color": `rgba(0, 0, 0, .85)`,
41 | // @text-color: rgba(0, 0, 0, .65);
42 | "text-color": `rgba(0, 0, 0, .65)`,
43 | // @text-color-secondary : rgba(0, 0, 0, .45);
44 | "text-color-secondary": `rgba(0, 0, 0, .45)`,
45 | // @disabled-color : rgba(0, 0, 0, .25);
46 | "disabled-color": `rgba(0, 0, 0, .25)`,
47 | // @border-radius-base: 4px;
48 | "border-radius-base": `4px`,
49 | // @border-color-base: #d9d9d9;
50 | "border-color-base": `#d9d9d9`,
51 | // @box-shadow-base: 0 2px 8px rgba(0, 0, 0, .15);
52 | "box-shadow-base": `0 2px 8px rgba(0, 0, 0, .15)`,
53 | },
54 | },
55 | },
56 | // Setup WPGraphQL.com to be the source
57 | {
58 | resolve: `gatsby-source-graphql`,
59 | options: {
60 | // This type will contain remote schema Query type
61 | typeName: `WPGraphQL`,
62 | // This is field under which it's accessible
63 | fieldName: `wpgraphql`,
64 | // Url to query from
65 | url: `https://demo.wpgraphql.com/graphql`,
66 | },
67 | },
68 | `gatsby-plugin-react-helmet`,
69 | {
70 | resolve: `gatsby-source-filesystem`,
71 | options: {
72 | name: `images`,
73 | path: `${__dirname}/src/images`,
74 | },
75 | },
76 | `gatsby-transformer-sharp`,
77 | `gatsby-plugin-sharp`,
78 | {
79 | resolve: `gatsby-plugin-manifest`,
80 | options: {
81 | name: `gatsby-wpgraphql-starter`,
82 | short_name: `starter`,
83 | start_url: `/`,
84 | background_color: `#f0f2f5`,
85 | theme_color: `#001529`,
86 | display: `minimal-ui`,
87 | icon: `src/images/wpgraphql-logo.png`, // This path is relative to the root of the site.
88 | },
89 | },
90 | // this (optional) plugin enables Progressive Web App + Offline functionality
91 | // To learn more, visit: https://gatsby.app/offline
92 | `gatsby-plugin-offline`,
93 | ],
94 | }
95 |
--------------------------------------------------------------------------------
/gatsby-node.js:
--------------------------------------------------------------------------------
1 | const createPosts = require(`./gatsby/createPosts`)
2 | const createPages = require(`./gatsby/createPages`)
3 | const createUsers = require(`./gatsby/createUsers`)
4 | const createCategories = require(`./gatsby/createCategories`)
5 | const createTags = require(`./gatsby/createTags`)
6 |
7 | exports.createPages = async ({ actions, graphql }) => {
8 | await createPosts({ actions, graphql })
9 | await createPages({ actions, graphql })
10 | await createUsers({ actions, graphql })
11 | await createCategories({ actions, graphql })
12 | await createTags({ actions, graphql })
13 | }
14 |
--------------------------------------------------------------------------------
/gatsby-ssr.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/
5 | */
6 |
7 | // You can delete this file if you're not using it
8 |
--------------------------------------------------------------------------------
/gatsby/createCategories.js:
--------------------------------------------------------------------------------
1 | const path = require(`path`)
2 | module.exports = async ({ actions, graphql }) => {
3 | const GET_CATEGORIES = `
4 | query GET_CATEGORIES($first: Int, $after: String) {
5 | wpgraphql {
6 | categories(first: $first, after: $after) {
7 | pageInfo {
8 | hasNextPage
9 | endCursor
10 | }
11 | nodes {
12 | id
13 | categoryId
14 | slug
15 | }
16 | }
17 | }
18 | }
19 | `
20 | const { createPage } = actions
21 | const allTags = []
22 | const fetchTags = async variables =>
23 | await graphql(GET_CATEGORIES, variables).then(({ data }) => {
24 | const {
25 | wpgraphql: {
26 | categories: {
27 | nodes,
28 | pageInfo: { hasNextPage, endCursor },
29 | },
30 | },
31 | } = data
32 | nodes.map(category => {
33 | allTags.push(category)
34 | })
35 | if (hasNextPage) {
36 | return fetchTags({ first: 100, after: endCursor })
37 | }
38 | return allTags
39 | })
40 |
41 | await fetchTags({ first: 100, after: null }).then(allTags => {
42 | const categoryTemplate = path.resolve(`./src/templates/category.js`)
43 |
44 | allTags.map(category => {
45 | console.log(`create category: ${category.slug}`)
46 | createPage({
47 | path: `/blog/category/${category.slug}`,
48 | component: categoryTemplate,
49 | context: category,
50 | })
51 | })
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/gatsby/createPages.js:
--------------------------------------------------------------------------------
1 | const path = require(`path`)
2 | module.exports = async ({ actions, graphql }) => {
3 | const GET_PAGES = `
4 | query GET_PAGES($first:Int $after:String){
5 | wpgraphql {
6 | pages(
7 | first: $first
8 | after: $after
9 | where: {
10 | parent: null
11 | }
12 | ) {
13 | pageInfo {
14 | endCursor
15 | hasNextPage
16 | }
17 | nodes {
18 | id
19 | uri
20 | pageId
21 | title
22 | }
23 | }
24 | }
25 | }
26 | `
27 | const { createPage } = actions
28 | const allPages = []
29 | const fetchPages = async variables =>
30 | await graphql(GET_PAGES, variables).then(({ data }) => {
31 | const {
32 | wpgraphql: {
33 | pages: {
34 | nodes,
35 | pageInfo: { hasNextPage, endCursor },
36 | },
37 | },
38 | } = data
39 | nodes.map(page => {
40 | allPages.push(page)
41 | })
42 | if (hasNextPage) {
43 | return fetchPages({ first: variables.first, after: endCursor })
44 | }
45 | return allPages
46 | })
47 |
48 | await fetchPages({ first: 100, after: null }).then(allPages => {
49 | const pageTemplate = path.resolve(`./src/templates/page.js`)
50 |
51 | allPages.map(page => {
52 | console.log(`create page: ${page.uri}`)
53 | createPage({
54 | path: `/${page.uri}`,
55 | component: pageTemplate,
56 | context: page,
57 | })
58 | })
59 | })
60 | }
61 |
--------------------------------------------------------------------------------
/gatsby/createPosts.js:
--------------------------------------------------------------------------------
1 | const path = require(`path`)
2 | module.exports = async ({ actions, graphql }) => {
3 | const GET_POSTS = `
4 | query GET_POSTS($first:Int $after:String){
5 | wpgraphql {
6 | posts(
7 | first: $first
8 | after:$after
9 | ) {
10 | pageInfo {
11 | endCursor
12 | hasNextPage
13 | }
14 | nodes {
15 | id
16 | uri
17 | postId
18 | title
19 | }
20 | }
21 | }
22 | }
23 | `
24 | const { createPage } = actions
25 | const allPosts = []
26 | const blogPages = []
27 | let pageNumber = 0
28 | const fetchPosts = async variables =>
29 | await graphql(GET_POSTS, variables).then(({ data }) => {
30 | const {
31 | wpgraphql: {
32 | posts: {
33 | nodes,
34 | pageInfo: { hasNextPage, endCursor },
35 | },
36 | },
37 | } = data
38 |
39 | const nodeIds = nodes.map(node => node.postId)
40 | const blogTemplate = path.resolve(`./src/templates/blog.js`)
41 | const blogPagePath = !variables.after ? `/` : `/page/${pageNumber}`
42 |
43 | blogPages[pageNumber] = {
44 | path: blogPagePath,
45 | component: blogTemplate,
46 | context: {
47 | ids: nodeIds,
48 | pageNumber: pageNumber,
49 | hasNextPage: hasNextPage,
50 | },
51 | ids: nodeIds,
52 | }
53 | nodes.map(post => {
54 | allPosts.push(post)
55 | })
56 | if (hasNextPage) {
57 | pageNumber++
58 | return fetchPosts({ first: 12, after: endCursor })
59 | }
60 | return allPosts
61 | })
62 |
63 | await fetchPosts({ first: 12, after: null }).then(allPosts => {
64 | const postTemplate = path.resolve(`./src/templates/post.js`)
65 |
66 | blogPages.map(blogPage => {
67 | console.log(`createBlogPage ${blogPage.context.pageNumber}`)
68 | createPage(blogPage)
69 | })
70 |
71 | allPosts.map(post => {
72 | console.log(`create post: ${post.uri}`)
73 | createPage({
74 | path: `/blog/${post.uri}/`,
75 | component: postTemplate,
76 | context: post,
77 | })
78 | })
79 | })
80 | }
81 |
--------------------------------------------------------------------------------
/gatsby/createTags.js:
--------------------------------------------------------------------------------
1 | const path = require(`path`)
2 | module.exports = async ({ actions, graphql }) => {
3 | const GET_TAGS = `
4 | query GET_TAGS($first: Int, $after: String) {
5 | wpgraphql {
6 | tags(first: $first, after: $after) {
7 | pageInfo {
8 | hasNextPage
9 | endCursor
10 | }
11 | nodes {
12 | id
13 | tagId
14 | slug
15 | }
16 | }
17 | }
18 | }
19 | `
20 | const { createPage } = actions
21 | const allTags = []
22 | const fetchTags = async variables =>
23 | await graphql(GET_TAGS, variables).then(({ data }) => {
24 | const {
25 | wpgraphql: {
26 | tags: {
27 | nodes,
28 | pageInfo: { hasNextPage, endCursor },
29 | },
30 | },
31 | } = data
32 | nodes.map(tag => {
33 | allTags.push(tag)
34 | })
35 | if (hasNextPage) {
36 | return fetchTags({ first: 100, after: endCursor })
37 | }
38 | return allTags
39 | })
40 |
41 | await fetchTags({ first: 100, after: null }).then(allTags => {
42 | const tagTemplate = path.resolve(`./src/templates/tag.js`)
43 |
44 | allTags.map(tag => {
45 | console.log(`create tag: ${tag.slug}`)
46 | createPage({
47 | path: `/blog/tag/${tag.slug}`,
48 | component: tagTemplate,
49 | context: tag,
50 | })
51 | })
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/gatsby/createUsers.js:
--------------------------------------------------------------------------------
1 | const path = require(`path`)
2 | module.exports = async ({ actions, graphql }) => {
3 | const GET_USERS = `
4 | query GET_USERS($first: Int) {
5 | wpgraphql {
6 | users(first: $first) {
7 | pageInfo {
8 | hasNextPage
9 | endCursor
10 | }
11 | nodes {
12 | id
13 | userId
14 | slug
15 | }
16 | }
17 | }
18 | }
19 | `
20 | const { createPage } = actions
21 | const allUsers = []
22 | const fetchUsers = async variables =>
23 | await graphql(GET_USERS, variables).then(({ data }) => {
24 | const {
25 | wpgraphql: {
26 | users: {
27 | nodes,
28 | pageInfo: { hasNextPage, endCursor },
29 | },
30 | },
31 | } = data
32 | nodes.map(user => {
33 | allUsers.push(user)
34 | })
35 | if (hasNextPage) {
36 | return fetchUsers({ first: 100, after: endCursor })
37 | }
38 | return allUsers
39 | })
40 |
41 | await fetchUsers({ first: 100, after: null }).then(allUsers => {
42 | const userTemplate = path.resolve(`./src/templates/user.js`)
43 |
44 | allUsers.map(user => {
45 | console.log(`create user: ${user.slug}`)
46 | createPage({
47 | path: `/author/${user.slug}`,
48 | component: userTemplate,
49 | context: user,
50 | })
51 | })
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/img/screenshot-demo.gatsby-wpgraphql-blog-example.netlify.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/img/screenshot-demo.gatsby-wpgraphql-blog-example.netlify.com.png
--------------------------------------------------------------------------------
/img/screenshot-demo.wpgraphql.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/img/screenshot-demo.wpgraphql.com.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-starter-default",
3 | "private": true,
4 | "description": "A simple starter to get up and developing quickly with Gatsby",
5 | "version": "0.1.0",
6 | "author": "Kyle Mathews ",
7 | "dependencies": {
8 | "antd": "^3.12.3",
9 | "babel-eslint": "^10.0.1",
10 | "eslint": "^5.6.1",
11 | "eslint-config-google": "^0.10.0",
12 | "eslint-config-prettier": "^3.1.0",
13 | "eslint-plugin-flow-vars": "^0.5.0",
14 | "eslint-plugin-flowtype": "^2.50.3",
15 | "eslint-plugin-import": "^2.14.0",
16 | "eslint-plugin-jsx-a11y": "^6.1.2",
17 | "eslint-plugin-prettier": "^3.0.0",
18 | "eslint-plugin-react": "^7.11.1",
19 | "gatsby": "^2.0.76",
20 | "gatsby-cli": "^2.4.9",
21 | "gatsby-image": "^2.0.20",
22 | "gatsby-plugin-antd": "^2.0.2",
23 | "gatsby-plugin-less": "^2.0.11",
24 | "gatsby-plugin-manifest": "^2.0.9",
25 | "gatsby-plugin-offline": "^2.0.23",
26 | "gatsby-plugin-react-helmet": "^3.0.2",
27 | "gatsby-plugin-sharp": "^2.0.14",
28 | "gatsby-plugin-typography": "^2.2.7",
29 | "gatsby-source-filesystem": "^2.0.8",
30 | "gatsby-source-graphql": "^2.0.8",
31 | "gatsby-transformer-sharp": "^2.1.8",
32 | "less": "^3.9.0",
33 | "lodash": "^4.17.11",
34 | "moment": "^2.24.0",
35 | "prop-types": "^15.6.2",
36 | "react": "^16.6.3",
37 | "react-dom": "^16.6.3",
38 | "react-helmet": "^5.2.0"
39 | },
40 | "keywords": [
41 | "gatsby"
42 | ],
43 | "license": "MIT",
44 | "scripts": {
45 | "build": "gatsby build",
46 | "develop": "gatsby develop",
47 | "start": "npm run develop",
48 | "format": "prettier --write \"src/**/*.js\"",
49 | "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\""
50 | },
51 | "devDependencies": {
52 | "prettier": "^1.15.2"
53 | },
54 | "repository": {
55 | "type": "git",
56 | "url": "https://github.com/gatsbyjs/gatsby-starter-default"
57 | },
58 | "bugs": {
59 | "url": "https://github.com/gatsbyjs/gatsby/issues"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/components/CategoriesWidget/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StaticQuery, graphql, Link } from "gatsby"
3 |
4 | const QUERY = graphql`
5 | {
6 | wpgraphql {
7 | categories {
8 | nodes {
9 | name
10 | slug
11 | link
12 | }
13 | }
14 | }
15 | }
16 | `
17 |
18 | const CategoriesWidget = () => (
19 | {
22 | return (
23 |
24 |
Categories
25 |
26 | {data.wpgraphql.categories.nodes.map(category => {
27 | return (
28 | -
29 | {category.name}
30 |
31 | )
32 | })}
33 |
34 |
35 | )
36 | }}
37 | />
38 | )
39 |
40 | export default CategoriesWidget
41 |
--------------------------------------------------------------------------------
/src/components/HomepageLayout/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import SiteHeader from "../../components/SiteHeader"
3 | import { Layout, Row, Col, Button } from "antd"
4 | import wpgraphqlLogo from "../../images/wpgraphql-logo.png"
5 | import gatsbyLogo from "../../images/gatsby-logo.png"
6 |
7 | const { Content } = Layout
8 |
9 | const HomepageLayout = ({ pageNumber, location, children }) => (
10 |
11 |
12 | {!pageNumber ? (
13 |
18 |
19 | Gatsby + WPGraphQL Demo
20 |
26 |
27 |
28 |
29 |
30 |
35 |
36 |
37 |
38 | +
39 |
40 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
98 |
99 |
100 | ) : null}
101 |
109 |
110 |
117 | {children}
118 |
119 |
120 |
121 |
122 | )
123 |
124 | export default HomepageLayout
125 |
--------------------------------------------------------------------------------
/src/components/PostEntry/index.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from "react"
2 | import { Link, graphql } from "gatsby"
3 | import { Row, Col, Divider } from "antd"
4 | import config from "../../../config"
5 | import PostEntryMeta from "../PostEntryMeta"
6 |
7 | const PostEntry = ({ post }) => {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {post.title}
17 |
18 |
23 |
24 |
25 |
26 |
27 | )
28 | }
29 |
30 | export default PostEntry
31 |
32 | export const query = graphql`
33 | fragment PostEntryFragment on WPGraphQL_Post {
34 | id
35 | title
36 | uri
37 | slug
38 | date
39 | content: excerpt
40 | author {
41 | name
42 | slug
43 | avatar(size: 100) {
44 | url
45 | }
46 | }
47 | }
48 | `
49 |
--------------------------------------------------------------------------------
/src/components/PostEntryMeta/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import moment from "moment/moment"
3 | import { Row, Col, Avatar } from "antd"
4 | import { Link } from "gatsby"
5 |
6 | const PostEntryMeta = ({ post }) => (
7 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {post.author.name}
19 |
20 | {moment(post.date).format(`MMM Do YY`)}
21 |
22 |
23 | )
24 |
25 | export default PostEntryMeta
26 |
--------------------------------------------------------------------------------
/src/components/RecentCommentsWidget/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StaticQuery, graphql, Link } from "gatsby"
3 | import { createLocalLink } from "../../utils"
4 |
5 | const QUERY = graphql`
6 | {
7 | wpgraphql {
8 | comments(first: 5) {
9 | nodes {
10 | author {
11 | __typename
12 | ... on WPGraphQL_CommentAuthor {
13 | name
14 | }
15 | ... on WPGraphQL_User {
16 | name
17 | }
18 | }
19 | commentedOn {
20 | __typename
21 | ... on WPGraphQL_Post {
22 | id
23 | title
24 | link
25 | }
26 | ... on WPGraphQL_Page {
27 | id
28 | title
29 | link
30 | }
31 | }
32 | }
33 | }
34 | }
35 | }
36 | `
37 |
38 | const RecentCommentsWidget = () => (
39 | {
42 | return (
43 |
44 |
Recent Comments
45 |
46 | {data.wpgraphql.comments.nodes.map(comment => {
47 | if (`WPGraphQL_Post` === comment.commentedOn.__typename) {
48 | return (
49 | -
50 | {comment.author.name} on{` `}
51 |
52 | {comment.commentedOn.title}
53 |
54 |
55 | )
56 | }
57 | return null;
58 | })}
59 |
60 |
61 | )
62 | }}
63 | />
64 | )
65 |
66 | export default RecentCommentsWidget
67 |
--------------------------------------------------------------------------------
/src/components/RecentPostsWidget/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { StaticQuery, graphql, Link } from "gatsby"
3 | import { createLocalLink } from "../../utils"
4 |
5 |
6 | const QUERY = graphql`
7 | {
8 | wpgraphql {
9 | posts(first: 5) {
10 | nodes {
11 | id
12 | title
13 | link
14 | }
15 | }
16 | }
17 | }
18 | `
19 |
20 | const RecentPostsWidget = () => (
21 | {
24 | return (
25 |
26 |
Recent Posts
27 |
28 | {data.wpgraphql.posts.nodes.map(post => {
29 | return (
30 | -
31 | {post.title}
32 |
33 | )
34 | })}
35 |
36 |
37 | )
38 | }}
39 | />
40 | )
41 |
42 | export default RecentPostsWidget
43 |
--------------------------------------------------------------------------------
/src/components/Seo/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import PropTypes from "prop-types"
3 | import Helmet from "react-helmet"
4 | import { StaticQuery, graphql } from "gatsby"
5 |
6 | function Seo({ description, lang, meta, keywords, title }) {
7 | return (
8 | {
11 | const metaDescription =
12 | description || data.site.siteMetadata.description
13 | return (
14 | 0
56 | ? {
57 | name: `keywords`,
58 | content: keywords.join(`, `),
59 | }
60 | : []
61 | )
62 | .concat(meta)}
63 | />
64 | )
65 | }}
66 | />
67 | )
68 | }
69 |
70 | Seo.defaultProps = {
71 | lang: `en`,
72 | meta: [],
73 | keywords: [],
74 | }
75 |
76 | Seo.propTypes = {
77 | description: PropTypes.string,
78 | lang: PropTypes.string,
79 | meta: PropTypes.array,
80 | keywords: PropTypes.arrayOf(PropTypes.string),
81 | title: PropTypes.string.isRequired,
82 | }
83 |
84 | export default Seo
85 |
86 | const detailsQuery = graphql`
87 | query DefaultSEOQuery {
88 | site {
89 | siteMetadata {
90 | title
91 | description
92 | author
93 | }
94 | }
95 | }
96 | `
97 |
--------------------------------------------------------------------------------
/src/components/SiteHeader/index.js:
--------------------------------------------------------------------------------
1 | import { Link, StaticQuery, graphql } from "gatsby"
2 | import PropTypes from "prop-types"
3 | import React from "react"
4 | import { Layout } from "antd"
5 | import SiteMenu from "../SiteMenu"
6 | import wpgraphqlLogo from "../../images/wpgraphql-logo.png"
7 |
8 | const { Header } = Layout
9 |
10 | const Index = ({ location }) => (
11 | (
22 |
51 | )}
52 | />
53 | )
54 |
55 | Index.propTypes = {
56 | siteTitle: PropTypes.string,
57 | }
58 |
59 | Index.defaultProps = {
60 | siteTitle: ``,
61 | }
62 |
63 | export default Index
64 |
--------------------------------------------------------------------------------
/src/components/SiteLayout.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import PropTypes from "prop-types"
3 | import Header from "./SiteHeader"
4 | import { Layout, Row, Col } from "antd"
5 | import "./style.css"
6 |
7 | const { Content, Footer } = Layout
8 |
9 | const SiteLayout = ({ children, location }) => (
10 |
11 |
12 |
20 |
21 |
28 | {children}
29 |
30 |
31 |
32 |
38 |
39 | )
40 |
41 | SiteLayout.propTypes = {
42 | children: PropTypes.node.isRequired,
43 | }
44 |
45 | export default SiteLayout
46 |
--------------------------------------------------------------------------------
/src/components/SiteMenu/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Menu } from "antd"
3 | import { Link, StaticQuery, graphql } from "gatsby"
4 | import { createLocalLink } from "../../utils"
5 |
6 | const SubMenu = Menu.SubMenu
7 | const MenuItemGroup = Menu.ItemGroup
8 |
9 | const MENU_QUERY = graphql`
10 | fragment MenuFields on WPGraphQL_MenuItem {
11 | id
12 | label
13 | url
14 | connectedObject {
15 | __typename
16 | }
17 | }
18 |
19 | query GET_MENU_ITEMS {
20 | wpgraphql {
21 | menuItems(where: { location: PRIMARY }) {
22 | nodes {
23 | ...MenuFields
24 | childItems {
25 | nodes {
26 | ...MenuFields
27 | childItems {
28 | nodes {
29 | ...MenuFields
30 | childItems {
31 | nodes {
32 | ...MenuFields
33 | childItems {
34 | nodes {
35 | ...MenuFields
36 | childItems {
37 | nodes {
38 | ...MenuFields
39 | childItems {
40 | nodes {
41 | ...MenuFields
42 | childItems {
43 | nodes {
44 | ...MenuFields
45 | childItems {
46 | nodes {
47 | ...MenuFields
48 | childItems {
49 | nodes {
50 | ...MenuFields
51 | }
52 | }
53 | }
54 | }
55 | }
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 | }
63 | }
64 | }
65 | }
66 | }
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 | `
74 |
75 | const renderMenuItem = menuItem => {
76 | const link = createLocalLink(menuItem.url)
77 | if (menuItem.childItems && menuItem.childItems.nodes.length) {
78 | return renderSubMenu(menuItem)
79 | } else {
80 | return (
81 |
82 | {link ? (
83 | {menuItem.label}
84 | ) : (
85 | menuItem.label
86 | )}
87 |
88 | )
89 | }
90 | }
91 |
92 | const renderSubMenu = menuItem => (
93 |
94 |
95 | {menuItem.childItems.nodes.map(item => renderMenuItem(item))}
96 |
97 |
98 | )
99 |
100 | const SiteMenu = ({ location }) => (
101 | {
104 | if (data.wpgraphql.menuItems) {
105 | return (
106 |
123 | )
124 | } else {
125 | return null
126 | }
127 | }}
128 | />
129 | )
130 |
131 | export default SiteMenu
132 |
--------------------------------------------------------------------------------
/src/components/style.css:
--------------------------------------------------------------------------------
1 | img {
2 | max-width: 100%;
3 | height: auto;
4 | }
5 |
6 | iframe {
7 | max-width: 100%;
8 | }
9 |
10 | * {
11 | word-break: break-word;
12 | }
13 |
--------------------------------------------------------------------------------
/src/images/gatsby-astronaut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/src/images/gatsby-astronaut.png
--------------------------------------------------------------------------------
/src/images/gatsby-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/src/images/gatsby-icon.png
--------------------------------------------------------------------------------
/src/images/gatsby-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/src/images/gatsby-logo.png
--------------------------------------------------------------------------------
/src/images/wpgraphql-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wp-graphql/gatsby-wpgraphql-blog-example/6e31fb099be283f385f751315828e92effc77cf9/src/images/wpgraphql-logo.png
--------------------------------------------------------------------------------
/src/layouts/SiteLayout/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | const SiteLayout = ({location}) => {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/404.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | import SiteLayout from "../components/SiteLayout"
4 | import Seo from "../components/Seo"
5 |
6 | const NotFoundPage = ({ location }) => (
7 |
8 |
9 | NOT FOUND
10 | You just hit a route that doesn't exist... the sadness.
11 |
12 | )
13 |
14 | export default NotFoundPage
15 |
--------------------------------------------------------------------------------
/src/templates/blog.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react"
2 | import { graphql, navigate } from "gatsby"
3 | import { Button, Col, Row } from "antd"
4 | import CategoriesWidget from "../components/CategoriesWidget"
5 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
6 | import RecentPostsWidget from "../components/RecentPostsWidget"
7 | import PostEntry from "../components/PostEntry"
8 | import HomepageLayout from "../components/HomepageLayout"
9 | import Seo from "../components/Seo"
10 |
11 | class IndexPage extends Component {
12 | renderPreviousLink = () => {
13 | const {
14 | pageContext: { pageNumber },
15 | } = this.props
16 |
17 | let previousLink = null
18 |
19 | if (!pageNumber) {
20 | return null
21 | } else if (1 === pageNumber) {
22 | previousLink = `/`
23 | } else if (1 < pageNumber) {
24 | previousLink = `/page/${pageNumber - 1}`
25 | }
26 |
27 | return (
28 |
31 | )
32 | }
33 |
34 | renderNextLink = () => {
35 | const {
36 | pageContext: { hasNextPage, pageNumber },
37 | } = this.props
38 |
39 | if (hasNextPage) {
40 | return (
41 |
47 | )
48 | } else {
49 | return null
50 | }
51 | }
52 |
53 | render() {
54 | const {
55 | data,
56 | location,
57 | pageContext: { pageNumber },
58 | } = this.props
59 | const blogPageNumber = pageNumber ? ` Page ${pageNumber}` : ``
60 | return (
61 |
62 |
63 |
64 |
65 | {data &&
66 | data.wpgraphql &&
67 | data.wpgraphql.posts.nodes.map(post => (
68 |
71 | ))}
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
88 |
89 |
90 | {this.renderPreviousLink()}
91 |
92 |
93 |
94 |
95 | {this.renderNextLink()}
96 |
97 |
98 |
99 |
100 | )
101 | }
102 | }
103 |
104 | export default IndexPage
105 |
106 | export const query = graphql`
107 | query GET_POSTS($ids: [ID]) {
108 | wpgraphql {
109 | posts(where: { in: $ids }) {
110 | nodes {
111 | ...PostEntryFragment
112 | }
113 | }
114 | }
115 | }
116 | `
117 |
--------------------------------------------------------------------------------
/src/templates/categoriesArchive.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | const CategoriesArchiveTemplate = props => {
4 | return (
5 |
6 |
Category Archive...
7 |
8 | )
9 | }
10 |
11 | export default CategoriesArchiveTemplate
12 |
--------------------------------------------------------------------------------
/src/templates/category.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import SiteLayout from "../components/SiteLayout"
3 | import { graphql } from "gatsby"
4 | import { Row, Col, Divider } from "antd"
5 | import CategoriesWidget from "../components/CategoriesWidget"
6 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
7 | import RecentPostsWidget from "../components/RecentPostsWidget"
8 | import PostEntry from "../components/PostEntry"
9 | import Seo from "../components/Seo"
10 |
11 | const CategoryTemplate = props => {
12 | const {
13 | location,
14 | data: {
15 | wpgraphql: { category },
16 | },
17 | } = props
18 | return (
19 |
20 |
21 |
22 |
23 | Category: {category.name}
24 |
25 | {category.posts.nodes &&
26 | category.posts.nodes.map(post => )}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | )
36 | }
37 |
38 | export default CategoryTemplate
39 |
40 | export const pageQuery = graphql`
41 | query GET_CATEGORY($id: ID!) {
42 | wpgraphql {
43 | category(id: $id) {
44 | id
45 | name
46 | slug
47 | posts(first: 100) {
48 | nodes {
49 | ...PostEntryFragment
50 | }
51 | }
52 | }
53 | }
54 | }
55 | `
56 |
--------------------------------------------------------------------------------
/src/templates/page.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { graphql } from "gatsby"
3 | import { Row, Col, Divider } from "antd"
4 | import SiteLayout from "../components/SiteLayout"
5 | import CategoriesWidget from "../components/CategoriesWidget"
6 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
7 | import RecentPostsWidget from "../components/RecentPostsWidget"
8 | import Seo from "../components/Seo"
9 |
10 | const Page = props => {
11 | const {
12 | location,
13 | data: {
14 | wpgraphql: { page },
15 | },
16 | } = props
17 | const { title, content } = page
18 | return (
19 |
20 |
21 |
22 |
23 | {title}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | )
39 | }
40 |
41 | export default Page
42 |
43 | export const pageQuery = graphql`
44 | query GET_PAGE($id: ID!) {
45 | wpgraphql {
46 | page(id: $id) {
47 | title
48 | content
49 | uri
50 | }
51 | }
52 | }
53 | `
54 |
--------------------------------------------------------------------------------
/src/templates/post.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from "react"
2 | import { graphql } from "gatsby"
3 | import { Row, Col, Divider, Tag } from "antd"
4 | import SiteLayout from "../components/SiteLayout"
5 | import CategoriesWidget from "../components/CategoriesWidget"
6 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
7 | import RecentPostsWidget from "../components/RecentPostsWidget"
8 | import PostEntryMeta from "../components/PostEntryMeta"
9 | import Seo from "../components/Seo"
10 |
11 | const renderTermNodes = (nodes, title) => (
12 |
13 | {title}
14 | {` `}
15 | {nodes.map(term => (
16 | {term.name}
17 | ))}
18 |
19 | )
20 |
21 | const renderTerms = (categoryNodes = [], tagNodes = []) => (
22 |
23 |
24 | {categoryNodes ? renderTermNodes(categoryNodes, `Categories: `) : null}
25 | {tagNodes && tagNodes.length ? renderTermNodes(tagNodes, `Tags: `) : null }
26 |
27 | )
28 |
29 | const Post = props => {
30 | const {
31 | location,
32 | data: {
33 | wpgraphql: { post },
34 | },
35 | } = props
36 | const { title, content } = post
37 | return (
38 |
39 |
40 |
41 |
42 | {title}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {post.categories.nodes.length || post.tags.nodes.length
51 | ? renderTerms(post.categories.nodes, post.tags.nodes)
52 | : null}
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | )
64 | }
65 |
66 | export default Post
67 |
68 | export const pageQuery = graphql`
69 | query GET_POST($id: ID!) {
70 | wpgraphql {
71 | post(id: $id) {
72 | title
73 | content
74 | uri
75 | author {
76 | name
77 | slug
78 | avatar {
79 | url
80 | }
81 | }
82 | tags {
83 | nodes {
84 | name
85 | link
86 | }
87 | }
88 | categories {
89 | nodes {
90 | name
91 | link
92 | }
93 | }
94 | }
95 | }
96 | }
97 | `
98 |
--------------------------------------------------------------------------------
/src/templates/tag.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import SiteLayout from "../components/SiteLayout"
3 | import { graphql } from "gatsby"
4 | import { Row, Col } from "antd"
5 | import CategoriesWidget from "../components/CategoriesWidget"
6 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
7 | import RecentPostsWidget from "../components/RecentPostsWidget"
8 | import PostEntry from "../components/PostEntry"
9 | import Seo from "../components/Seo"
10 |
11 | const TagTemplate = props => {
12 | const {
13 | location,
14 | data: {
15 | wpgraphql: { tag },
16 | },
17 | } = props
18 | return (
19 |
20 |
21 | {tag.name}
22 |
23 |
24 | {tag.posts.nodes &&
25 | tag.posts.nodes.map(post => )}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | )
35 | }
36 |
37 | export default TagTemplate
38 |
39 | export const pageQuery = graphql`
40 | query GET_TAG($id: ID!) {
41 | wpgraphql {
42 | tag(id: $id) {
43 | id
44 | name
45 | slug
46 | posts(first: 100) {
47 | nodes {
48 | ...PostEntryFragment
49 | }
50 | }
51 | }
52 | }
53 | }
54 | `
55 |
--------------------------------------------------------------------------------
/src/templates/tagsArchive.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | const TagsArchiveTemplate = props => {
4 | return (
5 |
6 |
Tag Archive...
7 |
8 | )
9 | }
10 |
11 | export default TagsArchiveTemplate
12 |
--------------------------------------------------------------------------------
/src/templates/user.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import SiteLayout from "../components/SiteLayout"
3 | import { Row, Col } from "antd"
4 | import { graphql } from "gatsby"
5 | import CategoriesWidget from "../components/CategoriesWidget"
6 | import RecentCommentsWidget from "../components/RecentCommentsWidget"
7 | import RecentPostsWidget from "../components/RecentPostsWidget"
8 | import PostEntry from "../components/PostEntry"
9 | import Seo from "../components/Seo"
10 |
11 | const User = props => {
12 | const {
13 | location,
14 | data: {
15 | wpgraphql: { user },
16 | },
17 | } = props
18 | return (
19 |
20 |
21 |
22 |
23 | {user.name}
24 | Latest Posts
25 | {user.posts.nodes.map(post => (
26 |
27 | ))}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | )
37 | }
38 |
39 | export default User
40 |
41 | export const pageQuery = graphql`
42 | query user($id: ID!) {
43 | wpgraphql {
44 | user(id: $id) {
45 | name
46 | avatar {
47 | url
48 | }
49 | posts {
50 | nodes {
51 | ...PostEntryFragment
52 | }
53 | }
54 | }
55 | }
56 | }
57 | `
58 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | import config from "../../config"
2 |
3 | export const createLocalLink = url => {
4 | if (`#` === url) {
5 | return null
6 | }
7 | return url ? url.replace(config.wordPressUrl, ``) : url
8 | }
9 |
--------------------------------------------------------------------------------