Skip to content
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

Discuss: Contextual block behavior #21728

Open
ockham opened this issue Apr 20, 2020 · 10 comments
Open

Discuss: Contextual block behavior #21728

ockham opened this issue Apr 20, 2020 · 10 comments
Labels
[Feature] Blocks Overall functionality of blocks [Type] Discussion For issues that are high-level and not yet ready to implement.

Comments

@ockham
Copy link
Contributor

ockham commented Apr 20, 2020

Is your feature request related to a problem? Please describe.
I'm currently thinking about site editing related problems (theme assets, i18n). Part of the solution to those problems might be available through block context (I've written one proposal here), but I think I might've identified another requirement:

Describe the solution you'd like
I think that blocks (down to 'primitive' ones, such as paragraph or image) need to be aware if they're being used in a regular post (or page, or other 'content' CPT) context, or within a template. If they're used in a template, some of their behavior needs to change to listen to information provided through e.g. block context. As an example:

What's the function of any visible text/string that's entered through a block (e.g. Paragraph) as part of a template? Unlike strings that a user enters in a post context, they aren't part of the content -- instead, they're of a presentational or navigational nature. (Think a 'Home' link, a 'Social links' menu heading, etc). By their very nature, templates aren't the place to hold content, but presentation and navigation. As a consequence, I think it makes sense to assume that all strings used in template should be subject to i18n

