• Stars
    star
    149
  • Rank 248,619 (Top 5 %)
  • Language
    JavaScript
  • Created almost 9 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

npm version

wordexpress-schema

WordExpress Schema is a GraphQL schema that is modeled off of how WordPress stores data in a MySQL database. It provides modular GraphQL type definitions and GraphQL query resolvers, as well as an easy connection to a WordPress database.

WordExpress Schema exports the following:

  • WordExpress Database: provides a connection to your WordPress database and returns some models and queries using Sequelize. These queries replace MYSQL queries, and return promises.

  • WordExpress Resolvers: resolving functions that work with the WordExpressDatabase connectors to resolve GraphQL queries

  • WordExpress Definitions: a modular GraphQL schema definition.

Combined, this package can be used with any GraphQL server (like Apollo Server) to provide an easy connection to your WordPress database. An example of using this package with Apollo Server and Webpack is provided below.

If you'd like a solution that already includes a GraphQL server for you, check out the WordExpress Server repository. WordExpress Server uses WordExpress Schema and provides you with a GraphQL server out of the box.

Installation

npm install --save-dev wordexpress-schema

Usage

WordExpressDatabase

The first part of WordExpress Schema is WordExpressDatabase. This class provides an easy connection to your WordPress database using some connection settings. Typically, you'll want to put the database in its own file in case you want to extend the Models.

Below is the basic implementation:

//db.js
import Config from 'config'
import {WordExpressDatabase} from 'wordexpress-schema'

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


const publicSettings = Config.get('public')
const privateSettings = Config.get('private')

const Database = new WordExpressDatabase({publicSettings, privateSettings})
const {connectors, models} = Database

export default Database
export {connectors, models}

Connection Settings

In the above example, WordExpressDatabase is passed a settings 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_date: { 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 },
}),
User: Conn.define(prefix + 'users', {
  id: { type: Sequelize.INTEGER, primaryKey: true },
  user_nicename: { type: Sequelize.STRING },
  user_email: { type: Sequelize.STRING },
  user_registered: { type: Sequelize.STRING },
  display_name: { type: Sequelize.STRING }
}),
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 },
})

Creating The Schema

WordExpress uses GraphQL Tools's makeExecutableSchema to generate an executable schema. makeExecutableSchema requires type definitions and resolvers. WordExpress gives you both of those! Here's the basic implementation of the schema:

import {makeExecutableSchema} from 'graphql-tools'
import {WordExpressDefinitions, WordExpressResolvers} from 'wordexpress-schema'
import {connectors} from './db'
import Config from 'config'

const RootResolvers = WordExpressResolvers(connectors, Config.get('public'))

const schema = makeExecutableSchema({
  typeDefs: [WordExpressDefinitions]
  resolvers: RootResolvers
})

export default schema

