Closed mtias closed 6 years ago
This stores the block content and name in a specific post type reserved for blocks.
This is an interesting idea and I think it was discussed a few times in the past. Maybe could be interesting to have a look at other systems that are already treating content as reusable "pieces of content", first one that come into my mind: Liferay.
Cool idea. We've developed plugins that create a custom post type to embed these via shortcodes in the past, so this addition would be very welcome.
Maybe could be interesting to have a look at other systems that are already treating content as reusable "pieces of content"
TYPO3 does that. Basically, every content element (block) is a separate post, thus you can reference each one of them. Not really user friendly though.
Neos CMS has nodes, but I'm not sure they can be referenced/embedded.
This sounds similar to what is being done by Divi. You can make an element "global" and it changes the background color of that element.
💥
This is the stuff that Gutenberg was built for. Even just for trivial use cases like "avatar on the left, text on the right, then a separator" on an "About Us" page would be so good to have.
To expand on what @jwold says, I think it's important that we have the right visual style for this. Color is one tool, background is another, border-style is a third. When we choose this style it's important we think about what other things we might one day use block borders and colors on, and in the past collaborative editing has been suggested as something that might be built as a feature. In such a feature, you could imagine a block being "locked" to the person editing it. Perhaps in this case we would "gray it out". But we'd want to find a style for these reusable blocks that was distinct from "locked" blocks.
Would there ever be a situation where a reusable block had aspects that could be edited? In that case we'd want a style that stacked with being locked to a user.
@jasmussen great points! Here are a few ideas I had to start off the conversation of what the global/locked states could look like:
Beaver Builder uses a similar model where we store saved module instances in a custom post type. We have two flavors: normal & global. A normal saved module acts as a preset, so when someone adds it they get a preconfigured block and they can make changes to that instance. A global saved module has all it's instances bound so when it's edited, those edits are reflected across the site. Both are very useful.
Airstory thinks about these shared "global" content as "Cards" that you can drag into different posts. It might be useful to have a library of saved content blocks that you can insert. Once inserted, any changes that you make could be pushed back to the original saved block or kept different.
Imagine global blocks replacing headers, footers, and sidebars :)
Like @jasmussen said, color, background color, etc. can be a good differentiator, especially if we add a secondary indication like border thickness or radius. Or, even a label.
Would be good to run some usability tests on other services and plugins that offer "global blocks" to see how they perform and what kind of pitfalls they have. @karmatosed is this something you could help shepherd?
Would be good to run some usability tests on other services and plugins that offer "global blocks" to see how they perform and what kind of pitfalls they have. @karmatosed is this something you could help shepherd?
Absolutely, any you can think good to focus on?
Definitely Divi. Should also figure out if or how any of the big site builders (Squarespace, Wix, Weebly) handle content across multiple pages. @brentjett, have you done any usability testing on global blocks in Beaver Builder you could share the results from? If not, we can also include that in testing. :)
@melchoyce I'm not aware of any specific to saved/global blocks but I'll ask the guys. If anyone would like to see how they are used in Beaver Builder for yourself, i'm happy to set up a demo.
@brentjett I would appreciate a demo, thank you so much.
An aside, but I also would love to have any usability testing insights in general from the Beaver Builder team.
@karmatosed and anyone else who'd like to play with it, I set up a demo site with some saved and global modules. Feel free to play. Beaver Builder and Beaver Themer are both installed. http://annoying-panda.w3.poopy.life/ demo / T6h3X7uccJU1 Message me on slack if you have any questions.
@mtias:
Saving flow can be tricky, because we could issue saves through the API separately from saving a post, since the post only has a reference to the content of the block.
Aside from the UX question, I think at a technical plumbing level it is similar to the issue of previewing and saving changes to postmeta. In the Redux store, I think essentially it should be structured to allow for any number of REST API resources to be contained within them, whereas right now it only contains the one post resource (with nested meta
). One of the store properties can be the post that the editor is currently editing, for example, but by allowing any number of REST API resources to be kept in the store we can then include not only changes to the post itself but also changes to any reused external block
posts. Then since all of these are in the store, they can be held onto for drafting, revisions, and frontend previewing.
That is to say, the Redux store for the editor could essentially look a lot like a Customizer changeset, and changesets actually then be utilized for revisions and and frontend preview.
To expand on what @jwold says, I think it's important that we have the right visual style for this. Color is one tool, background is another, border-style is a third. When we choose this style it's important we think about what other things we might one day use -- @jasmussen
I love the global block idea and the UI @saracannon shared re Airstory is an interesting approach. I want to echo @jasmussen, however, if we end up using borders and backgrounds to indicate a block's status we're assuming that Gutenberg will always hide in the backend. I hope this not to be the case... a Gutenberg + Customizer union (Gutenmizer?) would potentially give us a decent "site builder" without having to visit customize.php and without having to worry about themes (gasp!).
@melchoyce said... "Imagine global blocks replacing headers, footers, and sidebars :)" YES! I am imagining.
Imagining aside. @jwold is there another way you can think of to represent a global block other than changing the border/background? Some kind of status icon perhaps?
a Gutenberg + Customizer union (Gutenmizer?) would potentially give us a decent "site builder" without having to visit customize.php and without having to worry about themes (gasp!).
THAT.
Imagining aside. @jwold is there another way you can think of to represent a global block other than changing the border/background? Some kind of status icon perhaps?
Here's some things I've captured from the above comments that give inspiration for how this could work:
Clicky interface
-or-
Drag and drop interface
And the overall visual experience should account for being edited in the fronted:
I'll play with some ideas and see if any inspiration strikes. Also keen to see what others come up with!
@rheinardkorf @marsjaninzmarsa:
a Gutenberg + Customizer union (Gutenmizer?) would potentially give us a decent "site builder" without having to visit customize.php and without having to worry about themes (gasp!).
I do hope that we can evolve the Customizer to eliminate the need to visit the customize.php
URL, where the live preview functionality can be seamlessly loaded into the admin (settings pages, post editor) and also bootstrapping while on the frontend. The Customizer is somewhat divided into two parts: the bundling together of changes (a changeset) and previewing how those changes apply onto the frontend of a site (or to the REST API). I'd love to see using the changeset as the mechanism for doing autodrafts and previewing changes on top of published posts (as above https://github.com/WordPress/gutenberg/issues/1516#issuecomment-312475519 and #1673 and https://github.com/WordPress/gutenberg/issues/1295#issuecomment-312734832).
But the other aspect of the Customizer, the frontend preview, will ultimately still be required to see how the blocks you are editing in the abstract preview (Gutenberg editor) will appear on the actual preview with the theme applied (what you see when you click the Preview button). If we can move to themes consisting primarily in styles, with templates constructed purely with blocks that are laid out with CSS grids, then indeed we shouldn't have to worry about themes in the same way we do today.
@westonruter Thanks for the feedback. I know you've been working towards this idea for a long time. So not trying to cut across it, I think its important in moving us towards a great customisation experience. Changesets was quite an important feature!
I completely understand though that frontend preview is required. Especially since Gutenberg doesn't care about theme styles. My dream though is the scenario you described towards the end...
If we can move to themes consisting primarily in styles, with templates constructed purely with blocks that are laid out with CSS grids, then indeed we shouldn't have to worry about themes in the same way we do today. -- @westonruter
It would kill an entire market, but, like Matt said, someone will create a plugin (or a theme can do it) that will turn off Gutenberg and then people can still have their themes.
I realize we're going on a tangent from the purpose of this issue, but FWIW, I don't think it will necessarily kill a market, but rather the market will evolve. I think that Gutenberg being used with themes as they exist today will be inherently limited to the extent it can customize what exists outside of content and sidebar areas. But new themes that add_theme_support()
for an as-of-yet undefined componentized theme conventions, then Gutenberg would be able to fully manage the templates in a theme. I believe themes should become increasingly declarative (config-driven) as opposed to imperative (procedural) in the way they are structured. This will allow the editor to operate at a meta level to manipulate entire templates as opposed to just the content inside of a template.
@westonruter agreed. We have diverged a bit and started dreaming. But having dynamic reusable (or global) blocks is a way to start moving us toward what we described here and why I feel that talking about how global blocks might work and how they will be presented inside Gutenberg is a big deal.
I am not convinced that styling the block to indicate its state is the best choice. Another type of indicator would be preferable.
And the overall visual experience should account for being edited in the fronted -- @jwold
^ ^
I believe themes should become increasingly declarative (config-driven) as opposed to imperative (procedural) in the way they are structured.
That is how you make WordPress better! 😄
I really like this idea. Like many others, it's along the lines of what I envision when I think of the future of themes. Just a set of preconfigured blocks in specific layouts a theme provides for people. They can do whatever they want from there. It's just a starting point, and a theme's design becomes even more emphasized.
I used a proprietary content management system that had a similar concept. This CMS had pages and templates. Pages could only take one-off blocks. You could use a template as the base of a page though, and it could contain blocks that would be "global" in the sense that they would be used on whatever page that template was in use on.
As a developer, I enjoyed the concept. As the manager of the CMS, I saw people using it struggle with a few concepts. These are anecdotal, of course, but I wanted to mention them:
Also, I'd want a nice way to view and edit all the global blocks I have, and know what pages or posts they're active on. Like a block library of sorts.
I've tried a few concepts for how global blocks could work.
Note 1: Since this could make its way into a true frontend editing experience, I'm trying to only use the content area and the settings panel. In an initial idea I was playing with converting multiple blocks to global up at the top (link: https://cloudup.com/ccGhILgDs3Q) but this creates problems as it gets you used to working sometimes in the settings panel and sometimes at the top of the screen. Bad idea. Here's what it would have looked like:
Note 2: We don't want to rely on borders and colors alone to differentiate a global block from a single block. As such I've added a global world icon to the top right of every global block.
Note 3: We need to figure out how concurrency locking fits into all of this. I played with some concepts for this toward the top of this thread.
Without further adieu here are the concepts. I welcome feedback and thoughts!
@jwold thanks for that. I like the global icon used with the border to indicate how it is reused in multiple places.
Your mocks incorporate the block group I hadn't seen discussed before (though it is mentioned above in #1680). If blocks in a group are re-ordered, they would then be re-ordered everywhere else that group is used, right? The block group would fit naturally to replace widget sidebars. But it seems from the concepts that you don't have to create a group if you don't want to. Or rather I suppose a group could just have one block in it.
The “revert to original blocks” link I think could instead be something like “clone global block into document” (better language needed). I don't think “original block” makes sense.
@westonruter great feedback. Here are my responses:
I like the global icon used with the border to indicate how it is reused in multiple places.
Agreed, these together work well.
If blocks in a group are re-ordered, they would then be re-ordered everywhere else that group is used, right?
Yes, I think that would probably make the most sense.
But it seems from the concepts that you don't have to create a group if you don't want to. Or rather I suppose a group could just have one block in it.
Yes, if you drag to select multiple single blocks, you can convert to a global block. And, if you just click on one block you can convert it to a global block.
The “revert to original blocks” link I think could instead be something like “clone global block into document” (better language needed). I don't think “original block” makes sense.
Agreed, the labels still need some work. Would something like "clone global block into document" just split up the global block and make them all single blocks again? If so I think something like (still a work in progress): "Convert global block to single blocks" could work.
See also #1930 which has a similar border-with-label design for indicating concurrent editing presence (maybe that's where you got it from).
See also #1930 which has a similar border-with-label design for indicating concurrent editing presence (maybe that's where you got it from).
I did see this ticket, but forgot about it. I think #1930 could help solve the problem discussed above with collaborative editing. Good suggestions so far!
Really dig the work done here, @jwold! Thanks for doing this, and super awesome use of the multi-select topbar! You get it.
Weston:
The “revert to original blocks” link I think could instead be something like “clone global block into document” (better language needed). I don't think “original block” makes sense.
In "Sketch", you can convert a symbol into the parts it was made of through a right-click menu action called "Detach from Symbol". Not sure if the verbiage can translate 1:1 to these concepts, but I like the term "detach".
A couple things related to UI, interaction, device independence, and accessibility.
Any feature based on drag and drop should also provide an alternative mechanism operable with a keyboard. Drag and drop is not available for all users and for all devices.
I see some of the interaction flows are based on the blocks multiple selection implemented in #62, see also #950. Blocks multiple selection currently works just with a mouse or other pointing devices. It's not available for keyboard users. I haven't open an issue for this yet because right now multiple selection is used only for bulk deleting blocks and after all, keyboard users can always delete blocks one by one, so it wasn't a huge barrier.
However, if more important features like managing global blocks are going to be based on blocks multiple selection, there should really be a way to do that using only a keyboard.
However, if more important features like managing global blocks are going to be based on blocks multiple selection, there should really be a way to do that using only a keyboard.
Agreed. This is a really great point. In a spreadsheet the way I often do it is something like this:
@afercia would something like this work from an accessibility perspective?
@jwold Shift + Arrows are the native way to make selection so I'd say that would be the best option. To evaluate from a technical point of view, also considering that now blocks can be navigated with arrows. See: "Arrowkeys should navigate between blocks" #520
This might help sighted keyboard users. Really not sure how to make multiple selection discoverable and usable for other users though, for example users who can't use mouse and keyboard or blind users.
The only thing I can think off the top of my head would be a very simplified alternative UI with a just a list of the blocks to be selected. Sort of very simplified "Bulk selection mode" like the one in the Media grid. Any thoughts very welcome 🙂
@afercia good point on how the UI I suggested works well for sighted users. But for blind users it would be a problem to try and sort through blocks and elements within the blocks.
Ok, here's the first (somewhat clunky) idea I've been able to think of:
Add a button for bulk selection in the right panel: settings > document > bulk selection button. When this is selected the content area UI will only show the block outlines with the titles of the blocks above them. Using keyboard navigation I could then arrow + shift through them and hear the names of the blocks called out and hear that they're being selected.
What do you think? I can create a sketch if what I shared above isn't clear.
Note: This does bring up a question @jasmussen, would we want to allow someone to make a global block out of common blocks that are NOT next to each other? My default answer to that is NO, that the blocks would have to be besides each other.
Add a button for bulk selection in the right panel: settings > document > bulk selection button.
@jwold it's clear 🙂 but I'm an a11y guy so I'd rather see the most simple solution as the best option. Using the inspector for these kind of tasks makes more sense to me. A bulk selection button there sounds good and I'd just make a list of checkboxes appear below the button 🙂
A bulk selection button there sounds good and I'd just make a list of checkboxes appear below the button
@afercia I tried a mockup of what this could look like. Since we only want global blocks to be made of single blocks that are next to each other, I'm struggling with how the UI could work. Can you give me your thoughts on this concept?
Since we only want global blocks to be made of single blocks that are next to each other
@jwold then I think I've missed this point. Do you mean global blocks are intended to be made of single blocks that are already next to each other in the content area? If so, why?
Haven't chimed in too much here since the discussion is on a great track. But wanted to quickly add:
seems to me the current multiple selection doesn't allow to select non-adjacent blocks; if so, this is a limitation... why I shouldn't be allowed to select, say, the 1st, 3rd, 6th, and last block to make a multiple selection (and then delete or build a global block)?
should the mouse-multiple-selection be improved to allow non-adjacent blocks selection? maybe using Cmd/Ctrl as modifiers?
instead, multiple selection based on checkboxes would allow to select any block, even non-adjacent ones; this seems to me something that would allow more flexibility to users
I'd like to see ⌘ + click to select non-adjecent blocks. One of the challenges that has made us punt this avenue of exploration for now, is that we are already dealing with multiple levels of focus on each block. There's hover, clicked (which is sticky so you can manipulate inspector items), and then there's selected. How do you ambiguate between clicked and selected? I have an idea I'll share in a minute, but I think as an interim solution, @jwold's idea of limiting the creation of global blocks to adjecent blocks could be fine:
As such it seems like if there's a straightforward, codewise, path forward to creating this feature without first having to enhance the multi select code, it might be worth it. (If it can be done in an accessible way, of course).
Alternately we should probably attack the multi select using keyboard as a first task. My intution was also to mimic how you select text — that is, hold shift and use the arrow keys. This intuitively suggests that only adjecent blocks can be selected. But your point about vision impairment certainly seems to make this tricky.
Here's what Google Photos does:
https://cloudup.com/cnBCurWTmL5
That is — hover over an image to surface a checkbox. Click the checkbox to select the image (clicking the thumbnail opens/zooms it). This is keyboard accessible through tabbing. One tab highlights the image, another tab highlights the checkbox, another highlights the next image, etc.
I'm unsure how the keyboard interaction could translate to Gutenberg, though, as it seems suboptimal for us. One idea would be that ...
Would that work or be a nightmare?
Do you mean global blocks are intended to be made of single blocks that are already next to each other in the content area? If so, why?
@afercia I was thinking this, but am open to going a different route. The reason was that if I am about to make a global block from the 1st and 3rd blocks, what happens to the 2nd block? Does the new global block have an empty space between it, or does it automatically just clump together? Seems like some confusing use cases. Whereas if global blocks are only made up of single blocks adjacent to each other there's less cause for confusion.
What would be a use case where I would want to create a global block from the 1st and 3rd block, while ignoring the 2nd? There may be a great case here I'm missing.
Oookay, let's rewind a bit. I just had a discussion with @mtias and he highlighted a few things that made me want to bonk myself on the head with a rubber mallet. The short is: we may have approached the solution here from the wrong angle. I do personally apologize for not having grokked this earlier. My excuse is that this work we are doing is very complex.
So, the thing is, this ticket is about turning a single block into a reusable block.
That means in V1 of Gutenberg, this feature is less about creating more complex templates or symbols, and more about re-using snippets that are then kept in sync. The examples Matías gives in the intro text explain the use-case.
Now the mockups got me so excited, but what they in fact depict, should probably be for V2 of Gutenberg. And they should probably take advantage of block nesting (see #428). So you could imagine first inserting a "Group" block, and then moving a number of blocks inside that group. Once that is done, you can once again make that single group block into a reusable block.
So that is to say, this particular issue should be resolved by making a button that turns a single block into a reusable block. This can probably be a button, "Make reusable block", at the bottom of the block inspector for every block, or something in that vein:
Grouping things together is something we'll need to look at regardless, for when we need to look at columns and other customization features.
we are already dealing with multiple levels of focus on each block. There's hover, clicked ... and then there's selected
Yep, and there are already several events bound to the blocks, we should be very careful in handling them see for example #1973
tab highlights a block (same as cursor hover)
Something worth considering, but: currently, the Tab/focus behavior on the blocks is inconsistent. Some blocks (e.g. text) have 2 focusable containers, while other blocks (e.g. image) have just one focusable container. This is particularly noticeable when tabbing backwards, see #1934 for more details.
On the first type of blocks (e.g. text), Gutenberg automatically moves focus from the outer container to the inner container (the one with contenteditable
). To implement a "tab highlights a block" mechanism, this behavior should probably be changed. I'd really like this behavior to be more consistent but also preserve quick navigation through blocks when tabbing.
Thinking a bit about this, what if all blocks had 2 focusable containers? This way, each container could have a different purpose, and expose different controls to users. However, at the same time there should be a mechanism to allow quickly tabbing through blocks with just one Tab press. The outer focused container could be used for navigation through blocks, the inner container for editing the block. @jasmussen thinking at your idea of "entering" a block and pressing Escape to "exit' it, maybe it could be combined with this? I'm trying to think at the interaction details but that's something definitely TL;DR 🙂
Re: Google Photos: it's an interesting example but they have the advantage there's just one control to display (the checkbox to select an image) while the Gutenberg blocks have several controls to display and having to tab through all of them is not so ideal.
However, seems to me Google Photos has 2 different "modes": using only the keyboard, when I tab to the album title the photos enter in a sort of "selection mode", they all become smaller and show a Remove button (screenshot on the left). Instead, when using the mouse, I get the "Select" checkbox (screenshot on the right) and only the selected images get smaller:
notice the tooltip at the bottom that informs me about the available action. Notice also all these visual feedback are also combined to a message sent to an aria-live region:
When using a keyboard, to go back to the "normal" mode I have to press Escape and then yes multi-selection is available using the checkboxes. Worth also noting that Escape is used as sort of back-navigation and always bring you to the previous view.
When using a screen reader, and entering one of the "modes", users get useful instructions with an aria-live message:
There are a lot of details on Google Photos implemented to have a good level of accessibility, all controls are reported correctly: buttons are buttons:
checkboxes are checkboxes:
and several, more advanced things that are expected on a highly engineered web app.
@jwold I think we imagine global blocks in a different way 🙂 I'm thinking at them as a way to extract "pieces of content" from a post and build a global block for later reuse, but not necessarily for immediate use as a global block in the current post. I may have the need to to get, say, the 1st and 3rd block, build a global block to use it in another post, but not in the current one where they would stay as single, separate blocks.
@jasmussen thanks for the followup. Seems like some of the bigger ideas that were discussed in this ticket should be held off for now. Agreed that this is exciting stuff though!
So that is to say, this particular issue should be resolved by making a button that turns a single block into a reusable block.
Do you think the UI for this is clear, or should I take a stab at what that could look like?
@jwold I think we imagine global blocks in a different way 🙂 I'm thinking at them as a way to extract "pieces of content" from a post and build a global block for later reuse, but not necessarily for immediate use as a global block in the current post. I may have the need to to get, say, the 1st and 3rd block, build a global block to use it in another post, but not in the current one where they would stay as single, separate blocks.
Great thoughts nonetheless. I appreciate your approach to the problem! At the end of the day I'd just want the solution to be something that makes sense for whoever is using it. I haven't thought of using global blocks in this way, but am open to it :). Sounds like that will be a discussion for another day for V2.
Will split out the keyboard interaction considerations in a separate issue 🙂
Do you think the UI for this is clear, or should I take a stab at what that could look like?
We're looking at ensuring that every block has a block inspector in some way shape or form (see #2023), and I was simply imagining that we add a button in that spot, somehow:
But I'm sure there's more to it than that. Feel free, if you have bandwidth, to take a stab!
@jasmussen I was thinking of putting this in the "advanced section" of the inspector, where we should place the "additional classes" and maybe the "anchor to this block" thing we discussed (#block-id
).
@jasmussen I was thinking of putting this in the "advanced section" of the inspector, where we should place the "additional classes" and maybe the "anchor to this block" thing we discussed (#block-id).
Yes! I've already taken steps towards that in https://github.com/WordPress/gutenberg/pull/2001 — feel free to commit to that and rename the heading, currently labelled "Block Settings" to "Advanced Settings" ;)
@mtias I've created a separate issue #2081 to focus on the technical aspects and data model for reusable blocks, since this issue is primarily focused on the user interface.
I dont like how it develops. "Global block", "Normal block", "Global group", etc...it means nothing to beginners, and is confusing for them. I believe so anyway.
It needs to be described in regard to Posts and front-end. It is how they experience all thing.
"Show block on all Posts", "Show block on all Pages", "Show block on this Post only", something like that they get directly.
"Show block on all Posts", "Show block on all Pages", "Show block on this Post only", something like that they get directly
I like this wording, @StaggerLeee 👍
We are not necessarily talking about a block that is shown in all pages / posts, but a block that could be displayed in multiple places, and updating it in one place propagates the changes to the others.
Think a testimonial I created for a single post, that then I want to display in a page that shows all my testimonials and I want them to be in sync. I convert my original testimonial to "global" (whatever name that is) and then I can select it from the inserter in my page.
One appealing aspect of blocks is that they lend themselves to become reusable pieces. This will be key for theme customization (think menus, headers, footers, etc) down the road, but it could already be useful in the context of posts, and it may be wise to get the foundation in place.
Examples
WordPress at the moment treats galleries like this—you insert the shortcode and it is evaluated at render time. But it would be nice if any block could be turned into such a reusable entity in a way that is clear to the user and not a surprise.
Proposal
Shared blocks can get a different outline color:
And when updating them the user can be presented with a confirm dialog asking if they want to update across all posts or convert the current instance back to a static block.
Saving flow can be tricky, because we could issue saves through the API separately from saving a post, since the post only has a reference to the content of the block. This is more of a UX question, though, that will affect blocks like "navigation menu" down the road.
cc @aduth @nb @westonruter @jasmussen @melchoyce @iseulde @youknowriad @nylen and anyone interested.