Queries

-


Statik framework levarages GraphQL mechanism shipped with Gatsby.js. It is a data layer API to consume external data within Gatsby generated website. There is an extensive explanation of how to use data fetched from different providers in the official Gatsby documentation. However, as long as your project consumes WordPress generated data only, it is handled out of the box by the Statik WordPress plugin. It exposes GraphQL mechanism as a wp-json extension, which is consumed during the Gatsby.js building process.

Models

Models exposed in the GraphQL interface depend on a project configuration. By default, Statik plugin exposes a list of WordPress native post types as well as some added by the framework like Documents, Authors, or People. To find out full list of available models simply visit the GraphiQL panel within the WordPress Dashboard, then navigate to Statik > GraphQl IDE

GraphiQL IDE within WordPress

GraphiQL IDE within WordPress

Native Models

Your boilerplate based project comes with some models ready to use without any configuration. The list may change over a time and may be different when manipulated by integrations or extensions so always refer to the list available in the WordPress dashboard (or graphiql interface in Gatsby).

List of native models

  • Posts – collection of posts,
  • Categories – collection of post categories,
  • Tags – collection of post tags,
  • Pages – collection of pages,
  • People – collection of people custom post type enabled by Statik Framework,
  • PeopleCategories – collection of category-like taxonomy applied to people custom post type enabled by Statik Framework,
  • PeopleTags – collection of tag-like taxonomy applied to people custom post type enabled by Statik Framework,
  • Documents – collection of documents custom post type enabled by Statik Framework,
  • DocumentCategories – collection of category-like taxonomy applied to documents custom post type enabled by Statik Framework,
  • DocumentTags – collection of tags-like taxonomy applied to documents custom post type enabled by Statik Framework,
  • GutenbergBlocks – collection of Gutenberg blocks. Please be aware blocks are applied as children of custom post types with Gutenberg experience enabled. These nodes, as long as provided as properties to the <StatikBlocks> component result in rendered Gutenberg content,
  • MediaItems – collection of media in the library,
  • Megamenus – collection of WordPress entities with Gutenberg content available to render as a mega menu,
  • Menus – collection of WordPress native menus,
  • MenuItems – collection of items added to WordPress native menus.

Please note, some collections are considered as child nodes applied to other models. The approach allows to query data more efficiently within the Gatsby app.

Custom Post Types

One of the most important features of WordPress is an ability of adding custom post types to manage content efficiently. Considering the fact, data is always presented in the front-end application, it needs to be enabled in WordPress based GraphQL interface.

Statik Framework covers adding a GraphQL enabled custom post types using one of the following ways:

  • Developers to add CPT by modifying WordPress child theme,
  • Content editors to use CPT generator plugin,

Adding CPT by modifying WordPress child theme

To ensure WordPress uses the most up-to-date version of theme, it is recommended not to edit any of its files directly. Instead, it is better to come up with a child theme. The approach is extenslively described on Updating page.

Assuming developers will follow directory hierarchy of the parent Statik theme, to add a custom post type named "Movies", make sure the following snippet within functions.php of a child theme is available.

/**
 * Load Custom post types.
 */
require_once __DIR__ . '/includes/custom-post-types/index.php';
backend/themes/statik-child/functions.php

backend/themes/statik-child/includes/custom-post-types/index.php becomes a hub for all custom post types added on a project level. The next step is to add a reference to CPT files held in a separate directory.

<?php

declare(strict_types=1);

\defined('ABSPATH') || exit('Direct access is not permitted!');

/**
 * In this file can be added more WordPress Custom Post Types.
 * Each CPT should be in the separate directory and each file should
 * be included there using the `require_once` function.
 */
require_once __DIR__ . '/movies/cpt.php';
backend/themes/statik-child/includes/custom-post-types/index.php

backend/themes/statik-child/includes/custom-post-types/movies/cpt.php holds all information about the new CPT as shown below. Note the show_in_graphql, graphql_single_name and graphql_plural_name properties that enforce the custom post type to be shown within WordPress GraphQL interface so as a result its data to be available to use in Gatsby instance.

<?php

declare(strict_types=1);

\defined('ABSPATH') || exit('Direct access is not permitted!');

\add_action('init', 'statik_register_movies_cpt', 1);