WordExpressResolvers requires some database connectors that the WordExpressDatabase provides. These connectors provide the root sequelize queries. WordExpressResolvers is simply a (resolving map)[https://www.apollographql.com/docs/graphql-tools/resolvers.html#Resolver-map] that tell the GraphQl queries how to fetch the data from the WordPress database.

WordExpressDefinitions is a modular GraphQL schema written in the GraphQL Schema language.

Using Definitions and Resolvers with Apollo Server

This example is from the WordExpress Server. After creating an executable schema, all we need to do is provide the schema to apollo-server-express.

import {ApolloServer} from 'apollo-server'
import {WordExpressDefinitions, WordExpressResolvers} from 'wordexpress-schema'
import {connectors} from './db'
import Config from 'config'

const PORT = 4000

const resolvers = WordExpressResolvers(connectors, Config.get('public'))

const server = new ApolloServer({
  typeDefs: [...WordExpressDefinitions],
  resolvers
})

server.listen({port: PORT}, () => {
  console.log(`wordexpress server is now running on port ${PORT}`)
})

Types

Post

import Postmeta from './Postmeta'
import User from './User'

const Post = `
  type Post {
    id: Int
    post_title: String
    post_content: String
    post_excerpt: String
    post_status: String
    post_type: String
    post_name: String
    post_parent: Int
    post_date: String
    menu_order: Int
    post_author: Int
    layout: Postmeta
    thumbnail: String
    post_meta(keys: [MetaType], after: String, first: Int, before: String, last: Int): [Postmeta]
    author: User
  }
`

export default () => [Post, Postmeta, User]

Postmeta

import Post from './post'

const Postmeta = `
  type Postmeta {
    id: Int
    meta_id: Int
    post_id: Int
    meta_key: String
    meta_value: String
    connecting_post: Post
  }
`

export default () => [Postmeta, Post]

MetaType

const MetaType = `
  enum MetaType {
    _thumbnail_id
    _wp_attached_file
    react_layout
    amazonS3_info
    order
  }
`

export default MetaType

Category

import Post from './post'

const Category = `
  type Category {
    term_id: Int!
    name: String
    slug: String
    posts(post_type: String = "post", limit: Int, skip: Int): [Post]
  }
`

export default () => [Category, Post]

Menu

import MenuItem from './menuItem'

const Menu = `
  type Menu {
    id: ID!
    name: String
    items: [MenuItem]
  }
`

export default () => [Menu, MenuItem]

MenuItem

import Post from './post'

const MenuItem = `
  type MenuItem {
    id: ID!
    post_title: String
    linkedId: Int
    object_type: String
    order: Int
    navitem: Post
    children: [MenuItem]
  }
`

export default () => [MenuItem, Post]

Setting

const Setting = `
  type Setting {
    uploads: String
    amazonS3: Boolean
  }
`

export default Setting

Inputs

OrderInput

const OrderInput = `
  input OrderInput {
    orderBy: String,
    direction: String
  }
`

export default OrderInput

Queries

WordExpress provides some out-of-the-box queries to do some basic stuff like getting posts, getting posts by category, getting a post by post_type, etc.

Posts

posts(post_type: String = "post", limit: Int, skip: Int, order: OrderInput): [Post]

You can query posts by post_type. If you don't provide a post_type, it will default to 'post'. You can also limit the results and skip results (allowing for pagination). Also, you can provide a custom sorting object to sort the results. Here's an example of sorting:

screen shot 2017-12-13 at 12 31 14 pm

Layouts for Pages and Posts

Posts and pages can be assigned a Component to use as a layout. You can use the WordExpress Companion Plugin for WordPress which will allow you to add the custom field to any page or post. Or you can add your own custom field. It needs to be called page_layout_component. Here's an example of the querying with a layout:

screen shot 2017-12-13 at 12 41 43 pm

Post

post(name: String, id: Int): Post

Returns a Post by either its ID or its name.

screen shot 2017-12-13 at 12 57 05 pm

Menu

menus(name: String!): Menu

Returns a menu and the menu items associated with it, as well as children items. Uses the slug of the menu that is registered with WordPress.

screen shot 2017-12-13 at 12 52 01 pm

Category

category(term_id: Int!): Category

Gets a category by its ID. Also capable of returning all posts with the category id. Here's an example:

screen shot 2017-12-13 at 12 59 57 pm

Postmeta

postmeta(post_id: Int!, keys:[MetaType]): [Postmeta]

Gets the postmeta of a post by the post id.

screen shot 2017-12-13 at 1 28 34 pm

If keys are passed it, it will only return those keys which are part of the MetaType. Example:

screen shot 2017-12-13 at 1 32 49 pm

More Repositories

1

WordExpress

WordPress using Node, React, GraphQL, and Apollo
JavaScript
1,561
star
2

wordexpress-starter-vue

WordPress with Vue, GraphQL, and Node
Vue
256
star
3

WordExpress-Server

A GraphQL server that connects to a WordPress database
JavaScript
60
star
4

wordexpress-starter-react

JavaScript
35
star
5

MeteorCMS

A simple, lightweight CMS for individual blogs or portfolios
CSS
34
star
6

vue-tutorials

JavaScript
29
star
7

Emojinate-old

Emojinate is a story/blogging platform that gives you a string of 20 random emojis that you craft a story around.
JavaScript
23
star
8

react-cssmodules-sass-boilerplate

CSS
16
star
9

WordExpress-Plugin

PHP
11
star
10

Meteor-Setup-Bash-Script

a bash script that setups up a general folder structure for meteor apps
Shell
11
star
11

SoYou

JavaScript
8
star
12

module-docs

an npm package that creates a server to browse node module README files
JavaScript
8
star
13

Orbital-CMS

CMS Built using Meteor JS
JavaScript
8
star
14

WordExpressComponents

JavaScript
7
star
15

ApolloPress

JavaScript
5
star
16

PushQuotes_Extension

JavaScript
4
star
17

meteor-login-package

A custom login package for meteor js
JavaScript
4
star
18

reruled-two

JavaScript
4
star
19

MarvelComicCovers

A simple app built using Meteor that allows the user to compare two comic book covers and pick which one they like best
CSS
4
star
20

gifgame

CSS
4
star
21

dnd-dm-graphql-schema

JavaScript
3
star
22

ReRuled-React

JavaScript
3
star
23

meteor-errors-package

Basic error notification package for Meteor.js - a slightly more advanced version than the Discover Meteor tutorial
JavaScript
3
star
24

Cardtharsis

JavaScript
3
star
25

vs-code-gist-generator

Easily create a Github Gist from selected code in VS Code
JavaScript
2
star
26

wordexpress-tools

JavaScript
2
star
27

PushQuotes_Webpack

JavaScript
2
star
28

react-graphql-boilerplate

JavaScript
2
star
29

HackForChangeDC

JavaScript
1
star
30

rss-reader-server

JavaScript
1
star
31

PushQuotes

JavaScript
1
star
32

deploy-the-jewels

A VS Code extension that executes your deploy script and gives you a random Run The Jewels music video.
JavaScript
1
star
33

emojinate-codestar

GitHub repository for AWS CodeStar Node.js web application emojinate-codes.
JavaScript
1
star
34

newt-qwik

TypeScript
1
star
35

dotfiles

Shell
1
star
36

ahoy

Easy on-boarding for any project
JavaScript
1
star
37

dnd-dm-server

JavaScript
1
star
38

something

1
star
39

reruled

Vue
1
star
40

newt-extension

JavaScript
1
star
41

playlast

Svelte
1
star
42

ahoy-api

backend service for ahoy app
JavaScript
1
star
43

newt

JavaScript
1
star
44

ramsaylanier.github.io

HTML
1
star
45

ArduinoGuitarMod

C++
1
star