WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.32k stars 4.12k forks source link

Discussion: What file-type should FSE themes use? #27144

Closed aristath closed 1 year ago

aristath commented 3 years ago

There have been long discussions in meetings and scattered tickets, but so far no final decision was made regarding the file-type that FSE themes will use for their templates.

There are pros and cons to both .html and .php file-types, so this ticket is an effort to collect opinions and knowledge with the hopes of reaching a decision.

.php

The main benefit of .php is that it's familiar and can allow far greater freedom for theme-developers. Translations work out of the box, theme-relative paths for images work, everything is easy. The downside is that it allows far greater freedom to theme-developers than what we are comfortable with. The goal of an FSE theme is to make things easy, allow non-developers to build something without any actual coding knowledge. Of course there's nothing stopping us from just dumping the output of the editor screen directly in a php file, it will work just the same as an html file. The only difference is that a PHP file can implement logic wrapped in <?php ?> tags.

.html

The main benefit of .html files is simplicity. We simply paste the HTML generated from the editor in the file, and it works (the same thing can be said for php files btw, it works there too). They restrict authors to only use block markup and in the long run can avoid the mess we sometimes see in "classic" themes with overcomplicated logic. The downside is that there is currently no way to make strings translatable in an html file, reference images included in the theme, or implement any kind of logic (see https://github.com/WordPress/gutenberg/issues/20966 and https://github.com/WordPress/gutenberg/issues/21932)


What is your opinion? What would you prefer to see and why?

jonoalderson commented 3 years ago

Wearing an SEO hat, it's my belief that we absolutely need to go with PHP.

We can't predict what controls and flexibility we might need around translation, dynamic behaviour, http headers, access control, structured data, accessibility, security, caching, and/or performance just to name a few areas (both for the theme files in their own context / when requested directly, and in the context of them being parsed/rendered) - all of which we lose control over as soon as we commit to 'static' templates in .html.

Relative image paths are just one small example; we'll run into the same constraints and problems with links, with embedded data, and with things which need to have the context of (and interact with) other things/environments/conditions.

carlomanf commented 3 years ago

Two downsides of PHP:

  1. The work that was done on #26650 and #26383 means that theme files are no longer being processed on-demand. Instead, they are being cached in the database and only refreshed when the content changes.

This means that if you had a block like this, then it would fail to update as you expect it to. It would continue to say "Happy Monday" even into Tuesday and beyond.

<!-- wp:paragraph -->
<p>Happy <?php echo date("l"); ?>!</p>
<!-- /wp:paragraph -->
  1. There would be nothing stopping theme developers from making "block-based" templates like this:
<!-- wp:html -->

<div class="loop">
    <?php if ( have_posts() ) : ?>
        <?php while ( have_posts() ) : the_post(); ?>
            <h1><?php the_title(); ?></h1>
            <?php the_content(); ?>
        <?php endwhile; ?>
    <?php endif; ?>
</div>

<!-- /wp:html -->

But that's obviously not block-based at all, and would be very difficult for users to customize.

carlomanf commented 3 years ago

Keeping with the same example, instead of doing this:

<!-- wp:paragraph -->
<p>Happy <?php echo date("l"); ?>!</p>
<!-- /wp:paragraph -->

theme developers should be doing this:

<!-- wp:example/greeting-block /-->

coupled with this:

function render_greeting_block( $attributes, $content, $block ) {
    return '<p>Happy ' . date("l") . '!</p>';
}

function greeting_block() {
    register_block_type(
        'example/greeting-block',
        array(
            'render_callback' => 'render_greeting_block',
        )
    );
}
add_action( 'init', 'greeting_block' );

But how can you expect developers to do things the right way if you don't have safeguards that prevent them from doing it the wrong way? This is exactly why wordpress has had such a bad reputation for many years, and this represents your one chance to fix it.

Hint: the same pattern I just showed above should be able to fix all of the "downsides" that exist with the HTML implementation:

The downside is that there is currently no way to make strings translatable in an html file, reference images included in the theme, or implement any kind of logic

aristath commented 3 years ago
  1. There would be nothing stopping theme developers from making "block-based" templates like this:
<!-- wp:html -->

<div class="loop">
    <?php if ( have_posts() ) : ?>
        <?php while ( have_posts() ) : the_post(); ?>
            <h1><?php the_title(); ?></h1>
            <?php the_content(); ?>
        <?php endwhile; ?>
    <?php endif; ?>
</div>

<!-- /wp:html -->

But that's obviously not block-based at all, and would be very difficult for users to customize.

The above example is just wrong code that would result in a broken site-editor. It's not block-based at all, it's just a classic theme syntax wrapped in block-syntax. However, the below would be valid block based and easy to customize. Opening the site-editor users would see the right thing and saving would work fine, creating the desired result:

echo ( get_option( 'rss_use_excerpt' ) )
    ? '<!-- wp:post-excerpt /-->'
    : '<!-- wp:post-content /-->';

If people can't understand the concept of an FSE theme or how to write code that doesn't break their users' sites and expectations, then they will write bad code no matter the file-format we use. Allowing advanced theme-developers to implement some amount of logic in their templates doesn't take anything away from the experience of the majority of users who will do the same thing no matter if it's html or php: They will either use the export-theme functionality, OR they will copy-paste the contents of the templates block-markup from the editor to a file. Sure, allowing greater freedom can be abused but WordPress is an open system by nature and if someone is ignorant enough to break things then there are a dozen ways to do that regardless of the file-type.

theme developers should be doing this:

<!-- wp:example/greeting-block /-->

coupled with this:

function render_greeting_block( $attributes, $content, $block ) {
  return '<p>Happy ' . date("l") . '!</p>';
}

function greeting_block() {
  register_block_type(
      'example/greeting-block',
      array(
          'render_callback' => 'render_greeting_block',
      )
  );
}
add_action( 'init', 'greeting_block' );

No, they should really not. Themes are not allowed to register blocks for good reason. Registering blocks in themes would result in a theme lock-in which is not something the w.org repo will ever allow.

carlomanf commented 3 years ago

First of all, I think it's disingenuous to suggest that the risk of badly written code is the same with either file format. Of course you can never eliminate it altogether, but you can discourage it.

Next, I did not advocate registering blocks in themes. I implied the block registration would go in a theme-independent plugin or in core. I thought this would go without saying, but I guess it's easier to create straw-men when you don't agree with someone and forcing them to reply back to avoid looking like a fool. I'm dreading that this is going to turn into one of those ugly heated discussions where people have already made up their minds and just shout at each other.

As for checking an option value and rendering different blocks accordingly, it's not much different to my greeting block example. It can all be done within the PHP callback of a dedicated block type, which would of course be registered in a theme-independent plugin or in core. If this (or any other) pattern of logic is commonly used across different themes then it's an excellent case for a dedicated block type.

Also, the dedicated block type has the added benefit of persisting the check of the option value after the user customises the template. If the logic is housed in the template, then it locks in whatever option was selected at the time of customisation, which is inconvenient at best. This is the "Happy Monday" problem I referred to before.

gziolo commented 3 years ago

Technically speaking, it shouldn't be that much work to allow PHP files as well. @mcsf created this technical prototype in #25316. It's obviously simpler to start with HTML and see how far we can get rather than the other way around. Allowing PHP from start creates a different set of challenges as you can read from the discussion above.

I wanted to share also my exploration for supporting dynamic content #23268 where I tried to use a special block type that uses inner blocks and server-side rendering to solve some of the issues that HTML format creates:

It's a growing pain in the block editor that we can't embed dynamic data like translations or locally formatted dates. This PR is just an experiment exploring how that interaction could look like using the existing concept of InnerBlocks. I don't think it's something that fits for the final implementation because at the moment one block can control only one InnerBlocks component.

I dismissed this idea pretty quickly, but my findings are quite interesting in the context of using HTML (https://github.com/WordPress/gutenberg/pull/23268#issuecomment-655434968):

I had a quite interesting discussion with @mtias about an alternative approach that we could investigate. I wanted to quickly summarize the idea. There is this registerFormatType API method developed by @ellatrix. I was wondering if we could implement tokens based on this concept using <data> HTML tag.

The HTML <data> element links a given piece of content with a machine-readable translation. If the content is time- or date-related, the <time> element must be used.

Example usage would be:

<data value="token/translation">Cherry Tomato</data>

On the server, there would be a logic that parses the output generated and runs filters registered for data tokens:

function block_content_token_translation( $content, $value ) {
    if ( $value !== 'token/translation' ) {
        return $content;
    }
    return __( $content );
}
add_filter( 'block_content_token', 'block_content_token_translation' );

UI part would work very similar to how other RichText formatting controls work as of today, closer to the concept of annotations though.

Retrofitterdk commented 3 years ago

Personally I really, really like the idea of html-only template i FSE. I appreciate the simplicity, which significantly lowers the barrier of entry for developers, that would like to take a swing at custumizing their site – and that is needed.

But it also simplifies things to an extent, where more advanced theme development could be hampered.

Especially how to make part of a page context aware in a html-only template is something that I wrestle with. While get_template_part() – as of WordPres 5.5 - accepts up to 3 parameters, which – since it’s php – can be dynamic, <!-- wp:template-part /--> only accepts slug, which – since it’s html – can’t be dynamic.

I recently did some work for a client on a site, that had between 800 and 1000 pages. In order for the users to navigate between these pages, they had implemented a secondary navigation, where different menus would be displayed according to the top level page ancestor. Displaying the right menus in this case would be greatly simplified using the $args parameter in get_template_part().

How to achieve the same in a html-template in FSE without creating lots of different templates is something I can’t picture. I realize it could probably be done using a custom dynamically rendered block type, but in that case the barrier of entry wouldn’t have been lowered for new developers. It would just have been moved a little further down the road.

So as much as I would love to create templates using html and blocks, retaining the possibility to add a splash of php when really needed would be greatly appreciated.

carlomanf commented 3 years ago

While get_template_part() – as of WordPres 5.5 - accepts up to 3 parameters, which – since it’s php – can be dynamic, <!-- wp:template-part /--> only accepts slug, which – since it’s html – can’t be dynamic.

This, just like nearly every other argument for PHP that's been given in this thread, is something that can be accomplished quite trivially with HTML. It would just require the block type to support an extra attribute. I feel like there are people who are well aware of this, but are not willing to point it out because they have an agenda.

Being able to pass through arguments to the template part is a valuable suggestion that should be discussed, and I would encourage you to open an issue about it. However, asking for PHP as a solution is like asking for a chainsaw to cut butter.

In case anyone was unaware, there were very specific challenges that caused the team to start exploring PHP as a possibility, and it's well-documented what those challenges were. They have never included:

The discussions that are happening at #25316 appear to be handling this exploration quite capably. In contrast, this thread is agenda-driven, lacking nuance, full of misinformation, missing the point, confusing people, and it only undermines rather than helps the team with the explorations they are doing in this area. (The exception so far being @gziolo's comment.)

If the decision is made to support PHP, it will be because there are technical challenges that could not be overcome with HTML, particularly to do with translations and theme assets. Not because a greater number of people "prefer" PHP. If the team were making decisions based on popularity, they'd be scrapping the whole project based on all the 1-star reviews that the plugin has, and they are rightly not doing that.

I'm confident that the team will make the right decision in the end, whether HTML or PHP or something else altogether, but I'm failing to see how this thread that asks for "opinions" is anything other than a distraction for them.

aristath commented 3 years ago

I'm confident that the team will make the right decision in the end, whether HTML or PHP or something else altogether, but I'm failing to see how this thread that asks for "opinions" is anything other than a distraction for them.

I agree, the team will make the right decision. But hearing out what people have to say is never a bad thing. We should not presume to know all the answers and we can't possibly believe that we have considered all the implications of our choices. Someone might say something that just clicks, something that we have never considered before. I don't build websites for a living, I build tools that others use to build their websites - as do most of us here. So it would be nice to actually hear from the people who build websites and consume the products we build here. We need to know what their struggles are and then we can figure out the best way to handle those cases. That might mean using *.html, *.php, or even a custom *.template with a completely different approach :shrug:

Retrofitterdk commented 3 years ago

However, asking for PHP as a solution is like asking for a chainsaw to cut butter.

I’m not asking for PHP as solution. I’m putting forward a real world example of something theme developers today can do on their own using PHP but I don’t how can be done with the current implementation of FSE Theme templates.

This, just like nearly every other argument for PHP that's been given in this thread, is something that can be accomplished quite trivially with HTML. It would just require the block type to support an extra attribute.

Yes, exactly. Any problem is solvable, if I can either:

  1. Persuade someone to change WordPress core.
  2. Write my own code (which at the moment would require creating a custom block).

Choosing whether theme templates should be *.html or *.php is a trade off between simplicity and flexibility. As a theme developer I can simply do more on my own using PHP than I can with HTML, but maybe I shouldn’t. Maybe I’m better off with the simplicity of HTML-templates.

I will be fine, whether templates are written in HTML og PHP, but up front disregarding challenges that theme developers may face with HTML-templates doesn’t seem helpful.

carlomanf commented 3 years ago

Clearly it's not an easy decision to make, or it wouldn't be taking them this long. At this late stage, the best way that all of us can help is by focusing on our own projects and letting the team get on with the job. I've looked through the old discussions and honestly none of us are saying anything new that someone else hadn't already said months ago.

mtias commented 3 years ago

Just wanted to chime in to say it's absolutely helpful to hear from theme developers at this stage and this conversation is already useful.

I'd say it's almost certain we'll go with PHP in the end to support dynamic entities (translations, paths, basic logic and so on), similar to how patterns began as static json files and moved to PHP registration. The main reason we are still using .html files is because it's a great constrain to both communicate the desired simplicity (what PHP would need to resolve to) and to ensure we build the right blocks and abstractions, which has important architectural benefits for the editor.

aristath commented 3 years ago

Technically there's nothing stopping us from using .html files while still allowing PHP in them... So in that case we'd have a reasonable middle-ground: The filetype would indicate that these should be simple. People starting on WordPress and first-time themes would immediately know that this is just HTML. Changing the way these files get loaded and using ob_start(); include $path; $template = ob_get_clean(); instead of $template = file_get_contents( $path ); would still allow PHP to be executed in them and they'd internally be treated as PHP files. Or... We can go with something like index.block-template. That filetype extension - though a bit verbose - would probably be a pretty good alternative. It's not "HTML" so you shouldn't add random code in it. It's a block-template syntax so you just copy-paste code from the editor itself. And if you know what you're doing then fine, go ahead and use PHP in them.

carlomanf commented 3 years ago

I don't know what you mean by "copy-paste code from the editor." The site editor has an automatic export feature that removes the need for any copy-pasting, so I don't think anyone will notice or care what the file extension is. The best way to discourage theme developers from using PHP is not through symbolism, but is to ensure there are fully-functioning block equivalents for everything a theme might want to do.

aristath commented 3 years ago

I don't know what you mean by "copy-paste code from the editor." The site editor has an automatic export feature that removes the need for any copy-pasting

You're right, I was thinking of the current implementation with manually created templates (from Appearance > Templates) and what we used to do until recently where we were switching to the code editor to grab the contents and then pasting those in a file :+1:

ridesirat commented 3 years ago

Hi guys Probably this comes a bit late and out of purpose but It's hard to keep up with all the discussions. I know I will be completely massacreted with these lines but I admire so much your work, I feel the urge to contribute in some way, even if none of this makes sense. If you don't want to bother reading all the stuff: PHP!

As a designer / frontend dev / amateur developer / WP user, I wanted to share some thoughts on using WP the different ways. Some years ago I changed to WP due to its Power & Simplicity on constructing Websites with a Content Management System. Even today I feel that's the strength of Wordpress. Now I feel that simplicity is changing. It feels we are forcing stuff to behave nonNaturally. The web still is HTML + CSS + JS + Server. Why should we neglect PHP? Just because new systems have emerged?

If we want dynamic pages why not use it? What's wrong with it? It had its ups and downs, like any other language, but likewise, it's evolving, it's getting better, faster, safer. The same way, Browsers, Servers, Caching systems are getting better. Can't WP make use of that. With PHP! We can't abandon it, we have to embrace it! WP should seek for the simplest solutions, the less is more approach all the time.Can't we take a step back, or even two if that will avoid three, and think about what are we building?

A block is just a template. A Page is a template, everything is a template. And PHP is a templating dynamic language! There will always be something needing dynamic control.

We have a great CMS and we have two kinds of users: "Consumers" & Developers. What do they want? As a developer I don't care if I have to build blocks/patterns in HTML, JS or PHP. I just care if it's the most simple & efficient way. If the best way to build blocks and templates is having dynamic HTML = PHP, why not? 

As a user I don't care how they were built. I just care if they work in the most user friendly way. I won't be touching any HTML or PHP!

And we cannot forget there are two kinds of "consumers": the ones who want to play around with Blocks & Patterns and the ones who don't! And these are a lot - they just want to create content and keep it in a safe & reusable place. And to know that the_content will show in any template. These can be big companies, institutions, etc. They just don't won't their sites to crash.

cr0ybot commented 3 years ago

I feel like I'm really late to this conversation, but the issue is still open, so...

As a custom theme developer, my vote would be for .php files as the basis for these FSE theme templates. There's no reason why a php file could not just be made up out of only HTML if the documentation would want to keep things simple "for beginners". But it seems (according to some suggestions in this thread, anyways) that if strictly HTML templates were used, some extra functionality may be needed to extend the block comment syntax, and I'd personally prefer that the custom syntax stuff be limited as much as possible in favor of standard HTML, PHP, JS, etc. I'm also not thrilled at the suggestion that there could be PHP allowed in .html files... then why not call them what they are, .php files!

I'm wondering what the real benefit to using HTML files would be other than to potentially simplify the implementation(?). It seems like this choice would be actively hostile to the expectations of current theme developers.

carlomanf commented 3 years ago

I'm wondering what the real benefit to using HTML files would be other than to potentially simplify the implementation(?). It seems like this choice would be actively hostile to the expectations of current theme developers.

I generally agree with you that it would be hostile to current theme developers, although I would probably use a different word. I would perhaps say that it's harsh on them, rather than hostile. I don't think HTML offers any benefit to current theme developers, and that explains why no theme developer has come out in support of it. I wouldn't expect them to.

However, HTML does offer benefit to plugin developers and users. By excluding themes from doing their own server-side logic, it would more greatly enforce the protocol that themes are strictly for design and that server-side logic should be left to plugins. This would protect users from theme lock-in and also give more certainty to plugin developers regarding compatibility. The block system was meant to create a standardised mechanism for extending core, which gives plugins the aforementioned certainty regarding what other extensions are active, but PHP gives themes a chance to subvert this.

I think that if you support PHP, you either believe that themes are for more than just design, or you believe that PHP is a design tool. I don't believe either, and that's why I support HTML.

Also, I feel the need to object to the assumption that a lot of (pro-PHP) people have made that simplicity is the main argument for HTML. I am someone who supports HTML, and for me it has never been about simplicity. I'm not sure I'd even say that HTML offers greater simplicity, depending on how you measure it. For me it's about standardisation, certainty, and user experience.

scruffian commented 3 years ago

I think that if you support PHP, you either believe that themes are for more than just design

I think this is a really interesting point. We could say, if you need PHP, your code should be in a plugin.

cr0ybot commented 3 years ago

I think that if you support PHP, you either believe that themes are for more than just design, or you believe that PHP is a design tool. I don't believe either, and that's why I support HTML.

This is a nice sentiment (I truly mean that!) but it isn't how it currently works in practice. Doesn't mean it has to be that way in the FSE environment, though, if it makes sense.

I might be coming around to .html files for template purposes in light of this conversation. My largest concern is still that if vanilla HTML isn't enough, some custom syntax will grow out of the constraint that we'll all have to learn—which, frankly, we've already got happening with the Gutenberg HTML comments, though we are not yet expected to write those comments ourselves yet. I believe that one of WordPress' core strengths and one of the reasons it powers 40% of the internet is that the templating isn't done with another language on top of what it's built with like many of the other CMSs out there.

However, I'm still not thrilled about having to essentially hard-code Gutenberg blocks into an HTML file. I probably can't speak for everyone, but the main reason I learned PHP back in the day was because I wanted to stop repeating and having to maintain separate headers/footers/components. If the templates were PHP, I'd expect that I could do something like the_block('namespace/blockname', [attributes...]) and regardless of the particular block's output (which may change over time) the block shows up on the page.

But I think maybe the point is that there probably shouldn't be a whole bunch of blocks hard-coded into theme templates, right? They should function mostly as structure to place blocks within. But I suspect I haven't fully grokked the FSE approach yet, and I apologize if some of my comments here are uninformed or naïve.

scruffian commented 3 years ago

I wouldn't ever want to write block markup by hand - If I want to create a template for a block theme then I do so in the block editor and copy/paste the code.

cr0ybot commented 3 years ago

I wouldn't ever want to write block markup by hand - If I want to create a template for a block theme then I do so in the block editor and copy/paste the code.

Sure, but you understand that block markup can change, and even though there is a mechanism to update deprecated block markup when a block is updated, I wonder how well that system would hold up when the block doesn't have the opportunity to update the markup to be saved like a normal post would?

aristath commented 3 years ago

Sure, but you understand that block markup can change, and even though there is a mechanism to update deprecated block markup when a block is updated, I wonder how well that system would hold up when the block doesn't have the opportunity to update the markup to be saved like a normal post would?

Tested, works fine.

cr0ybot commented 3 years ago

Tested, works fine.

Great!

I think my point still stands that block markup is generated, and any time you are hard-coding stuff that expects to have been generated and read back in with exacting expectations of the format, you are playing with fire. I create custom JS Gutenberg blocks fairly consistently these days, and the smallest deviation from the expected input results in a broken block in the editor. Even if it can be resolved by the "attempt to recover" button, it's a poor user experience for someone who isn't a developer.

pagelab commented 3 years ago

As a note: considering that the aim of FSE is to allow non-technical users to have more control over their websites, I think it's a pity that an important discussion like this happens in a place that is quite foreign to them.

We're mostly developers, designers and implementers. People that work with WordPress professionally.

Honestly, I think we completely miss relevant perspectives by segregating them from the decision. This kind of user may even prefer a PHP file – and for good reasons! But we will never know if we don't ask them directly.

cr0ybot commented 3 years ago

Honestly, I think we completely miss relevant perspectives by segregating them from the decision.

I think this is relevant to something I brought up in #20966. I get that we are developers and we must develop a system that uses a specific type of file for information about a theme, but why are we talking about these as manually coded files? Perhaps this is an MVP approach to getting the feature out, but if the ultimate goal is to lower the barrier to entry for theme creation, why expect the user to code at all?

If the expectation is that, in order to create a FSE theme, you must create a JSON file (with it's strict syntax, mind you) and also these HTML files with special comments that are not actually comments but additional processor commands, how is that lowering the barrier to entry? Maybe it takes it from a 10 to a 7? Is that enough?

If we were to talk to a non-coder about what they would expect from a WordPress full site editing experience, I bet they would point to something like Elementor or the like. Maybe it is unproductive for me to assume, but with that kind of page/theme builder, a non-coder can create a theme right there in the back-end without adding a single line of HTML, JS, or CSS, and can even package it up and export it for use on other sites. Is that what is being built here?

If this is about not having to manually code things at all unless you really want to, then frankly I don't care if PHP is involved. But in that case I would expect that these files would serve as a one-time reference on import to the database as a starting point that is then dynamically updated via some GUI similar to Gutenberg. If they are files that live in a special FSE theme folder on the server and are referenced at runtime, HTML seems too limiting (just have a look at #20966, all of my fears above about a unique custom templating syntax are made a reality in there).

EDIT: Now that some time has passed and I've played with this a little, I think that block template files using HTML that is exactly the same as how WordPress stores block markup in the database makes the most sense compared to other options. If you want to use PHP, then you aren't building a FSE theme. These files serve as a starting point but ultimately the templates themselves end up in the database and can be transferred across themes and sites. This was my hope and it looks like it panned out that way.

carlomanf commented 3 years ago

Honestly, I think we completely miss relevant perspectives by segregating them from the decision. This kind of user may even prefer a PHP file – and for good reasons! But we will never know if we don't ask them directly.

Why would it matter to non-technical users what file-type is used? Note that user customisation is designed to be done fully through the database, with no real need for them to touch the files. That's one of the biggest advantages of this system over the old one. User perspectives are important for other questions, but I don't think this question is relevant to them.

why are we talking about these as manually coded files?

I think that's a good question. If templates are meant to be exported from the site editor rather than hand-coded, then unless PHP statements are going to be automatically inserted into the file on export (unlikely), you are sending mixed messages to theme developers by allowing them to use PHP.

Do you export-and-go? Or, will you need a code editor and a local PHP server like a plugin developer?

Possibly the biggest question is this. If you use the site editor UI to make and export a theme, and then you manually modify the files to add in PHP statements, then how do you update the templates? If you re-import the files to the site editor, all the PHP will be wiped.

Would you need to be going back and forth between site editor and code editor, re-importing and re-exporting over and over until you're happy with the result? Not to mention re-adding the PHP that the site editor wipes. I'm not a theme developer, but that seems like a nuisance.

If the expectation is that, in order to create a FSE theme, you must create a JSON file (with it's strict syntax, mind you) and also these HTML files with special comments that are not actually comments but additional processor commands, how is that lowering the barrier to entry?

I don't think the intention is necessarily to lower the barrier to entry for theme developers, not commercial-level ones at least. It's to increase customisability for users. This could be described as users "creating" their own themes, but it would be done fully inside the UI and wouldn't involve any coding or file handling.

pagelab commented 3 years ago

Why would it matter to non-technical users what file-type is used?

I was referring to the whole new paradigm that the FSE template system (and its file format) represents, whether it uses PHP or HTML formats.

This system changes the game for everyone that creates and uses themes, but the end-user opinion about this system are surely underrepresented. Maybe this deserves its own GH issue.

CyberDomovoy commented 3 years ago

Hi there.

Since i haven't seen it mentioned, i thought i'd brought it up: Why limit the choice to php or html? Why not simply create an xml format for wordpress templates?

XML standard

Benefits of xml:

You're already kind of doing it, using html comments instead of custom xml elements.

Example:

<!-- wp:group {"layout":{"inherit":true},"tagName":"main"} -->
<main class="wp-block-group">
    <!-- more blocks -->
</main>
<!-- /wp:group -->

Would become (with added params/elements to give an idea of the possibilities):

<?xml version='1.0' ?>
<!DOCTYPE template SYSTEM "https://wordpress.uri/path/to/custom/schemas/template.dtd" >
<template xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude">
    <group tag="main" some-other-simple-setting="value">
        <layout inherit="true" />
        <some-other-complex-setting>
            <any-level-of-complexity-can-be-achieved />
        </some-other-complex-setting>
        <!-- More settings, either common to all blocks, or specific to group -->
        <content>
            <child-block />
            <html:p>The html block becomes a simple inclusion of the html xml namespace</html:p>
        </content>
    </group>
    <!-- including a template part doesn't require a custom element, it is done with XInclude -->
    <xi:include href="my-template-part.xml" />
</template>

Adding some programmatic capabilities without allowing the whole php language is as easy as a new element. Again, take a look at what xsl does.

<if test="is_admin()">
    <group>
        <!-- Blocks included only if the condition is true (in that case, the user is an admin) -->
    </group>
</if>

Which leads me to another observation: Why separate templates and template-parts? They're both simply templates, included in one another. It just happens so that some of them need to be specifically named so that they are used as entry points when generating the output. Going further, this could be applied to reusable blocks, block templates...

As it happens, a long time ago, i was coding a framework that did just that (about 10 years ago, never got to finish it):

Result: No more messing around in code with several formats (html, rss, json...). Just code for your own internal format, then write xsl to transform to/from whatever other format you want to support.

I know, it may seem like quite a different approach to what you're doing right now, but really, it is not, you're almost there with the "blocks are specifically formatted html comments" style.

In other words, i guess what i'm trying to say is: Why reinvent the wheel when there are already some well defined standards that does what you need?

mcsf commented 3 years ago

Hi there.

Since i haven't seen it mentioned, i thought i'd brought it up: Why limit the choice to php or html? Why not simply create an xml format for wordpress templates?

XML standard

Thanks for the thoughtful proposal. For now I'll just comment on the XML aspect, but there are other pertinent points in your comment. :)

It's not wrong that what we are doing with this HTML-based block format is close to what XML might offer. But, even if the two formats are morphologically identical, there is a fundamental difference: Gutenberg's approach affirms HTML — in other words, the printed page — as the canonical serialisation format. You could think of the format as "annotated HTML" in which HTML comments provide the support for said annotations: in the absence of a WordPress runtime, one is left with a plain functional HTML document.

Of course, there are trade-offs with this decision as with any, but the format has proved its worth over the past four years. It has adapted to complex nesting needs and contexts, accommodates both inline and sourced attributes, and allows interesting things like dynamic blocks that still contain static fallback content (imagine a newsletter post where some dynamic block defers to a static alternative that is better suited to the e-mail medium).

But these considerations distract from the priorities behind the initial choice: preserving backwards compatibility in WordPress, providing a flexible base for the future (as blocks evolve, user needs evolve, and multiple environments coexist — web vs. mobile, online vs. offline, static vs. dynamic, etc.), and retaining HTML as the lingua franca for all these applications and layers of WordPress. In this sense, I would argue that it's good that this format is less featureful than XML.

Before Gutenberg, WordPress was centred around the HTML post. One of Gutenberg's invisible feats is this: it managed to revolutionise WordPress without removing the HTML post as the "file" primitive, but still introducing a new fundamental unit of content: the block.

CyberDomovoy commented 3 years ago

You could think of the format as "annotated HTML" in which HTML comments provide the support for said annotations: in the absence of a WordPress runtime, one is left with a plain functional HTML document.

Sorry but... imho, the resulting templates are far from functional HTML:

On the other hand, most HTML parsers are also capable of displaying XML, provided you give them a stylesheet. Some of them are even able to handle XSL (those are linked to the document by xml stylesheet module linked previously).

It has adapted to complex nesting needs and contexts, accommodates both inline and sourced attributes, and allows interesting things like dynamic blocks that still contain static fallback content (imagine a newsletter post where some dynamic block defers to a static alternative that is better suited to the e-mail medium).

I don't see how XML would go against that, actually, if anything, it provides more flexibility. Fallback content? Just define a <fallback> element. That's the beauty of XML, you basically define your own markup. After all, HTML is valid XML.

In this sense, I would argue that it's good that this format is less featureful than XML.

Again, the features available with your own XML format are those you define. It all starts with the XML schema you provide.

If you really want to keep HTML as the main format, just reverse the namespaces, and all i exposed in my previous comment is still valid. As i said, HTML is valid XML. For it to be parsed as such, you just need to make sure it is processed as application/xhtml+xml.

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wp="https://wordpress.uri/for/namespace/wp">
    <head>
        <title>Some template</title>
    </head>
    <body>
        <p>This is a valid html document, Wordpress could use it as a template by just getting the content of the body</p>
        <wp:some-block>This is still valid html, it just won't be processed by any parser that doesn't know how to handle the wordpress namespace</wp:some-block>
    </body>
</html>

The important point here is: HTML is XML when processed as application/xhtml+xml. So you can keep the historical html format, while extending it with what is needed to implement gutenberg blocks.

mcsf commented 3 years ago

Sorry but... imho, the resulting templates are far from functional HTML:

  • no head, title... elements
  • with the majority of it being comments what is left to display by an HTML parser?

I should clarify: a) I was talking more from the perspective of the post itself rather than the templates, and b) by functional I meant that they are functional fragments of HTML (and could be understood by humans and machines alike), rather than documents.

Templates on their own, while they could be mostly made up of actual HTML, I think of them more as very (intentionally) simple macros. But the point remains that a template is an easy-to-understand fragment of HTML where the proper hardcoded elements (e.g. layout, landmarks) will be just HTML and the dynamic elements will be HTML comments — almost like placeholders.

I don't see how XML would go against that, actually, if anything, it provides more flexibility. Fallback content? Just define a <fallback> element. That's the beauty of XML, you basically define your own markup. After all, HTML is valid XML.

Again, the features available with your own XML format are those you define. It all starts with the XML schema you provide.

XML is the most powerful meta-format we could have. It's like Lisp. And, as much as I personally like Lisp, defining our own markup would not come for free. In a project as large as Gutenberg, starting from established knowledge and working our way up from there has advantages over starting from a clean slate. The clean slate denies a collective memory, a wealth of experiences. So we chose the most native dialect to WordPress — HTML — and added the bare minimum: the block boundaries.


At this point, it's hard to justify any approach that breaks away from our current meta-HTML. It's battle-tested, there are systems built all around it, and an ecosystem embracing this new convention. That said, I find all your feedback very enlightening:

[…] most HTML parsers are also capable of displaying XML, provided you give them a stylesheet. Some of them are even able to handle XSL […]

If you really want to keep HTML as the main format, just reverse the namespaces […] HTML is valid XML. For it to be parsed as such, you just need to make sure it is processed as application/xhtml+xml.

… and I think it should inform how we look at templates. That could mean learning from XSL best practices, or borrowing some XML tooling, or even actually using a very specific form of "disguised" XML to provide a better template system — who knows. But it would be a disservice to invest in something that aims to uproot Gutenberg's core HTML-based format — so whatever solution we come up with for templates will need to play nicely with that.

CyberDomovoy commented 3 years ago

I should clarify: a) I was talking more from the perspective of the post itself rather than the templates, and b) by functional I meant that they are functional fragments of HTML (and could be understood by humans and machines alike), rather than documents.

