Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wordpress source plugin and example site #1321

Merged
merged 16 commits into from
Jul 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/using-wordpress/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ['react', 'es2015', 'stage-1'],
"plugins": ['add-module-exports']
}
1 change: 1 addition & 0 deletions examples/using-wordpress/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
10 changes: 10 additions & 0 deletions examples/using-wordpress/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Build Path of Test Fixtures
.gatsby-context.js
.DS_Store
public/
build/
.cache/
.netlify

# IDE specific
.vscode/
43 changes: 43 additions & 0 deletions examples/using-wordpress/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module.exports = {
siteMetadata: {
title: 'A sample site using gatsby-source-wordpress',
subtitle: 'Data fetched from a site hosted on wordpress.com'
},
plugins: [
// https://public-api.wordpress.com/wp/v2/sites/gatsbyjsexamplewordpress.wordpress.com/pages/
/*
* Gatsby's data processing layer begins with “source”
* plugins. Here the site sources its data from Wordpress.
*/
{
resolve: 'gatsby-source-wordpress',
options: {
/*
* The base URL of the Wordpress site without the trailingslash and the protocol. This is required.
* Example : 'gatsbyjsexamplewordpress.wordpress.com' or 'www.example-site.com'
*/
baseUrl: 'gatsbyjsexamplewordpress.wordpress.com',
// The protocol. This can be http or https.
protocol: 'http',
// Indicates whether the site is hosted on wordpress.com.
// If false, then the asumption is made that the site is self hosted.
// If true, then the plugin will source its content on wordpress.com using the JSON REST API V2.
// If your site is hosted on wordpress.org, then set this to false.
hostingWPCOM: true,
// If useACF is true, then the source plugin will try to import the Wordpress ACF Plugin contents.
// This feature is untested for sites hosted on Wordpress.com
useACF: false,
// If auth.user and auth.pass are filled, then the source plugin will be allowed to access endpoints that are protected with .htaccess.
auth: {
user: 'your-htaccess-username',
pass: 'your-htaccess-password',
sendImmediately: false,
},
// Set verboseOutput to true to display a verbose output on `npm run develop` or `npm run build`
// It can help you debug specific API Endpoints problems
verboseOutput: false,
},
},

],
}
111 changes: 111 additions & 0 deletions examples/using-wordpress/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const _ = require(`lodash`)
const Promise = require(`bluebird`)
const path = require(`path`)
const slash = require(`slash`)

