Gutenberg: Creating templates that fully control the content layout

Created on 13 Jul 2018  路  2Comments  路  Source: WordPress/gutenberg

Block templates are great as a starting point for users. But plugin and theme developers also need a way for a template to completely control the layout of some content. Furthermore, this sort of controlling template must be extensible, such that when it is modified, everything across the site being rendered with the template is updated.

For example, consider a block template being used to display a CPT created by a plugin. The plugin author may wish to have the template locked such that it may only be changed at a global level, not for individual posts. This would be useful for theme developers who wish to customize how the CPT is displayed within their theme, or extension developers who wish to display additional information on the CPT's page.

One significant challenge to overcome will be to structure this in such a way that when a template is modified, any existing content (e.g. existing CPT posts) renders with the new template. Currently, if a block template is modified, existing posts do not render any differently. Only new posts have the new template applied.

_(Note that although it's convenient to think of these templates with regard to posts and CPT's, it is also applicable to parent Blocks using a template to lay out their children.)_

Implementation thoughts and concerns

  • The template needs to control both the Edit UI and the rendered frontend content, so that the user sees in the editor the layout that will ultimately be rendered on the frontend.

  • The content controlled by this sort of template will likely need to be rendered dynamically on the server, rather than statically from post_content. Otherwise we would have no way to change the rendered output of existing posts when the template is modified.

  • Currently, a template cannot (in general) be rendered without some frontend code being run. Consider a modified template that includes a static block. This block can only be rendered by running its save method in JavaScript. However, that method is not available on the server where the template is defined, so rendering an existing post with the new template will not be possible without some client-side code also being run.

  • Editable blocks within a template will likely need to have a "key" or some sort of unique identifier associated with them. This way, when a template is modified and blocks are moved around, the existing content can be displayed in the correct location.

Would love to start to have some discussion around this. I think it's a "phase two" thing, but it's a pretty important and challenging problem that we'll need to get right in order to make Gutenberg work well for theme and plugin developers.

[Feature] Templates API [Type] Enhancement [Type] Question

Most helpful comment

A huge step forward in this context would be to simply allow a template to have an assigned "id" which would then be added to the template wrapper as a class.

$block = [
    'template' => [
        [ 'block/name' ],
    ],
];

Becomes...

$block = [
   'template' => [
        'id' => 'my_lackluster_template',
        'blocks' => [
              [ 'block/name' ],
         ]
    ]
];

...which opens templates to be extensible via properties.

Maybe eventually including something like the ability to reference other templates:

$block = [
    'template' => [
        'id' => 'my_lackluster_template',
        'blocks' => [
            [ 'objects_are_blocks' ],
            'strings_reference_another_template',
            [ 'etc' ],
        ]
    ]
];

Setting aside that particular fever-dream, in the editor:

<div class="editor-block-list__block-edit template-my_lackluster_template" data-block="...">
...
</div>

Given that structure, we can now add CSS which specifically targets the template, both in-editor and on the front end.

All 2 comments

A huge step forward in this context would be to simply allow a template to have an assigned "id" which would then be added to the template wrapper as a class.

$block = [
    'template' => [
        [ 'block/name' ],
    ],
];

Becomes...

$block = [
   'template' => [
        'id' => 'my_lackluster_template',
        'blocks' => [
              [ 'block/name' ],
         ]
    ]
];

...which opens templates to be extensible via properties.

Maybe eventually including something like the ability to reference other templates:

$block = [
    'template' => [
        'id' => 'my_lackluster_template',
        'blocks' => [
            [ 'objects_are_blocks' ],
            'strings_reference_another_template',
            [ 'etc' ],
        ]
    ]
];

Setting aside that particular fever-dream, in the editor:

<div class="editor-block-list__block-edit template-my_lackluster_template" data-block="...">
...
</div>

Given that structure, we can now add CSS which specifically targets the template, both in-editor and on the front end.

And maybe a block's template should be an array of template objects, which can contain contextual information about which to use where. I suppose you could argue that you're in "define new block" territory at that point...but if so you cannot then have multiple defined templates for, say, custom post types...which I can definitely see a use-case for.

Was this page helpful?
0 / 5 - 0 ratings