Thanks for clarifying the fragment vs document point, it is actually a very important distinction.

But the point remains that a template is an easy-to-understand fragment of HTML where the proper hardcoded elements (e.g. layout, landmarks) will be just HTML and the dynamic elements will be HTML comments — almost like placeholders.

Imho, this is achieved with "wordpress blocks as a namespace". The layout is html, the current "blocks as html comments" become "blocks as elements of the wordpress namespace".

In a project as large as Gutenberg, starting from established knowledge and working our way up from there has advantages over starting from a clean slate. The clean slate denies a collective memory, a wealth of experiences. So we chose the most native dialect to WordPress — HTML — and added the bare minimum: the block boundaries.

What i propose doesn't imply starting from a clean slate, it's merely using namespaced elements in the html, instead of comments that mimic elements.

As i see it, you're actually adding some work by using comments: you need to parse them to a structure that your code can manipulate. Using xml elements removes this need, the xml parser gives you that structure: the DOM. From the coder point, it makes things easier: the DOM is a well defined, standardized structure, easy to query and manipulate, you don't need to make your own parser for it, you avoid introducing possible failure points (i.e. malformed content you didn't anticipate). From the user point, well i don't see the difference between learning the syntax of what goes in the comments, and learning the syntax of new elements. If anything, it feels more natural: elements, attributes, child elements... feels like html doesn't it?

I truly can't see how using comments that reproduce the structure of an element could actually be better than an element itself... But maybe i'm missing something.

At this point, it's hard to justify any approach that breaks away from our current meta-HTML. It's battle-tested, there are systems built all around it, and an ecosystem embracing this new convention.

I can see how this can feel like a "break" from what is currently done. But from my perspective, and what i've seen from the code, it really isn't. All that you need is to use the DOM from the XML parser, instead of using the results from you own, home-brewed, comments parser (which actually gives you very much the same thing as the DOM: element name, attributes, children). But i'm not an expert in wordpress code, i just read what i needed to, so i may be wrong about that.

In any case, far from me the idea to imply that you're doing it wrong. I certainly won't be the one coding the stuff, so whatever works for you is fine. I just wanted to expose another possibility.

strarsis commented 1 year ago

At least some filter should be offered that can be used to pre-process the templates. Many theme developers use Blade-PHP, and it would be nice if it can also be used as a block template language.

youknowriad commented 1 year ago

This discussion served its purpose. Thanks all.