Overview

-


Statik Framework works with the Gutenberg editor out of the box. One of Gutenberg's most important paradigms is editing content in block-based structure. Blocks are simply a components oriented on deliverying a complete functionality with its configuration pane and ability to modify a content, visually, on-screen just as it is edited. Such approach is called as What You See Is What You Get (WYSIWYG) and it replaces the traditional concept of freeform text with embedded media and shortcodes.1

Statik Blocks Library

Due to a decoupled architecture of Statik websites, blocks need to be prepared to be consumed by both back-end and front-end experience separately. Therefore, Statik framework comes with a bundled set of blocks, maintained and developed by a dedicated team. It consists of core blocks, which reflects all changes from original blocks released with Gutenberg updates, as well as bespoke blocks to focus on more complex challenges of modern web development for corporate clients and business in general. The team were supposed to address the following issues when developing a dedicated blocks libary:

  • Deliver blocks with a long term support so our partner agencies could maintain website for years, any applied changes, even to core blocks, will treat backwards compatibility as a priority,
  • Deliver blocks with a support for back-end and front-end experience at the same time. On top of a regular Gutenberg instance of a block, they are delivered with an additional layer of React.js components to handle the front-end experience properly so as a result it could be easily used in Gatsby powered applications,
  • Deliver blocks with a unified development experience to let developers update a single codebase for both back-end and front-end experience.

Blocks Architecture

Statik Block Library or any other Statik compatible block library follow the structure of regular Gutenberg blocks. Additionaly, to align with a decoupled arichtecture, they come with an additional React.js layer for Gatsby front-end experience. From a web developer perspective, it relies on an unified and consistent codebase. Any changes applied are within a single directory and then, they are transformed into:

  • A WordPress plugin to enable blocks in Gutenberg experience, and
  • A Gatsby.js plugin to enable blocks in front-end experience.

Any Statik based project can use more than one blocks library. In fact, we encourage our partner agencies to come up with their own block libraries as reusing components saves a lot of time in the development phase.

Example structure of a Statik enhanced block

Blocks Shadowing

Statik Block Library or any other Statik compatible block library can be easily overriden or extended using a shadowing process. The concept is well known in Gatsby based applications and it is described in Gatsby Documentation. Web developers can implement changes to blocks based on project or agency needs by replacing original files.

Blocks Processing

The Statik Framework automatically process Statik-enhanced Gutenberg blocks so as a result they are ready to use within a front-end application. All blocks from a Statik Blocks Library fully align with WYSIWYG approach making the editing process as easy as in classic PHP-based websites.

For an upcoming read, blocks will be divided into 2 categories which affects how they are processed by the Statik Framework

  • Dynamic Blocks (or stateful blocks, application rendered blocks) – these blocks are dynamic or complex enough to require at least a state management in the front-end experience (Think about blocks that would require tons of jQuery code to handle interactions in the classic approrach). In the front-end, they will be converted into dynamic React.js components that are hydrated with properties coming from block settings,
  • Static Blocks (or Server Side Renderable blocks, Server Side Rendered Blocks, SSR blocks) – these blocks are shipped to the front-end applications as HTML output to improve performance of rendering a website. Paragraphs, buttons, quotes or simillar will be shipped differently to dynamic ones.

The lifecycle

This section describes the complete journey of blocks delivery which starts in the Gutenberg experience and ends in the front-end Gatsby.js application. Assuming, we already took Statik-enabled blocks with an additional React.js front-end layer into equation, the lifecycle of such a delivery is divided into 4 phases:

  1. Saving data
  2. Exposing data
  3. Consuming data
  4. Rendering blocks

Saving data

All post types with Gutenberg editing experience enabled perform additional activities to save blocks data in a dedicated database space. A hook attached to save_post action (@TBD: Damian – filter?) in WordPress, iterates through inserted blocks to process blocks before saving it to the database. Static blocks are converted into a HTML code and dynamic blocks are saved as a JSON object of block configuration.

Exposing data

Data saved in a database and then exposed in the GraphQL interface. Static blocks are printed as a raw code in the rawHtml property, dynamic blocks are printed as a collection of key value pairs in the attributes property. Some of dynamic blocks are also processed by mutators so the raw data is adjusted to the front-end application needs.

Example of a Dynamic Block

Example of a Static Block

Consuming data

In the front-end application, whenever an output website is built (think about statik build or statik develop commands), Gatsby runs through a GraphQL interface exposed in the WordPress API and downloads data to its own internal API, also run on a GraphQL. As a result block data can be easily consumed by pages or collection routes based on project needs, more about how to use data from an internal Gatsby API is explained on Queries page.

Whenever a specific page or collection route query blocks, the easiest way is to use ...GutenbergBlockFragment fragment described on Queries page. The GraphQL call will fetch all data that is necessary to render blocks in the front-end experience, with no further hassle. See the example below, it presents a complete component that fetches Gutenberg data and prints it on the website.

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

Rendering blocks

As shown on the example above, data fetched through an internal Gatsby API can be rendered thanks to a <StatikBlocks> component. The collection of blocks delivered in the response can be passed directly to the component. It is then iterated and based on block type and whether it is known as static or dynamic component, each element is rendered either by <StaticRenderer> or <DynamicRenderer> internal components.

Please note, only blocks plugged-in as a WordPress and Gatsby extensions will be rendered. Makre sure proper library is installed on both ends to display block properly.

<StaticRenderer>

Static renderer is responsible for presenting a raw HTML output. Such payload is obviously processed by side xss libaries to stip out any dangerous code that might potentially impact visitors. As a result, code rendered on a website should be safe to use even before WAF is applied.

<DynamicRenderer>

Dynamic renderer is responsible for mapping a block data with an actual React.js component meant to render it on a website. All block attributes (key value pairs) are injected into the component as properties so they impact the way content is presented.

Neither <StaticRenderer> or DynamicRenderer should be consumed in projects. These are internal functions that are automatically called from a StaticBlocks React.js component.

  • Best practises: SSR or Dynamic block?
Edit on GitHub