-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal for Block Templates #3588
Comments
It took me a while to find this issue, but this is exactly what I have been looking for. Great, @mtias, that this already exists and work is actually already being done. I just want to add a couple of thoughts regarding your proposal: With a system like this, and nested blocks via BlockList or some other component that should have the same option to add a template like in your proposal, quite a few issues could be solved. At my company we use ACF Pro quite extensively. One of the great features is to be able to define static fields, but also (with the pro version) flexible content and repeater fields. The same thing could be achieved by defining a template that is locked and including a BlockList component to which you can add dynamic blocks. You would need to specify what childblocks are allowed in this BlockList, but I think someone is already on that. One other thing that comes to my mind is that besides Gutenberg showing a locked template, there should probably also be some server side validation. I do not know if this is a priority atm though. |
I'm going to close this as the initial version of this is shipped. I'll leave #1684 open to track "nested locking" |
Reopening so we can still access the remaining points about saved templates. |
I'm wondering if the code that has been merged for Block Template support exposes any API that would allow the template to be switched based on taxonomy selection? Say, for example, you have a category that you use for all image posts. Upon selecting that category, could you switch to a Block Template with an image block and nothing else? I guess this also leads to a broader question. If a post is begun without an assigned Block Template and a change is made (e.g. selecting a specific post format) that assigns a Block Template, what happens to the content? The block paradigm changes the current behaviour, where switching post formats has no impact on the editor. |
I think that such a blockified PHP template should really be returning the data structure. For example: <?php
return do_blocks( array(
// Theme header: "blocks/header/index.php"
do_block( 'theme/header' );
// A core text block
do_block( 'core/text', array( 'placeholder' => 'Fill some text here...' ) );
do_block( 'core/post-title', array( 'id' => get_post_id() ) );
// A post block: renders the_content
do_block( 'core/post', array( 'id' => get_post_id() ) );
// Theme footer: "my-theme/blocks/footer/index.php"
do_block( 'theme/footer' );
) ); This would then allow for the template's block configuration to be read out as data and it wouldn't have to be executed. This would make it easier for a PHP-coded template to be copied into the database for modification, and it would also allow a theme to introspect its templates to find where a given block is used. This would solve the problem currently faced in core with regard to widget sidebars, where we don't know in the theme where a given sidebar is used. If all of the templates were data, then it would be possible to parse them to find out which blocks are used in which templates, and then be able to come up with a URL for a request that would result in a template being chosen that would contain the desired block to view. |
Forgive me if this has already been asked/answered, and I'm not even sure this is the right place to ask it, but I haven't been able to find any specific info relating to how the following situation would be handled: I create a template that I use on every instance of a certain kind of post, whether it be a custom post type or a post about a certain thing or whatever - it doesn't matter what post it is, just that it is using the template. One day, I decide to change the layout of the blocks for those kinds of posts. I change the template... and what happens to the existing posts? Do they automatically change to match the new template? If I have a website with, for example, hundreds of products, and I decide one day that I want to move the gallery block from the left side to the right side of the page, do I have to go in and change every single product? I guess what I'm asking for is global layouts, without making the specific content (product title, description, the image used, etc.) global. This is kind of similar to the "Selective Sync" feature that Divi Builder modules have, which allows you to set which settings of a module are global and which are specific to each individual instance of the module. https://www.elegantthemes.com/documentation/divi/divi-library/ In the context of Gutenberg, where blocks are basically the equivalent of modules, the closest existing equivalent to the "Selective Sync" feature is making a plugin with a custom block made from one of the existing ones, but with certain settings turned into some kind of global field could work, but that's rather cumbersome and far from user-friendly. But in this case, what I'm asking for isn't limited to the scope of a single block, but rather the entire post... or if you want to allow for even more freedom (like a section that only exists on a single product), just a section of the post. If a "Selective Sync" kind of feature was added to global blocks, then the making-changes-to-templates issue could be resolved by having every block of a post nested in one parent block that uses global sync for the order of its children blocks, but not the content of the blocks themselves. But I'm not really sure as to whether or not this is the right way to handle this. What do you think... is this something that should be implemented in templates? Global blocks? Or something else entirely? Pre-Gutenberg, you would separate the content/data from the layout by using custom fields to store stuff like the price/description/title/whatever and page template .php files to store the layout of the page and how the content is presented. of course you could still do this in Gutenberg by using blocks that are basically just custom field holders that don't actually render on the page, like what GCF does: However, since Gutenberg is intended to make editing posts more visual, it would be really unfortunate if people using custom post types with a need for standardized layouts (WooCommerce products, for example) to settle for just throwing custom-field-input blocks onto the Gutenberg editor with no relation to the actual visual layout... or else make the editing experience visual but have layouts be stuck to individual posts with no easy way to apply changes to all of them at once. |
Is it possible to have block templates for Page Templates? I have some pages that have the need to have "fixed" sections of content, and some flexible "freeform" sections of content. I would like for a user to select a "Page Template" that hydrates the block UI with the appropriate mix of locked and free-form blocks. From what I can tell, that's not yet possible, but perhaps I'm missing something? |
I agree wholeheartedly with @jasonbahl. This is a must-have in my opinion. There is a ticket to this effect here: #3835 Initially, I was thinking it would make sense to add a filter to the Currently, users are able to switch page templates within the Gutenberg editor, which triggers an We could temporarily store a copy of the blocks in local storage for each page template; that way when the user switches the template back and forth without leaving the page it would allow us to change all the content and blocks without losing their data. I think it is safe to assume that after saving the post and leaving the page the old content can be forgotten, right? I think it makes sense to store the page template with revisions so that restoring a page will not break the block structure. We don't want a restored revision to return content from a previous page template when the current page template doesn't match and doesn't support that block structure. At the moment, I see a way to subscribe to the Allowing this type of access to the data stores would make it possible to implement a custom solution like @greatislander mentioned where the block template could be changed based on the taxonomy term selected (granted you still have the issue of deciding what block template to use when a user selects multiple taxonomy terms). Or it could allow you to change the block template based on the post format, etc. |
According to the data docs, there is an example with a comment: const { subscribe } = wp.data;
const unsubscribe = subscribe( () => {
// You could use this opportunity to test whether the derived result of a
// selector has subsequently changed as the result of a state update.
} ); I've taken this to mean that you have to subscribe to changes to the entire state tree for everything and then detect if a part of it has changed. That doesn't seem ideal, but it's what I've done in a recent PR to look at changes to a given post field in the |
Thanks @westonruter! I'll take a closer look at this. |
@wpscholar @westonruter I've got template switching for a project I'm working on. I'm using WPGraphQL, so what I have doesn't make sense for a core Gutenberg merge (unless we do a WPGraphQL core merge as well 😜). . .but might be helpful should Gutenberg core want to provide a way to swap templates as well. The way I have it working:
Here's a Gist of the client side code: https://gist.github.com/jasonbahl/2af7959e5d10c7eb6781fb86c097786e If it's helpful at all, here's the Logic used to hook into the WPGraphQL Schema to provide the necessary field/args for GraphQL to respond with the template(https://gist.github.com/jasonbahl/d2df4874a9e3c19fd05767c21fa800a1). . .I'll likely make some adjustments here. Also, one thing I want to add is having the current state of the template saved to post_meta before making the switch. You can see the GraphQL resolver is already setup to return the persisted template, if one exists. Not sure if meta is ideal for this, but will work for my immediate needs. |
^ Follow up to my last post. The
What you end up with after using that in Not quite sure what I'm missing and how to replace blocks with attributes set. 🤔 |
Is there anyway we could make a user select the page template when a page is first created? |
Closing this as the extent in which support mattered for phase 1 is in place. Phase 2 will work further on the saving mechanism and the UI for selecting templates. |
Any word if this is going to be addressed in Phase 2? I think a lot of developers of custom websites would really appreciate the blocks template feature. This way pages with a (semi)static layout could be built on top of gutenberg as well, instead of relying on plugins that use meta fields. In my opinion an ideal implementation you should be able to:
This way we can create complex template structures (with placeholder data) with fixed headers, footers, call-to-action areas, or any other block that is required on a page by design, while we can still add extra blocks to expand these pages. |
I think it would make sense to have both page templates and block templates as dropdowns in the editor. This way page templates can be created by the theme and may control sidebar layouts, etc. while the block templates can be registered by plugins and utilized within any given page template/layout. This would allow us more flexibility with block templates until Gutenberg takes over theming completely. |
@jeremyfelt has a proof of concept plugin for block templates: https://github.com/happyprime/select-editor-template |
And in the case you would like to lock block templates to a page template? I know this is somewhat outside the normal way Gutenberg should be utilized i.e. with blocks as plugins, but I do find myself in quite some situations (read: custom themes for clients) where a page template needs to dictate the blocks being placed. |
@Levdbas I think we should have a way to register block templates to different contexts. For example, a theme or plugin could register a block template to be used in a post type, page template, etc. However, if a page template explicitly names a registered block template in the page template's file header, then that would essentially disable the block template selector as the template has basically defined a specific block template as the only one that should be used. Likewise, if a post type explicitly defines a block template in the post type arguments, then that is the only block template that is allowed. However, if a template or post type doesn't explicitly name one, any of the block templates registered would be made available in the appropriate contexts. I'm thinking we'd have a generic function like register_block_template() that would allow for registration of a block template to specific contexts. |
@Levdbas: Yes. The extent of the work is yet to be determined, but templates are a focus for this phase. There's a Phase 2 GH project that can be handy to track, as well as the weekly editor chat. |
Seems we didn't have an overview issue for block templates even though we have discussed them repeatedly.
Definition: In its most general sense, a block template is a definition that includes a list of block items. Those blocks can have predefined attributes, placeholder content, be static or dynamic.
Uses
Not to mistake with global blocks and nested blocks, even though they can be related — the list of blocks a template provides could potentially include a global block and it can have nested blocks in the specification. The use case of "reusing a group of blocks" is not necessarily a template task, but a global blocks one paired with nesting.
What block templates allow is to specify a default state for an editor session and a mechanism for rendering a page-route's corresponding PHP theme file. This can be done in multiple ways:
defaultBlock
API should support option of supplying a list of blocks, not just a single block.)template.php
file or pulled from a custom post type (wp_templates
) that is site specific.Example with pseudo code below of a
template.php
:Details
Templates can:
save
callback on the server.Implementation Steps
(From 3 onwards we are in customization territory.)
Tasks
wp_templates
hidden post type.The text was updated successfully, but these errors were encountered: