{"id":13605425,"url":"https://github.com/ramsaylanier/WordExpressSchema","last_synced_at":"2025-04-12T05:33:02.693Z","repository":{"id":57399057,"uuid":"50382034","full_name":"ramsaylanier/WordExpressSchema","owner":"ramsaylanier","description":"This package provides a connection to a WordPress database using Sequelize and provides a standard set of GraphQL queries.","archived":false,"fork":false,"pushed_at":"2018-12-17T14:16:13.000Z","size":158,"stargazers_count":148,"open_issues_count":1,"forks_count":31,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-11T07:07:06.163Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ramsaylanier.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-25T21:25:27.000Z","updated_at":"2024-10-16T20:03:53.000Z","dependencies_parsed_at":"2022-08-24T20:11:29.184Z","dependency_job_id":null,"html_url":"https://github.com/ramsaylanier/WordExpressSchema","commit_stats":null,"previous_names":["ramsaylanier/wordexpress-schema"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramsaylanier%2FWordExpressSchema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramsaylanier%2FWordExpressSchema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramsaylanier%2FWordExpressSchema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ramsaylanier%2FWordExpressSchema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ramsaylanier","download_url":"https://codeload.github.com/ramsaylanier/WordExpressSchema/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248524257,"owners_count":21118610,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:00:58.561Z","updated_at":"2025-04-12T05:33:02.309Z","avatar_url":"https://github.com/ramsaylanier.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"[![npm version](https://badge.fury.io/js/wordexpress-schema.svg)](https://badge.fury.io/js/wordexpress-schema)\n\n# wordexpress-schema\n\nWordExpress 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.\n\nWordExpress Schema exports the following:\n\n- **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. \n\n- **WordExpress Resolvers**: resolving functions that work with the `WordExpressDatabase` connectors to resolve GraphQL queries\n\n- **WordExpress Definitions**: a modular GraphQL schema definition.\n\nCombined, this package can be used with any GraphQL server (like [Apollo Server](https://www.apollographql.com/docs/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.\n\nIf you'd like a solution that already includes a GraphQL server for you, check out the [WordExpress Server repository](https://github.com/ramsaylanier/WordExpress-Server). WordExpress Server uses `WordExpress Schema` and provides you with a GraphQL server out of the box. \n\n## Installation\n\n```\nnpm install --save-dev wordexpress-schema\n```\n\n## Usage\n\n* [Using WordExpress Database](#wordexpressdatabase)\n\n  * [Connection Settings](#connection-settings)\n\n  * [The Database Class](#the-database-class)\n\n    * [The Models](#the-models)\n\n\n* [Making an Executable Schema](#creating-the-schema)  \n\n* [Using Definitions and Resolvers with Apollo Server](#using-definitions-and-resolvers-with-apollo-server)\n\n* [Types](#types)\n\n  * [Post](#post)\n  \n  * [Postmeta](#postmeta)\n  \n  * [MetaType](#metatype)\n  \n  * [Category](#category)\n  \n  * [Menu](#menu)\n  \n  * [MenuItem](#menuitem)\n  \n  * [Setting](#setting)\n\n* [Inputs](#inputs)\n\n* [Queries](#queries)\n\n\n\n## WordExpressDatabase\nThe 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.\n\nBelow is the basic implementation:\n```es6\n\n//db.js\nimport Config from 'config'\nimport {WordExpressDatabase} from 'wordexpress-schema'\n\n/*\n  Example settings object:\n  public: {\n    uploads: \"http://wordexpress.s3.amazonaws.com/\",\n    amazonS3: true\n  },\n  private: {\n    wp_prefix: \"wp_\",\n    database: {\n      name: \"wpexpress_dev\",\n      username: \"root\",\n      password: \"\",\n      host: \"127.0.0.1\"\n    }\n  }\n*/\n\n\nconst publicSettings = Config.get('public')\nconst privateSettings = Config.get('private')\n\nconst Database = new WordExpressDatabase({publicSettings, privateSettings})\nconst {connectors, models} = Database\n\nexport default Database\nexport {connectors, models}\n```\n\n### Connection Settings\n\nIn the above example, **WordExpressDatabase** is passed a settings object that contains some WordPress database settings. Name, username, password, and host are all self-explanatory.\n\nWordExpress 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.\n\nLastly, 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.\n\n### The Database Class\n\nThe 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.\n\n#### The Models\nHere 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.\n\n```es6\nPost: Conn.define(prefix + 'posts', {\n  id: { type: Sequelize.INTEGER, primaryKey: true},\n  post_author: { type: Sequelize.INTEGER },\n  post_title: { type: Sequelize.STRING },\n  post_content: { type: Sequelize.STRING },\n  post_excerpt: { type: Sequelize.STRING },\n  post_status: { type: Sequelize.STRING },\n  post_type: { type: Sequelize.STRING },\n  post_name: { type: Sequelize.STRING},\n  post_date: { type: Sequelize.STRING},\n  post_parent: { type: Sequelize.INTEGER},\n  menu_order: { type: Sequelize.INTEGER}\n}),\nPostmeta: Conn.define(prefix + 'postmeta', {\n  meta_id: { type: Sequelize.INTEGER, primaryKey: true, field: 'meta_id' },\n  post_id: { type: Sequelize.INTEGER },\n  meta_key: { type: Sequelize.STRING },\n  meta_value: { type: Sequelize.INTEGER },\n}),\nUser: Conn.define(prefix + 'users', {\n  id: { type: Sequelize.INTEGER, primaryKey: true },\n  user_nicename: { type: Sequelize.STRING },\n  user_email: { type: Sequelize.STRING },\n  user_registered: { type: Sequelize.STRING },\n  display_name: { type: Sequelize.STRING }\n}),\nTerms: Conn.define(prefix + 'terms', {\n  term_id: { type: Sequelize.INTEGER, primaryKey: true },\n  name: { type: Sequelize.STRING },\n  slug: { type: Sequelize.STRING },\n  term_group: { type: Sequelize.INTEGER },\n}),\nTermRelationships: Conn.define(prefix + 'term_relationships', {\n  object_id: { type: Sequelize.INTEGER, primaryKey: true },\n  term_taxonomy_id: { type: Sequelize.INTEGER },\n  term_order: { type: Sequelize.INTEGER },\n}),\nTermTaxonomy: Conn.define(prefix + 'term_taxonomy', {\n  term_taxonomy_id: { type: Sequelize.INTEGER, primaryKey: true },\n  term_id: { type: Sequelize.INTEGER },\n  taxonomy: { type: Sequelize.STRING },\n  parent: { type: Sequelize.INTEGER },\n  count: { type: Sequelize.INTEGER },\n})\n```\n\n## Creating The Schema\nWordExpress uses [GraphQL Tools](https://github.com/apollographql/graphql-tools)'s [makeExecutableSchema](https://www.apollographql.com/docs/graphql-tools/generate-schema.html#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:\n\n```es6\nimport {makeExecutableSchema} from 'graphql-tools'\nimport {WordExpressDefinitions, WordExpressResolvers} from 'wordexpress-schema'\nimport {connectors} from './db'\nimport Config from 'config'\n\nconst RootResolvers = WordExpressResolvers(connectors, Config.get('public'))\n\nconst schema = makeExecutableSchema({\n  typeDefs: [WordExpressDefinitions]\n  resolvers: RootResolvers\n})\n\nexport default schema\n```\n\n`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. \n\n`WordExpressDefinitions` is a modular GraphQL schema written in the [GraphQL Schema language](https://www.apollographql.com/docs/graphql-tools/generate-schema.html#schema-language). \n\n\n## Using Definitions and Resolvers with Apollo Server\nThis example is from the [WordExpress Server](https://github.com/ramsaylanier/WordExpress-Server). \nAfter creating an executable schema, all we need to do is provide the schema to [apollo-server-express](https://www.apollographql.com/docs/apollo-server/servers/express.html).\n\n```es6\nimport {ApolloServer} from 'apollo-server'\nimport {WordExpressDefinitions, WordExpressResolvers} from 'wordexpress-schema'\nimport {connectors} from './db'\nimport Config from 'config'\n\nconst PORT = 4000\n\nconst resolvers = WordExpressResolvers(connectors, Config.get('public'))\n\nconst server = new ApolloServer({\n  typeDefs: [...WordExpressDefinitions],\n  resolvers\n})\n\nserver.listen({port: PORT}, () =\u003e {\n  console.log(`wordexpress server is now running on port ${PORT}`)\n})\n```\n\n## Types\n\n### Post\n```es6\nimport Postmeta from './Postmeta'\nimport User from './User'\n\nconst Post = `\n  type Post {\n    id: Int\n    post_title: String\n    post_content: String\n    post_excerpt: String\n    post_status: String\n    post_type: String\n    post_name: String\n    post_parent: Int\n    post_date: String\n    menu_order: Int\n    post_author: Int\n    layout: Postmeta\n    thumbnail: String\n    post_meta(keys: [MetaType], after: String, first: Int, before: String, last: Int): [Postmeta]\n    author: User\n  }\n`\n\nexport default () =\u003e [Post, Postmeta, User]\n```\n\n### Postmeta\n``` es6\nimport Post from './post'\n\nconst Postmeta = `\n  type Postmeta {\n    id: Int\n    meta_id: Int\n    post_id: Int\n    meta_key: String\n    meta_value: String\n    connecting_post: Post\n  }\n`\n\nexport default () =\u003e [Postmeta, Post]\n```\n\n### MetaType\n```es6\nconst MetaType = `\n  enum MetaType {\n    _thumbnail_id\n    _wp_attached_file\n    react_layout\n    amazonS3_info\n    order\n  }\n`\n\nexport default MetaType\n```\n\n### Category\n``` es6\nimport Post from './post'\n\nconst Category = `\n  type Category {\n    term_id: Int!\n    name: String\n    slug: String\n    posts(post_type: String = \"post\", limit: Int, skip: Int): [Post]\n  }\n`\n\nexport default () =\u003e [Category, Post]\n```\n\n### Menu\n```es6\nimport MenuItem from './menuItem'\n\nconst Menu = `\n  type Menu {\n    id: ID!\n    name: String\n    items: [MenuItem]\n  }\n`\n\nexport default () =\u003e [Menu, MenuItem]\n```\n\n### MenuItem\n```es6\nimport Post from './post'\n\nconst MenuItem = `\n  type MenuItem {\n    id: ID!\n    post_title: String\n    linkedId: Int\n    object_type: String\n    order: Int\n    navitem: Post\n    children: [MenuItem]\n  }\n`\n\nexport default () =\u003e [MenuItem, Post]\n```\n\n### Setting\n```es6\nconst Setting = `\n  type Setting {\n    uploads: String\n    amazonS3: Boolean\n  }\n`\n\nexport default Setting\n```\n\n## Inputs\n\n### OrderInput\n```es6\nconst OrderInput = `\n  input OrderInput {\n    orderBy: String,\n    direction: String\n  }\n`\n\nexport default OrderInput\n```\n\n\n## Queries\nWordExpress 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.\n\n### Posts\n```\nposts(post_type: String = \"post\", limit: Int, skip: Int, order: OrderInput): [Post]\n```\n\nYou 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:\n\n\u003cimg width=\"1035\" alt=\"screen shot 2017-12-13 at 12 31 14 pm\" src=\"https://user-images.githubusercontent.com/2359852/33953187-258e7394-e002-11e7-9792-a4680d087cd7.png\"\u003e\n\n#### Layouts for Pages and Posts\nPosts and pages can be assigned a Component to use as a layout. You can use the [WordExpress Companion Plugin](https://github.com/ramsaylanier/WordExpress-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:\n\n\u003cimg width=\"1064\" alt=\"screen shot 2017-12-13 at 12 41 43 pm\" src=\"https://user-images.githubusercontent.com/2359852/33953467-11e93990-e003-11e7-9994-fb967a2acb4a.png\"\u003e\n\n### Post\n```\npost(name: String, id: Int): Post\n```\n\nReturns a Post by either its ID or its name.\n\n\u003cimg width=\"1431\" alt=\"screen shot 2017-12-13 at 12 57 05 pm\" src=\"https://user-images.githubusercontent.com/2359852/33954058-306b90f0-e005-11e7-83fe-383c6ed490f6.png\"\u003e\n\n### Menu\n```\nmenus(name: String!): Menu\n```\n\nReturns 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.\n\n\u003cimg width=\"1065\" alt=\"screen shot 2017-12-13 at 12 52 01 pm\" src=\"https://user-images.githubusercontent.com/2359852/33953852-8479de64-e004-11e7-84b3-c51d84eb98fd.png\"\u003e\n\n\n### Category\n```\ncategory(term_id: Int!): Category\n```\n\nGets a category by its ID. Also capable of returning all posts with the category id. Here's an example:\n\n\n\u003cimg width=\"1373\" alt=\"screen shot 2017-12-13 at 12 59 57 pm\" src=\"https://user-images.githubusercontent.com/2359852/33954203-8f2031e6-e005-11e7-932b-fdc1d4321e53.png\"\u003e\n\n### Postmeta\n```\npostmeta(post_id: Int!, keys:[MetaType]): [Postmeta]\n```\nGets the postmeta of a post by the post id. \n\n\u003cimg width=\"1088\" alt=\"screen shot 2017-12-13 at 1 28 34 pm\" src=\"https://user-images.githubusercontent.com/2359852/33955582-02546f98-e00a-11e7-8fcb-c106b9372b65.png\"\u003e\n\nIf `keys` are passed it, it will only return those keys which are part of the `MetaType`. Example:\n\n\u003cimg width=\"995\" alt=\"screen shot 2017-12-13 at 1 32 49 pm\" src=\"https://user-images.githubusercontent.com/2359852/33955614-2603bf98-e00a-11e7-9ce3-100b60190dd6.png\"\u003e\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framsaylanier%2FWordExpressSchema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Framsaylanier%2FWordExpressSchema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framsaylanier%2FWordExpressSchema/lists"}