Coder Social home page Coder Social logo

nubotics / wordexpress-schema Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ramsaylanier/wordexpressschema

0.0 4.0 0.0 16 KB

This package provides a connection to a WordPress database using Sequelize and provides a standard set of queries.

Home Page: http://wordexpress.io

JavaScript 100.00%

wordexpress-schema's Introduction

wordexpress-schema

This package provides a connection to a WordPress MYSQL database using Sequelize and provides a standard set of queries to use with GraphQL.

For a full example, check out the repo for WordExpress.io, which was built using this package.

##Installation

npm install --save-dev wordexpress-schema

##Usage WordExpress Schema exports two things: WordExpressDatabase and WordExpressGraphQLSchema.

WordExpressDatabase provides a connection to your database and returns some models and queries using Sequelize. These queries replace MYSQL queries, and return promises. You can use the queries exposed in WordExpressDatabase to manually write your own GraphQL Schema, as you will see below. Or, you can use WordExpressGraphQLSchema.

WordExpressGraphQLSchema is a GraphQL Schema based on the queries provided to it from WordExpressDatabase. With the schema, you can do things like Find Posts by post_type, get the Postmeta of a Post by the post_id, and so on.

Below is detailed documentation on using both.

##WordExpressDatabase The first part of WordExpress Schema is WordExpressDatabase. This class provides an easy connection to your WordPress database using a Sequelize connection.

Below is the basic implementation:

import { WordExpressDatabase } from 'wordexpress-schema';
import { publicSettings, privateSettings } from '../settings/settings';

/*
  Example settings object:
  publicSettings: {
    uploads: "http://wordexpress.s3.amazonaws.com/",
    amazonS3: true
  },
  privateSettings: {
    wp_prefix: "wp_",
    database: {
      name: "wpexpress_dev",
      username: "root",
      password: "",
      host: "127.0.0.1"
    }
  }
*/

const { name, username, password, host } = privateSettings.database;
const { amazonS3, uploads } = publicSettings;

const connectionDetails = {
  name: name,
  username: username,
  password: password,
  host: host,
  amazonS3: amazonS3,
  uploadDirectory: uploads
}

const Database = new WordExpressDatabase(connectionDetails);
const ConnQueries = Database.queries;
export default ConnQueries;

###Connection Settings

In the above example, WordExpressDatabase is passed a connectionDetails object that contains some WordPress database settings. Name, username, password, and host are all self-explanatory.

WordExpress will work with Amazon S3; passing in a truthy value for amazonS3 will alter the query for getting Post Thumbnail images. If you are using S3, you just need the include the base path to your S3 bucket (which means you should exclude the wp-content/uploads/ part of the path). If you are hosting images on your own server, include the full path to the uploads folder.

Lastly, you can modify the wordpress database prefix. Some people don't use the default "wp_" prefix for various reasons. If that's you, I got your back.

###The Database Class

The Database class above contains the connectionDetails, the actual Sequelize connection, the database queries, and the database models. Really, all you need for GraphQL setup are the queries; however, if you'd like to extend queries with your own, the Database Models are exposed.

####The Models Here are the models and their definitions. As you can see, for the Post model, not every column in the wp_posts table is included. I've included the most relevant columns; however because the Database class exposes the models, you can extend them to your liking.

Post: Conn.define(prefix + 'posts', {
  id: { type: Sequelize.INTEGER, primaryKey: true},
  post_author: { type: Sequelize.INTEGER },
  post_title: { type: Sequelize.STRING },
  post_content: { type: Sequelize.STRING },
  post_excerpt: { type: Sequelize.STRING },
  post_status:{ type: Sequelize.STRING },
  post_type:{ type: Sequelize.STRING },
  post_name:{ type: Sequelize.STRING},
  post_parent: { type: Sequelize.INTEGER},
  menu_order: { type: Sequelize.INTEGER}
}),
Postmeta: Conn.define(prefix + 'postmeta', {
  meta_id: { type: Sequelize.INTEGER, primaryKey: true, field: 'meta_id' },
  post_id: { type: Sequelize.INTEGER },
  meta_key: { type: Sequelize.STRING },
  meta_value: { type: Sequelize.INTEGER },
}),
Terms: Conn.define(prefix + 'terms', {
  term_id: { type: Sequelize.INTEGER, primaryKey: true },
  name: { type: Sequelize.STRING },
  slug: { type: Sequelize.STRING },
  term_group: { type: Sequelize.INTEGER },
}),
TermRelationships: Conn.define(prefix + 'term_relationships', {
  object_id: { type: Sequelize.INTEGER, primaryKey: true },
  term_taxonomy_id: { type: Sequelize.INTEGER },
  term_order: { type: Sequelize.INTEGER },
}),
TermTaxonomy: Conn.define(prefix + 'term_taxonomy', {
  term_taxonomy_id: { type: Sequelize.INTEGER, primaryKey: true },
  term_id: { type: Sequelize.INTEGER },
  taxonomy: { type: Sequelize.STRING },
  parent: { type: Sequelize.INTEGER },
  count: { type: Sequelize.INTEGER },
})

####The Queries

In the above example, ConnQueries will give you the following:

getViewer()

Necessary because GraphQL doesn't currently allow for nodes on the root query. It simply returns a User object with id:1 and name:Anonymous

getPosts(args)

args is an object; however, the only acceptable key in args is post_type. This finds all published posts by post type. Returns a promised array.

getPostById(postId)

Accepts a post id and returns the corresponding post.