if (false === \function_exists('statik_register_movies_cpt')) {
    /**
     * Register custom post type for Movies.
     *
     * @since 2.0.0
     */
    function statik_register_movies_cpt(): void
    {
        $labels = [
            'name' => \_x('Movies', 'Post Type General Name', 'statik'),
            'singular_name' => \_x('Movie', 'Post Type Singular Name', 'statik'),
            'menu_name' => \__('Movies', 'statik'),
            'name_admin_bar' => \__('Movies', 'statik'),
            'archives' => \__('Movie Archives', 'statik'),
            'attributes' => \__('Movie Attributes', 'statik'),
            'parent_item_colon' => \__('Parent Movie:', 'statik'),
            'all_items' => \__('All Movies', 'statik'),
            'add_new_item' => \__('Add New Movie', 'statik'),
            'add_new' => \__('Add New', 'statik'),
            'new_item' => \__('New Movie', 'statik'),
            'edit_item' => \__('Edit Movie', 'statik'),
            'update_item' => \__('Update Movie', 'statik'),
            'view_item' => \__('View Movie', 'statik'),
            'view_items' => \__('View Movies', 'statik'),
            'search_items' => \__('Search Movie', 'statik'),
            'not_found' => \__('Not found', 'statik'),
            'not_found_in_trash' => \__('Not found in Trash', 'statik'),
            'featured_image' => \__('Featured Image', 'statik'),
            'set_featured_image' => \__('Set featured image', 'statik'),
            'remove_featured_image' => \__('Remove featured image', 'statik'),
            'use_featured_image' => \__('Use as featured image', 'statik'),
            'insert_into_item' => \__('Insert into Movie', 'statik'),
            'uploaded_to_this_item' => \__('Uploaded to this Movie', 'statik'),
            'items_list' => \__('Movies list', 'statik'),
            'items_list_navigation' => \__('Movies list navigation', 'statik'),
            'filter_items_list' => \__('Filter Movies list', 'statik'),
        ];

        \register_post_type(
            'movie',
            [
                'label' => \__('Movie', 'statik'),
                'description' => \__('Movies', 'statik'),
                'labels' => $labels,
                'supports' => ['title', 'custom-fields', 'revisions'],
                'hierarchical' => false,
                'public' => true,
                'show_ui' => true,
                'show_in_menu' => true,
                'menu_position' => 20,
                'menu_icon' => 'dashicons-media-archive',
                'show_in_admin_bar' => true,
                'show_in_nav_menus' => true,
                'can_export' => true,
                'has_archive' => false,
                'exclude_from_search' => true,
                'publicly_queryable' => true,
                'capability_type' => 'post',
                'show_in_rest' => true,
                'rest_base' => 'documents',
                'rewrite' => ['with_front' => false],
                'show_in_graphql' => true,
                'graphql_single_name' => 'movie',
                'graphql_plural_name' => 'movies',
            ]
        );
    }
}
backend/themes/statik-child/includes/custom-post-types/movies/cpt.php

Using CPT generator plugin

@TBA: Damian

Querying data

Any data available in the WordPress GraphQL interface (@TBD: Damian to confirm) can be queried out of front-end Gatsby application. This approach allows to generate data JSONs that hydrates the front-end website during the build time. No further communication with WordPress is required – more about this concept is explained on the Foundation page.

Example presented below will create a single page that holds a post data. It will be returned for /insights/hello-world route. Also, the example implements Gutenberg Blocks support which is explained more in detail on Blocks page.

A component that is expected to render a Hello World page looks for a post with ID 18 in the GraphQL query. Please note, no JavaScript variables can be passed to the GraphQL call as it is performed outside the regular JavaScript lifecycle. If you need to make calls more dynamic, simply consider using Collection Routes explained more in detail on the Routing page – Collection Routes allows to pass dynamic variables that were picked out of the URL.

import React from 'react';
import PropTypes from 'prop-types';
import { graphql } from 'gatsby';

const HelloWorld = props => {
  const {
    data: {
      post: {
        title,
        gutenbergBlocks,
      },
    },
  } = props;

  return (
    <main>
      <h1>
      {gutenbergBlocks && gutenbergBlocks.nodes && (
        <StatikBlocks blocks={gutenbergBlocks.nodes} />
      )}
    </main>
  );
};

HelloWorld.propTypes = {
  data: PropTypes.shape({
    post: PropTypes.shape({
      title: PropTypes.string,
      gutenbergBlocks: PropTypes.shape({
        nodes: PropTypes.array,
      }),
    }),
  }),
};

export default HelloWorld;

export const query = graphql`
  query Query {
    post(id: 18) {
      title
      gutenbergBlocks {
        nodes {
          ...GutenbergBlockFragment
        }
      }
    }
  }
`;
frontend/src/pages/hello-world.js

Fragments

In the example above there's a reference to ...GutenbergBlockFragment, which is a fragment. Fragments are destructed into additional properties to be fetched in the GraphQL call. In other words, during the build phase, the script will consider this code

nodes {
  ...GutenbergBlockFragment
}

as the following

nodes {
  id
  databaseId
  parentId
  parentDatabaseId
  name
  attributes {
    key
    value
  }
  rawHtml
}

It will be possible to reference any of the properties in Gatsby frontend application without actually requesting them in the GraphQL call. Developers are in position to create their own fragments, however some of them are already bundled in the Statik Framework. Below you can find a list of fragments that might be helpful in the development:

...PostFragment

id
slug
uri
date
seo {
  node {
    ...NodeSeoFieldFragment
  }
}
featuredImage {
  node {
    ...MediaItemFragment
  }
}
author {
  node {
    name
  }
}
categories {
  nodes {
    slug
    name
  }
}
gutenbergBlocks {
  nodes {
    ...GutenbergBlockFragment
  }
}

...PageFragment

id
slug
uri
seo {
  node {
    ...NodeSeoFieldFragment
  }
}
gutenbergBlocks {
  nodes {
    ...GutenbergBlockFragment
  }
}

...MediaItemFragment

sourceUrl
srcSet
placeholderBase64
mediaDetails {
  height
  width
}
title
altText
id
parentId
databaseId
parentDatabaseId
url
label
cssClasses
order
childItems {
  nodes {
    id
  }
}
megamenu {
  node {
    gutenbergBlocks(first: 1000) {
      nodes {
        ...GutenbergBlockFragment
      }
    }
  }
}

...GutenbergBlockFragment

id
databaseId
parentId
parentDatabaseId
name
attributes {
  key
  value
}
rawHtml
...GutenbergFormsBlockFieldFragment
...GutenbergCoverBlockFieldFragment
...GutenbergCardsBlockFieldFragment
...GutenbergTeamMemberBlockFieldFragment

...NodeSeoFieldFragment

canonicalUrl
description
imageUrl
noarchive
nofollow
noindex
ogDescription
ogTitle
redirectUrl
title
twitterDescription
twitterTitle
  • Best Practises – Build a Single Page
  • Best Practises – Build a Template using Collection Routes
Edit on GitHub