A similar point can be made for images: Template images are clearly presentational; when shipping a template-based theme, it needs to include those images as assets (that's basically #20966). Thus, image URLs cannot be absolute (referring to the current site), but need to be relative to the theme root.

Note that both cases might be less of an issue when editing a theme template locally in the site editor (i.e., when persisted to wp_template/wp_template_part CPTs), but they become quite relevant once 'exported' as a theme. (Not sure we currently have functionality to do that yet, but I'm pretty sure we eventually want something like that.)

Describe alternatives you've considered
One conceivable variation of the above would be to 'duplicate' existing blocks for usage in templates: the 'original' 'primitive' blocks (for use in content) would remain unchanged, and their would be a separate set of modified blocks for use in template editing. This sounds appealing from a separation-of-concerns POV; maybe we could even provide some sort of wrapper to existing primitive blocks that connects their attributes to some kind of block context, whenever they're used as part of a template. As pointed out in #20966 (comment), I'm however not 100% sure that simple tapping into block attributes could cover all cases.

In #20966 and #21204, others have suggested using JavaScript (or a server-side templating system for PHP, e.g. Twig) to implement 'dynamic' features (such as translated strings, or image URLs referring to a local asset). While this might make sense for manually adding functionality to a template, I don't think it's ultimately viable, since templates that contain JavaScript would become near-impossible to parse and render in the editor, and we'd be back to a basically manual editing of themes, which wouldn't be an improvement over the pre-Gutenberg themes situation.


Curious to hear comments. Does this sound like a good approach? Did I miss anything?

/cc @johnstonphilip @wpscholar @aduth @youknowriad @mtias @noahtallen @vindl @Addison-Stavlo

@ockham ockham added the [Type] Tracking Issue Tactical breakdown of efforts across the codebase and/or tied to Overview issues. label Apr 20, 2020
@johnstonphilip
Copy link
Contributor

@ockham I definitely think this is the right direction, though I'm not sure if I am fully wrapping my brain around the proposed solution yet.

Would you be able to provide some pseudo code of how a block's code might look in this proposal?

For example, how might this code change as a result of this?
<!-- wp:cover {"url":"https://mystagingsite.local/wp-content/themes/custom-theme-for-client/image.png","id":1575} -->

@noahtallen
Copy link
Member

i18n

all strings used in template should be subject to i18n

I definitely agree with your reasoning for this! A template is defining the structure of a site or pages on the site; it's the UI that exists around the content. Though I'm not sure I agree with the idea of having a second block implementation just for the site editor. I feel like part of the point of FSE in Gutenberg is that it's "just plain blocks," and part of the power we expose is that all blocks "just work." It seems as if we would have to wrap a ton of blocks for this to work out, and if they appear different to the user in the inserter, that would be confusing. There are a ton of different text and image-related blocks! (Let me know if I am misunderstanding your proposal!)

Would it be better to have an "option" in some of these blocks to do i18n? For example, the paragraph block setting might have a checkbox for "Translate?", and then if true, the block would pass its content through __ before saving it (or before rendering it, or something like that).

I think a critical difference here is that before, a theme could literally hardcode, e.g. __( 'download' ), but now, that is editable. So the user can change the text of anything to whatever they want. So in the previous case, the translations might be done here, but now... there is no guarantee what words have been used, so it's no longer possible to guarantee a complete translation for a theme. This seems like a much bigger issue than blocks can solve by themselves.

Which is why I wonder if we're getting ahead of ourselves with respect to i18n. Since we are switching from storing site layout in theme PHP files (which have easy access to __) to storing site layout in post_content of a CPT, I wonder if the i18n case for templates and template parts would (or should) be solved by WordPress multi-language support? I'm pretty sure that was on the roadmap at some point. It seems like solving that problem for normal post_content (and blocks) would solve it for templates and template parts at the same time.

It's an interesting problem, to be sure. If we were to wait for multilingual support in general, that would definitely put block-based themes at a big disadvantage in the meantime. I'm sure many folks would avoid block-based themes if they could not be translated.

dynamic image

when it comes to linking images, I guess I'm not sure why the new block context API couldn't be used to solve the problem of relative URLs. For example, what happens if you change the domain of your current site? Do all the images you inserted stop working because they are hardcoded to the olg domain? (To be honest, though, I'm not sure how that works in WP :))

I definitely like the idea of an omnipresent site context, which specifies the base domain, and then we can rely on that to concatenate the relative path to the file. I guess I don't understand why we would need to create a second block to wrap around that? Couldn't a site context exist in the post editor as well?

exporting

Not sure we currently have functionality to [export as a theme] yet

Some discussion about theme export here. TLDR is that it was working in a PR, but the PR was too large so it was removed for the time being: #19260

@ockham
Copy link
Contributor Author

ockham commented Apr 20, 2020

i18n

all strings used in template should be subject to i18n

I definitely agree with your reasoning for this! A template is defining the structure of a site or pages on the site; it's the UI that exists around the content. Though I'm not sure I agree with the idea of having a second block implementation just for the site editor. I feel like part of the point of FSE in Gutenberg is that it's "just plain blocks," and part of the power we expose is that all blocks "just work." It seems as if we would have to wrap a ton of blocks for this to work out, and if they appear different to the user in the inserter, that would be confusing. There are a ton of different text and image-related blocks! (Let me know if I am misunderstanding your proposal!)

I think you're understanding it mostly correctly. To clarify, I wouldn't want any of this added complexity to be exposed to the user: in the block picker, they should only see the plain ol' primitive blocks when in content editing mode, and only the 'smart' (context-connected) ones in site editing mode (which, for all practical purposes, should look the same way as the primitives, and bear the same names).

Would it be better to have an "option" in some of these blocks to do i18n? For example, the paragraph block setting might have a checkbox for "Translate?", and then if true, the block would pass its content through __ before saving it (or before rendering it, or something like that).

I think it'd make sense to have those blocks 'natively' support i18n (that's actually what I was trying to say with my proposal 😅 -- the 'wrapper' only being an implementation variation), but without the UI option. (The idea being that we can always assume that strings in content editing mode aren't supposed to be translated, whereas in template editing mode, they always are. I think that makes at least sense from a YAGNI angle; we can always add more manual control later if we decide we need it.)

I think a critical difference here is that before, a theme could literally hardcode, e.g. __( 'download' ), but now, that is editable. So the user can change the text of anything to whatever they want. So in the previous case, the translations might be done here, but now... there is no guarantee what words have been used, so it's no longer possible to guarantee a complete translation for a theme. This seems like a much bigger issue than blocks can solve by themselves.

I don't quite get this paragraph 😅 -- could you rephrase? (I was thinking each theme had associated with it a language pack, and it's up to translators to provide those for individual languages, based on strings extracted from the theme.)

Which is why I wonder if we're getting ahead of ourselves with respect to i18n. Since we are switching from storing site layout in theme PHP files (which have easy access to __) to storing site layout in post_content of a CPT, I wonder if the i18n case for templates and template parts would (or should) be solved by WordPress multi-language support? I'm pretty sure that was on the roadmap at some point. It seems like solving that problem for normal post_content (and blocks) would solve it for templates and template parts at the same time.

Yeah, that's a fair point, and it briefly crossed my mind while I was writing this proposal. Are you suggesting to postpone solving this problem? I think that's entirely possible if we want to prioritize FSE over i18n (as we do).

It's an interesting problem, to be sure. If we were to wait for multilingual support in general, that would definitely put block-based themes at a big disadvantage in the meantime. I'm sure many folks would avoid block-based themes if they could not be translated.

Indeed 🤔

dynamic image

when it comes to linking images, I guess I'm not sure why the new block context API couldn't be used to solve the problem of relative URLs.

I think the block context API can be part of a solution, but it's not sufficient -- more pieces are needed.

For example, what happens if you change the domain of your current site? Do all the images you inserted stop working because they are hardcoded to the olg domain? (To be honest, though, I'm not sure how that works in WP :))

I think that WP almost exclusively uses absolute URLs to refer to images (which makes sense, if they're supposed to work from /wp-admin/post.php, /some/permalink/, and /some/other/permalink/ regardless); those absolute URLs might be updated if you change the site's URL; but I don't think that that covers our needs:

The use case from #20966 is that we're dealing with a block/template-based theme that is distributed somehow, e.g. as a zipfile. That theme was authored using templates that contain blocks -- among them, an image block. At the time the image was uploaded and inserted, it ended up in some subfolder of in the wp-content/uploads/ folder of that site; the image source attribute stored in the block is an absolute URL. That's not a problem as long as the theme is only used locally, but if the idea is to export/'package' it for distribution, the image should obviously be included as an asset, and the URL needs to change. It's possible that making it a relative URL would be enough, but I think that since a WP site's theme root folder can be customized (through a filter), it should be relative to that folder, and thus needs to be re-concatenated with that folder when used. (Old-school PHP-based themes just use built-in WP functions such as get_template_directory_uri/().

I definitely like the idea of an omnipresent site context, which specifies the base domain, and then we can rely on that to concatenate the relative path to the file. I guess I don't understand why we would need to create a second block to wrap around that? Couldn't a site context exist in the post editor as well?

The site context could exist in the post editor, yeah. I think the concatenation is the crucial part though; the 'primitive' image block doesn't support something like that out of the box, so I was thinking we'd need some intermediary layer to do that.

exporting

Not sure we currently have functionality to [export as a theme] yet

Some discussion about theme export here. TLDR is that it was working in a PR, but the PR was too large so it was removed for the time being: #19260

Perfect, thank you!


It might be fair to ask if this problem could be de-prioritized, if indeed solving #21204 can/should be postponed to whenever i18n is tackled at a Gutenberg/WordPress-wide level, and if #20966 turns out to be relevant only for the authoring of themes (for distribution) -- although the latter might be fairly relevant to prove the viability of Gutenberg's FSE capabilities.

@noahtallen
Copy link
Member

I was thinking each theme had associated with it a language pack, and it's up to translators to provide those for individual languages, based on strings extracted from the theme

To rephrase, that language pack is translated and exists assuming that all of the strings are constant and cannot be changed. I.e. they are defined like __( 'I want this string to display!' ). Previously, the end-user wouldn't be modifying that value (since it is in PHP). But now, in the site editor, that value is easily modified. In fact, we expect and want everyone to be able to e.g. remove or re-write a paragraph block saying 'I want this string to display!'. Basically, a translator won't have any idea what text actually ends up on the site after the end-user is done modifying the templates. Of course, you can guarantee the translations that are shipped with the basic theme, but since the user can change anything and everything about the various templates very easily, they would move outside of the definitions provided in the translation pack very quickly. This would result in inconsistent translation across the site. (I can't claim to be very knowledgeable about i18n because of my English bias, but I have heard folks complain that half a translation can be worse than no translation.)

I should also note that I have not created WP themes before, so it is likely that I don't know exactly how things like this "normally" work :)

Are you suggesting to postpone solving this problem?

Honestly, I am not sure. I can see arguments both ways. The main thing from my limited (and more selfish) point of view is that it seems as if it would be solved in a "cleaner" way if it was part of the comprehensive multilingual support. It seems that whatever we try to come up in the meantime is just working around the lack of proper multilingual support. But proper i18n support might be an important enough requirement for launch that we need to add those workarounds for now. I don't think I'm the person to make that decision :)

the 'primitive' image block doesn't support something like that out of the box, so I was thinking we'd need some intermediary layer to do that.

Thanks for fleshing that out a bit more! I was thinking we could just try to add that kind of support to the 'primitive' image block directly. Do you foresee issues with that approach?

It might be fair to ask if this problem could be de-prioritized

It does at least seem like theme export is a prerequisite for this problem! How can we test that our ideas around contextual images work if we cannot create themes in the editor?

@ockham
Copy link
Contributor Author

ockham commented Apr 20, 2020

I was thinking each theme had associated with it a language pack, and it's up to translators to provide those for individual languages, based on strings extracted from the theme

To rephrase, that language pack is translated and exists assuming that all of the strings are constant and cannot be changed. I.e. they are defined like __( 'I want this string to display!' ). Previously, the end-user wouldn't be modifying that value (since it is in PHP). But now, in the site editor, that value is easily modified. In fact, we expect and want everyone to be able to e.g. remove or re-write a paragraph block saying 'I want this string to display!'. Basically, a translator won't have any idea what text actually ends up on the site after the end-user is done modifying the templates. Of course, you can guarantee the translations that are shipped with the basic theme, but since the user can change anything and everything about the various templates very easily, they would move outside of the definitions provided in the translation pack very quickly. This would result in inconsistent translation across the site. (I can't claim to be very knowledgeable about i18n because of my English bias, but I have heard folks complain that half a translation can be worse than no translation.)

Right, gotcha -- thanks for rephrasing.

My gut reaction is -- that's a bridge we can cross when we come to it. Your next statement is relevant:

I should also note that I have not created WP themes before, so it is likely that I don't know exactly how things like this "normally" work :)

They work pretty much the same way! If you use a theme as-is -- the way it's distributed, you get its translated strings. If you change any strings, you lose the translations. To add new translations, you can re-run string extraction, edit *.po files, and generate *.mo files from them -- either with a toolchain on your local machine, or through a WP plugin.

The point being: Both modifying themes, and translating strings is cumbersome now. With FSE, we make the first part easier -- the second part remains unchanged. To improve it, we'd need to implement a user-friendly translation system in WP/GB, which is clearly beyond the scope of this project.

It's true that without such functionality, modifying themes will be somwehat less appealing -- this will eventually highlight the relevance of Gutenberg's projected i18n phase. But I don't think that this current deficiency should block us. We can differentiate use cases -- if a user just wants to modify their theme for their current WP site, it's fine to replace an English language string with a string in their own language; since WP won't find that string in its translation files, it'll just use the untranslated string. If they won't to do it more professionally, they can use an English language string, and use a plugin to translate.

Are you suggesting to postpone solving this problem?

Honestly, I am not sure. I can see arguments both ways. The main thing from my limited (and more selfish) point of view is that it seems as if it would be solved in a "cleaner" way if it was part of the comprehensive multilingual support. It seems that whatever we try to come up in the meantime is just working around the lack of proper multilingual support.

Yeah, makes sense. I think to explore this further, we'd need to think through if content and presentation (templates) will really follow the same principles when it comes to i18n: For presentation, we have an established system that solves part of the problem -- PHP/WP's gettext and language packs. Scaling those to a JS/GB/block world seems more straightforward than the question of how to manage multilingual content; or at least is it easy to extend WP's current translation system incrementally to cater for templates (e.g. by passing the locale through block context) without arguably getting in the way of the (probably) more complex solution that multilingual content will require.

But proper i18n support might be an important enough requirement for launch that we need to add those workarounds for now. I don't think I'm the person to make that decision :)

Well we can certainly discuss it some more 😄 -- You certainly have an informed opinion!

the 'primitive' image block doesn't support something like that out of the box, so I was thinking we'd need some intermediary layer to do that.

Thanks for fleshing that out a bit more! I was thinking we could just try to add that kind of support to the 'primitive' image block directly. Do you foresee issues with that approach?

Yeah, so that was kind of my proposal. The issue I see mainly is mixing concerns, and that we might end up copying the same edit-site specific logic to a number of different blocks (which is what brought me to the wrapper approach). But maybe those are implementation details, and we can just start with one approach and see if it fits.

It might be fair to ask if this problem could be de-prioritized

It does at least seem like theme export is a prerequisite for this problem! How can we test that our ideas around contextual images work if we cannot create themes in the editor?

Indeed 👍

@gziolo gziolo added the [Feature] Blocks Overall functionality of blocks label Apr 21, 2020
@mtias
Copy link
Member

mtias commented Apr 21, 2020

There are a few things being conflated here. If a user modifies text coming from a theme it becomes their content and doesn't need to be translated anymore. Basically, a translator won't have any idea what text actually ends up on the site after the end-user is done modifying the templates.

Of course, you can guarantee the translations that are shipped with the basic theme, but since the user can change anything and everything about the various templates very easily, they would move outside of the definitions provided in the translation pack very quickly. This would result in inconsistent translation across the site.

What would be inconsistent? The user is modifying text in the context of their locale. User content is never meant to be translated.

@noahtallen
Copy link
Member

Definitely! I agree with that.

What would be inconsistent

Some strings provided by the theme would be translated and others would not be. If I understand what @ockham said, this can still be the case today (?), but the site editor makes it easier to get into that state. (Unless, does the theme translation go into only the site's locale, not front-end user's locales?)

Isn't a broader problem how to differentiate between a string provided by the theme in a template, and a string that the user has modified in the template? So the former ought to be translated, but the latter should not be translated. If content is stored the same way in both cases and are all in blocks, how do we translate for the first scenario 🤔

@noahtallen
Copy link
Member

By the way, thank you all for helping me understand the context around how this works :)

@epiqueras
Copy link
Contributor

Isn't a broader problem how to differentiate between a string provided by the theme in a template, and a string that the user has modified in the template?

Exactly, see #21932.

@mcsf
Copy link
Contributor

mcsf commented Apr 29, 2020

Echoing some of what has been said, I agree that it's important to draw a distinction between strings* in HTML-declared block-based themes and strings in user-modified templates and template parts which reside in CPTs on a site. The former are something to solve soon, and an expectation for anyone coming from traditional themes; the latter is a specific branch of the problem of supporting multiple translations of user content, and is thus something for Phase 4 of Gutenberg — multilingual support.

*: It's must be noted that serialized block content is just HTML with block boundaries on top of it. The concept of "string" doesn't materialize in there. It's merely an understanding that we all share that some fragments of the HTML correspond to "values" that we'd like to be able to run through specific functions.

when it comes to linking images, I guess I'm not sure why the new block context API couldn't be used to solve the problem of relative URLs. For example, what happens if you change the domain of your current site? Do all the images you inserted stop working because they are hardcoded to the olg domain? (To be honest, though, I'm not sure how that works in WP :))

If I'm not mistaken, this is still not solved by WordPress and requires manual intervention, usually in the form of a database-wide string-substitution operation. Knowing this is relevant for establishing expectations around the early forms of block-based theming: while block context is a tool we can already count on, we shouldn't necessarily overuse it in an attempt to solve everything prematurely.

@youknowriad youknowriad added [Type] Discussion For issues that are high-level and not yet ready to implement. and removed [Type] Tracking Issue Tactical breakdown of efforts across the codebase and/or tied to Overview issues. labels Jun 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Blocks Overall functionality of blocks [Type] Discussion For issues that are high-level and not yet ready to implement.
Projects
None yet
Development

No branches or pull requests

8 participants