getPostByName(name)

Accepts a post name (AKA slug) and returns it. The post must be published.

getPostThumbnail(postId)

Accepts a post id and returns the thumbnail image. In the connectionDetails object above you'll notice that there is a setting for AmazonS3. Set to true if you want to use WordPress with AmazonS3.

getPostmeta(postId, keys)

Returns a posts' Postmeta. Keys is an array of valid meta_key values. See the below example for usage.

getPostMetaById(metaId)

Returns a single Postmeta by id. Probably not very useful right now. Instead, you'll want to use getPostmeta();

getMenu(name)

Returns a menu and all of its menu items where the name argument is the slug of your menu.

####Extending Queries

Extending the above example, it's possible to add your own queries (or even your own models). Here's an example:

...
const Database = new WordExpressDatabase(connectionDetails);
const Models = Database.models;
const ConnQueries = Database.queries;

const CustomPostsQuery = () => {
  return Models.Post.findAll({
    where: {
      post_type: 'my_custom_post_type',
      post_status: 'publish',
    }
  })
}

ConnQueries.getCustomPosts = CustomPostsQuery;
...

###Example Usage With GraphQL

This example requires working knowledge of GraphQL. If you aren't familiar, start by reading the GraphQL documentation.

If you'd like a full example, check out the repo for WordExpress.io, which is built using this package.

const GraphQLUser = new GraphQLObjectType({
  name: "User",
  fields: {
    id: {type: new GraphQLNonNull(GraphQLID)} ,
    settings: {
      type: GraphQLSetting,
      resolve: ()=>{
        return publicSettings
      }
    },
    posts: {
      type: PostsConnection,
      args: {
        post_type: {
          type: GraphQLString,
          defaultValue: 'post'
        },
        ...connectionArgs
      },
      resolve(root, args) {
        return connectionFromPromisedArray( ConnQueries.getPosts(args), args );
      }
    },
    page: {
      type: GraphQLPost,
      args:{
        post_name:{ type: GraphQLString },
      },
      resolve(root, args){
        return ConnQueries.getPostByName(args.post_name);
      }
    },
    menus: {
      type: GraphQLMenu,
      args: {
        name: { type: GraphQLString }
      },
      resolve(root, args) {
        return ConnQueries.getMenu(args.name);
      }
    },
    postmeta: {
      type: PostmetaConnection,
      args: {
        post_id: {
          type: GraphQLInt
        },
        ...connectionArgs
      },
      resolve(root, args){
        return ConnQueries.getPostmeta(args.post_id)
      }
    }
  }
})

const GraphQLRoot = new GraphQLObjectType({
  name: 'Root',
  fields: {
    viewer: {
      type: GraphQLUser,
      resolve: () => {
        return ConnQueries.getViewer();
      }
    }
  }
});

const WordExpressSchema = new GraphQLSchema({
  query: GraphQLRoot
});
export default WordExpressSchema;

##WordExpressGraphQLSchema Instead of writing your own GraphQL schema, you can use WordExpressGraphQLSchema. To extend upon the earlier example, this is how it's implemented:

import { WordExpressDatabase, WordExpressGraphQLSchema } from 'wordexpress-schema';
import { publicSettings, privateSettings } from '../settings/settings';

const { name, username, password, host } = privateSettings.database;
const { amazonS3, uploads } = publicSettings;

const connectionDetails = {
  name: name,
  username: username,
  password: password,
  host: host,
  amazonS3: amazonS3,
  uploadDirectory: uploads
}

const Database = new WordExpressDatabase(connectionDetails);
const ConnQueries = Database.queries;
const Schema = WordExpressGraphQLSchema(ConnQueries, publicSettings);

export default Schema;

The Schema that gets exported contains a Root query that has a viewer field. The viewer is of type GraphQLUser, which is a custom GraphQLObjectType that is defined by the package. GraphQLUser serves as the main fragment that will be queried from. This will make sense if you are at all familiar with GraphQL. If you arent, here are some practical examples of how to use the provided Schema.

###Building a Landing Page Component In this example, I'm using Relay to query a fragment on User to find a page with the post_name(AKA slug) of "homepage". I'm getting the post_title, the post_content, and the thumbnail.

import React from 'react';
import Relay from 'react-relay';
import Page from './page.js';
import PostContent from '../posts/PostContent';

class LandingPage extends React.Component{

	render(){
		const { post_title, post_content, thumbnail} = this.props.viewer.page;
		let bg = {
			backgroundImage: "url('" + thumbnail + "')"
		}

		let heroClass = thumbnail ? "hero_thumbnail" : "hero"

		return (
			<Page>
				<div styleName={heroClass} style={bg}>
					<div styleName="wrapper tight">
						<h1 styleName="title">WordExpress</h1>
						<h4 styleName="subtitle">WordPress using Node, Express, and React.</h4>
					</div>
				</div>

				<div styleName="content">
					<div styleName="wrapper tight">
						<PostContent post_content={post_content}/>
					</div>
				</div>
			</Page>
		)
	}
}

export default Relay.createContainer(LandingPage, {
  fragments: {
    viewer: () => Relay.QL`
      fragment on User {
        page(post_name:"homepage"){
					id,
					post_title
					post_content
					thumbnail
				},
				settings{
					id
					uploads
					amazonS3
				}
      }
    `,
  },
});

This example comes directly from WordExpress.io, an open-source project used to document the usage of this package. I urge you to clone the WordExpress repo and play around with it yourself.

wordexpress-schema's People

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.