First of all I want to say, that I am really enjoying the discussion about the flexible content builder or the WHATEVER-builder (as I accidentally named it earlier) we are having here. And now I am purposely not calling it more specifically Site / Content / Page / Layout / Theme Builder. I think that @kongondo made a really wise question asking to define the distinction between those. And to determine, what exactly do we want to build.
Are we really talking about the different things?
It seems to me that now we are contrasting the YOOtheme Builder from @Jonathan Lahijani‘s epic video labeling it as a layout editor or a site builder, to bard / editor.js calling them content block editor or something like that. And choosing between the two.
But, as I understand, @Jonathan Lahijani never proposed a layout editor / site builder way in a sense that it should store the final html code and let the content editor to directly manipulate it. He intentionally made it clear, that he chose to show us YOOtheme builder because it “separates the builder-part from the actual content” doing it in a “ProcessWire way”. And he also stated, that he is not for tightly coupling to the CSS framework (Uikit in YOOtheme). But he would want the ability to define the layout IN SOME WAY, like being able to create a 2/3/4 column grid and place the components (I think that they are the same as content blocks from bard / editor.js) inside those columns. And to be able to move those components to desired slot in the layout. I would really want that part too)
I think that the earlier mentioned “ProcessWire way” is actually the separation of content and presentation. When we use Repeater Matrix, we store the content and some meta information not directly in the html code, but in the Repeater Matrix Page’s fields. Actually, editor.js (do not know about the bard field, but probably that one too) is also storing the content separately from the presentation. Not in the separate database tables, but in one json object. So it is kind of doing it the “ProcessWire” way too))) One difference, is that in the case of editor.js we have to manually deal with json when generating actual markup, when Repeater Matrix provides us the comfortable PW API for that (making this way a little bit more ProcessWire). The other difference is that when using Repeater Matrix we have to manually create all the actual fields and assign them to content types, making this way more laborious. The coin has two sides.
So, as I can tell, we all want the same kind of editor. The one that does not store the actual markup, but the one that stores data, that later we can render to actual html (or any other format really).
What about the layout part?
As I said earlier, I would really want to have the ability to define layout with the flexible content builder we are talking about. @Jonathan Lahijani showed 3 ways of doing it in current Repeater Matrix-based content builder, and all of them are kind of a pain. But I do not want our editor to actually store something like col-sm-6, but rather some generic layout information. Like having a grid block, that can only have col block as a child, which in it’s turn can store the actual components.
In Repeater Matrix now we do not have a distinction between layout element and a component. We only have the ability to put one element inside the other (the ugly nested Repeater Matrix way or the repeater depth way which also has its flaws). But it is the developer who is responsible to make all the decisions generating markup. So the developer could choose to implement the layout part or not to do so, which is really a powerful stuff I enjoy and would like to keep. That’s why I was talking about the “WHATEVER-builder” or a “framework for constructing a content builder” before.
To do so, our new flexible content builder should allow us to:
define the allowed parents/children for the elements;
allow to show the child elements side by side (to imitate layout);
intelligently control the drag and drop, taking into account the allowed parents/children for the elements.
As far as I know, editor.js does not allow the nesting of the elements.
Creating custom elements from admin
The other great thing about the Repeater Matrix-based content builders is that we can easily create new custom content types (elements, components…) right in the comfort of the admin. It is not really a quick thing, as we need to deal with creating the fields and assigning them, but it is rather familiar. And those custom components can use all the other ProcessWire data with Page Reference fields, Selector fields etc, which is cool.
If we go with with editor.js, I am in real doubt we would be able to create the new elements in admin. The dev would probably need to develop a js plugin and install it in non-PW-standard way, making it unlikely to happen. The connection to other Processwire content from that custom element would be even harder to implement.
Visual representation of the content
Repeater Matrix-based flexible content builders in the mentioned video look nothing like the actual content. The left part of YOOtheme builder does neither, but it at least represent the layout in some way. Editor.js / bard do not do that too. From the other replies in this thread I see, that it is not that important and even not desirable.
Repeater Matrix interface is kind of ugly, when representing content. But:
at least is is familiar and in line with all the other backend;
it could be improved to be more like YOOtheme builder:
add icons for adding content types,
remove or refactor the repeater elements “chrome”,
allow showing repeater elements side by side for the layout thing;
and it uses the standard admin form ui, which means it is easier for @ryan to deal with.
As you see, I am for the native ProcessWire UI here)
And one more thing. In the video we see the actual markup rendered to the right of the YOOtheme content editor. We can do that also, creatively reloading THE WHOLE PAGE on changes with Hotwire / Unpoly / Vue. Making the flexible content builder feel dynamic and not requiring those saves-and-reloads. And making the connections between the options in the builder part and the final markup obvious to the editor.
The data storage
Repeater Matrix-based flexible content builders store the data in pages and fields. This makes it laborious to create new content types (create a new field, or find an existing one to reuse it, assign it, override it…) This also makes it hard to duplicate, copy/paste content in the site or between the projects. But it also allows us to use the familiar API when generating markup.
Editor.js’ data object is compact and probably easier to be reused. But it lacks connection to other PW data. And the UI is totally different.
Could we combine the benefits of the two? What if we invent the json-based storage for the data gathered with regular ProcessWire inputfields? Something like Mystique field combined with JsonNativeField (so the content is even searchable).
And what if we allow to create the Interface for the new flexible content builders components with “fake” fields, which have their inputfields only, and are not connected to the database? Kind of like fields for the Form Builder or the UI for the @adrian’s Admin Actions’ actions.
Think about that. We could design elements with any fields we need not messing up the regular fields namespace. Those fields’ definitions would be stored in our flexible content builder’s options, as well as all the content types (elements) and the actual field data in json. The UI would be the same inputfields we already have. When working with this field from the API, the field could be accessible as a PageArray object where each Page is a corresponding element.
Bringing it all together
I think it is possible to build the flexible content builder (or the WHATEVER-builder) using a lot of the technology we already have in PW. It can be comparable if not better than all the other competition. It can be well integrated and totally configurable through the admin. It can be portable between templates and projects. And it can be visual and responsive.
What do you think?