// Implement the Gatsby API “createPages”. This is
// called after the Gatsby bootstrap is finished so you have
// access to any information necessary to programatically
// create pages.
// Will create pages for Wordpress pages (route : /{slug})
// Will create pages for Wordpress posts (route : /post/{slug})
exports.createPages = ({ graphql, boundActionCreators }) => {
const { createPage } = boundActionCreators
return new Promise((resolve, reject) => {
// The “graphql” function allows us to run arbitrary
// queries against the local Wordpress graphql schema. Think of
// it like the site has a built-in database constructed
// from the fetched data that you can run queries against.

// ==== PAGES (WORDPRESS NATIVE) ====
graphql(
`
{

allWordpressPage {
edges {
node {
id
slug
status
template
}
}
}

}
`
)
.then(result => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could destructure (in many places)

.then(({ errors, data }) => {

if (result.errors) {
console.log(result.errors)
reject(result.errors)
}

// Create Page pages.
const pageTemplate = path.resolve('./src/templates/page.js')
// We want to create a detailed page for each
// page node. We'll just use the Wordpress Slug for the slug.
// The Page ID is prefixed with 'PAGE_'
_.each(result.data.allWordpressPage.edges, edge => {
// Gatsby uses Redux to manage its internal state.
// Plugins and sites can use functions like "createPage"
// to interact with Gatsby.
createPage({
// Each page is required to have a `path` as well
// as a template component. The `context` is
// optional but is often necessary so the template
// can query data specific to each page.
path: `/${edge.node.slug}/`,
component: slash(pageTemplate),
context: {
id: edge.node.id,
},
})
})
})
// ==== END PAGES ====

// ==== POSTS (WORDPRESS NATIVE AND ACF) ====
.then(() => {
graphql(
`{
allWordpressPost {
edges {
node {
id
slug
status
template
format
}
}
}

}
`
).then(result => {
if (result.errors) {
console.log(result.errors)
reject(result.errors)
}
const postTemplate = path.resolve('./src/templates/post.js')
// We want to create a detailed page for each
// post node. We'll just use the Wordpress Slug for the slug.
// The Post ID is prefixed with 'POST_'
_.each(result.data.allWordpressPost.edges, edge => {
createPage({
path: `/post/${edge.node.slug}/`,
component: slash(postTemplate),
context: {
id: edge.node.id,
},
})
})
resolve()
})
})
// ==== END POSTS ====

})
}
33 changes: 33 additions & 0 deletions examples/using-wordpress/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "gatsby-example-using-wordpress",
"private": true,
"description": "Gatsby example site using the Wordpress source plugin",
"version": "1.0.0-beta.6",
"author": "Sebastien Fichot <[email protected]>",
"dependencies": {
"gatsby": "next",
"gatsby-link": "next",
"gatsby-plugin-react-helmet": "next",
"gatsby-plugin-styled-components": "next",
"gatsby-source-wordpress": "next",
"hedron": "^0.7.1",
"lodash": "^4.16.4"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"scripts": {
"dev": "gatsby develop",
"lint": "./node_modules/.bin/eslint --ext .js,.jsx --ignore-pattern public .",
"test": "echo \"Error: no test specified\" && exit 1",
"develop": "gatsby develop",
"build": "gatsby build",
"start": "gatsby serve",
"predeploy": "gatsby build --prefix-links"
},
"devDependencies": {
"eslint": "^4.1.1"
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 13 additions & 0 deletions examples/using-wordpress/src/components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { Page, Row } from './styled';

const Footer = props =>
<footer>
<Page>
<Row height={5}>
This is a sample footer.
</Row>
</Page>
</footer>

export default Footer;
39 changes: 39 additions & 0 deletions examples/using-wordpress/src/components/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
import { H1, H2, H3, H4 } from '../components/styled';
import { Row, Page, Column } from './styled';

const Header = ({ title, subtitle, pages }) => {

// TODO : Sort order of menu based on field menu_order
return (
<Page>
<Row>
<H3>{title}</H3>
</Row>
<Row>
<H4>{subtitle}</H4>
</Row>
<Row>
<Column fluid xs={1} sm={10} md={10} lg={10}>
<span><Link to={'/'}>Home</Link> - </span>
{pages.edges.map((p, i) => {
if (p.node.slug == 'blog') return
if (p.node.slug == 'home') return
return <span key={p.node.id}>{i !== 0 ? ' - ' : ''}<Link to={p.node.slug}>{unescape(p.node.title)}</Link></span>
})}
</Column>
<hr />
</Row>
</Page>
)
}

Header.propTypes = {
title: PropTypes.string,
pages: PropTypes.object.isRequired,
}


export default Header;
30 changes: 30 additions & 0 deletions examples/using-wordpress/src/components/PostPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Row, Page, Column, BlockLink, P2, P4 } from './styled';
import styled from 'styled-components';
import theme from './styled/theme';

const BlogPreviewImg = styled.img`
width: 100%;
`;

const PostPreview = ({ article, id }) => {
console.log('article is', article)
return (
<Column outline fluid xs={4} sm={4} md={4} lg={4}>
<BlockLink to={`/post/${id}`} paddingHorizontal={2} paddingTop={2} paddingBottom={5} block>
<BlogPreviewImg src={'http://via.placeholder.com/416x245'} alt="placeholder"/>
<P2 color={theme.color.han} dangerouslySetInnerHTML={{ __html: article.node.title }}></P2>
<P4 color={theme.color.han} dangerouslySetInnerHTML={{ __html: article.node.excerpt }}></P4>
<P4 color={theme.color.link}>Read More</P4>
</BlockLink>
</Column>
)
}

PostPreview.propType = {
article: PropTypes.object.isRequired,
id: PropTypes.string,
}

export default PostPreview;
68 changes: 68 additions & 0 deletions examples/using-wordpress/src/components/PostsListSearchable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { H3, Row, Page, Column } from './styled';
import PostPreview from './PostPreview'

class PostsListSearchable extends Component {

// Put the props in the state
constructor(props) {
super(props)
this.state = {
data: this.props.propsData.allWordpressPost.edges
}
}

handleFilter = id => {
this.setState({
data: this.props.propsData.allWordpressPost.edges.filter(p => {
return p.node.categories.includes(id.replace('CATEGORY_', ''))
})
})
}

resetFilter = () => this.setState({ data: this.props.propsData.allWordpressPost.edges })

render() {

return (
<Page>
<H3>The latests blog posts</H3>
<Row gutter gutterWhite>
<Column fluid xs={1} sm={10} md={10} lg={10}>
<span>Filter by category: </span>
<span onClick={() => this.resetFilter()}>All - </span>
{
this.props.propsData.allWordpressCategory.edges.map((cat, i) => {

return (<span
key={cat.node.id}
onClick={() => this.handleFilter(cat.node.id)}
>
{i !== 0 ? ' - ':''}{cat.node.name}
</span>)
})
}
<span onClick={() => this.resetFilter()}> - Reset filter</span>
</Column>
</Row>
<Row gutter>
{
this.state.data.map(article =>
<PostPreview key={article.node.slug} id={article.node.slug} article={article} />)}
</Row>
<Row gutter height={19}>
</Row>
</Page>
)
}


}


PostsListSearchable.propTypes = {
propsData: PropTypes.object.isRequired,
}

export default PostsListSearchable;
Loading