Template System
Templates in Faust bring the power of the WordPress Template Hierarchy to your JavaScript frontend application. This reference guide describes in detail how Templates are resolved and how to develop templates using this system.
If you prefer, see this video overview of Using the WordPress Template Hierarchy with Faust.js.
How Templates Are Resolved
The template resolver works by sending a preliminary GraphQL request (called the Seed Query) for the given URI in WordPress. The response includes data like the databaseId, slug, content type, etc, which is then used to determine what the possible templates are for the given URI.
For example, let’s say a user visits the /sample-page
URI on our Faust app, and in WordPress we have a page called “Sample Page” with the same URI. The template resolver will receive the following data as the Seed Query:
Seed Query Response
{
"data": {
"node": {
"__typename": "Page",
"uri": "/sample-page/",
"id": "cG9zdDoyNjQ=",
"databaseId": 264,
"isContentNode": true,
"slug": "sample-page",
"contentType": {
"node": {
"name": "page"
}
},
"template": {
"templateName": "Default"
},
"isFrontPage": false,
"isPostsPage": false
}
}
}
Code language: JSON / JSON with Comments (json)
With this data, we then apply a set of rules/logic to get all the possible templates for the /sample-page
route.
Setting Up the Template System
To setup your Faust template system, start by creating a directory in your project (it can be named anything, but we typically call it wp-templates
). Inside this newly created directory, create index.js
with an empty object as the default export:
// wp-templates/index.js
export default {
// Templates go here
};
Code language: JavaScript (javascript)
Templates must be placed in this object with the key being the template name, and the value being the default export of the template. For example:
// wp-templates/index.js
import page from './page';
import single from './single';
export default {
page: page,
single: single,
};
Code language: JavaScript (javascript)
Finally, you must include the templates in faust.config.js
at your project root:
// faust.config.js
import { setConfig } from '@faustwp/core';
import templates from './wp-templates/index.js';
/**
* @type {import('@faustwp/core').FaustConfig}
**/
export default setConfig({
templates: templates,
});
Code language: JavaScript (javascript)
Template Structure
A faust template has three parts, the component, query, and variables. Here is an example template in its most basic form:
// wp-templates/single.js
import { gql } from '@apollo/client';
// The Component is required
export default function Component(props) {
const { title, content } = props?.data?.post;
return (
<>
<h1>{title}</h1>
<div dangerouslySetInnerHTML={{ __html: content }} />
</>
);
}
// Query is optional
Component.query = gql`
query GetPost($databaseId: ID!) {
post(id: $databaseId, idType: DATABASE_ID) {
title
content
}
}
`;
// Variables is optional
Component.variables = (seedQuery, ctx) => {
return {
databaseId: seedQuery?.databaseId,
};
};
Code language: JavaScript (javascript)
Component
The Component
portion of the template serves as the rendering layer. You can compare this to a traditional Next.js file based page, where the contents of this component will be rendered to the webpage.
props
are exposed to the Component
as usual in React. There are two props that are specific to a template:
props.data
: the response to the template’squery
props.loading
: aboolean
flag to determine if the template’squery
is still being fetched
Component Variables
The Component.variables
portion of the template is a callback function which returns an object of GraphQL variables for the template’s GraphQL query.
The Component.variables()
callback has two parameters: seedQuery
, and context
:
Component.variables(seedQuery, context) => {
return {
// Return GraphQL variables here as needed
}
}
Code language: PHP (php)
The seedQuery
parameter is the data resulted from the seed query. You can learn more about the request and response of the seed query here.
The context
of Component.variables
has the following properties:
interface {
asPreview?: boolean
locale?: string
}
Code language: PHP (php)
Finally, the object returned from this function will be usable in your template’s GraphQL Query.
Component Query
The Component.query
portion of the template is a GraphQL query string used to fetch the template’s data. It can be used as follows:
import { gql } from '@apollo/client';
Component.query = gql`
query GetPost($databaseId: ID!, $asPreview: Boolean = false) {
post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
title
content
}
}
`;
Code language: PHP (php)
Notice the $databaseId
and $asPreview
variables as well. These are available because they were configured in the Component.variables
callback:
Component.variables = (seedQuery, context) => {
return {
databaseId: seedQuery?.databaseId,
asPreview: context?.asPreview,
};
};
Code language: JavaScript (javascript)