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

I can manage container blocks #99

Open
7 tasks
djay opened this issue Jul 8, 2024 · 6 comments
Open
7 tasks

I can manage container blocks #99

djay opened this issue Jul 8, 2024 · 6 comments
Assignees
Labels

Comments

@djay
Copy link
Member

djay commented Jul 8, 2024

Current volto doesn't handle containers very well.
There isn't a built in way to navigate up and down container heirachies and add sub blocks. This was managed by block specific custom code. Removing block custom inline UI we need to have a generic way to manage this.

e.g.

User stories (As an editor...)

Out of scope

Proposed integrator api

  • if the a block is rendered inside another block then this will automatically be recognised as a container. There isn't a need to know the bounds of the container. Adding a new block after this block will add it to the blocks and blocks_layout fields of the parent block.

  • Blocks are added into a container using the add button after the currently selected block. However this won't work if the container is empty and in fact the container itself can be hard to select if it's empty. In this case hydra will add in the default block into the json (which in most cases will be a special block called the ChooserBlock), so a container is never empty.

  • ChooserBlock can be rendered as a kind of skeleton for the various kinds of blocks that might be in this container and should be styled to take up the space it's replacement would

    • hydra.js will place an add icon in the center and clicking on it will popup the block chooser which will then replace this block with the chosen type
      • similar to - Image
      • The integrator customise the add button on a chooser block or turn another block into a chooser block by adding data-chooser attribute an element within that block to act as the default add/chooser icon
      • The Integrator could also choose to remove the add button by hide_chooser_add:true in the container hints.
        • for example the SlateBlock acts as a chooser using "/" shortcut so doesn't need an add button
    • ChooserBlocks aren't saved so won't appear in the final rendered page. The integrator can then choose to not render the container if it's empty.
  • You can add some hints to control the container using data-block-container. This contains json. e.g.

<table data-block-id="..." data-block-container="{field:blocks, min:2, max:4, allowed:['SlateBlock', 'ImageBlock'], default:'SlateBlock', 'hide_chooser_add':true, style:'horizontal'}">
<tr data-block-id="..."><td data-editable-field="value"><p>my text</p></td></td>
<tr data-block-id="..."><td data-editable-field="value"><p>other slate</p></td></td>
</table>
  • defaults are

    • field="blocks" (and will use blocks_layout to out the order so this is really a prefix).
      • This allows you to have more than one container within a block, for example, left and top for a forms block?
    • min=1 (you can't have 0)
    • max=null - unlimited
    • allowed=[] - any block
    • style=null - {horizontal, vertical} - null means opposite orientation of the parent container. This determines the location of the "add" button after the block, and the DND markers.
    • default=null - if only one block is allowed then it's that block, otherwise it's a special block ChooserBlock
      • If the editor deletes blocks so the remaining blocks is less thanmin then a the default block will be created in it's place.
    • hide_chooser_add - prevent hydra from putting an add icon on your default block type. false if it's a ChooserBlock, false otherwise.
  • The sidebar UI should provide a way to edit settings and select parent blocks

    • maybe similar to I can add a table #135 where parent settings are merged with child settings with two levels of accordions
      • pro: simple blocks it's all in one place, with less clicking and trying to understand your context
      • con: complex blocks you already have a lot of settings. a listing inside a form could be too much? but also hiding that under tabs etc might not make that simpler...
        • and you can always just close the parent blind to make it simpler

This syntax allows for the top level page to have more than one container instead of just the single "blocks" main section. volto doesn't let allow it but in the future we could use this to have blocks placed in a sidebar or footer etc so they don't have to be all in the middle of the page.

@djay
Copy link
Member Author

djay commented Aug 14, 2024

@MAX-786 of the things that are left this is the thing I'd most like to see

What it means is that if we have a block like the grid - https://demo.plone.org/block/grid-block/text.

  • We will have a standard way to add, rearrange and remove blocks from inside a container block
  • a standard way to move blocks in and out of containers (e.g. DND)
  • containers or always either horizontal or vertical
  • a standard way to handle containers inside containers and selecting parent containers that aren't easy to click on.

So the goal of a demo would be just to be able to add a block to a grid block, remove it and DND it in and out.

btw. Not really sure what they did in https://demo.plone.org/block/grid-block/text to allow multiline text. but it doesn't seem right to me to have paragraphs be seperate blocks outside a grid but one block inside a block.
So instead of this I would

  • have a column block that can be added inside a grid block. it's just a container
  • allow text blocks to be added inside a column block (vertically).

@djay
Copy link
Member Author

djay commented Aug 14, 2024

for the integrator.

json looks like

"debb8187-e54f-4cad-8301-2343d65e2024": {
      "@type": "gridBlock", 
      "blocks": {
        "91cdc344-e34c-4387-b0d2-73962abc2559": {
          "@type": "slate", 
        ...
        }, 
        "b6d056e8-0f7f-453e-b8bc-ef97a654b48f": {
          "@type": "slate", 
        ...
        }
      }, 
      "blocks_layout": {
        "items": [
          "b6d056e8-0f7f-453e-b8bc-ef97a654b48f", 
          "91cdc344-e34c-4387-b0d2-73962abc2559"
        ]
      }, 
      "styles": {}
    }
  }, 

The integrator needs to tell hydra what html element to place the blocks inside only I think.

Something like this?

<table data-block-id="..." data-block-container-horizontal="blocks,blocks_layout">
<tr data-block-id="..."><td data-editable-field="value"><p>my text</p></td></td>
<tr data-block-id="..."><td data-editable-field="value"><p>other slate</p></td></td>
</table>

You can see in this case the integrator has decided to change how the blocks are rendered when inside a container. which this should allow them to do.
The above would also allow us to have more than one container in the same block, which I think is something that should be allowed. for example a left slot and a right slot.

Questions

  • I don't really know where you get the list of allowed sub block types for a given container. is it in the container block schema?
  • somehow need to know the max number that can be added. like grids have a max of 4 columns
    • can't just be an integrator instruction because admin UI could have a way to add a subblock
  • there should be a concept of a default sub block type. Whenever the last block is deleted in a container, then a new empty default block is created to take it's place. so then it's never empty. This solves many UI problems.
    • Maybe just pick the first in the list of allowed types?

@MAX-786 MAX-786 self-assigned this Aug 14, 2024
@djay
Copy link
Member Author

djay commented Aug 21, 2024

If the default block isn't slate but you have multiple choices of block then filling the empty container with the first one isn't that good. the user then has to create a new block, rearrange them and remove the default one. If the max size is 1 that can't be done.

There is a couple of options

  • have a chooser block that renders clickable elment which pops up the block selector
    • so have a data-block-selector attribute to turn something into that clickable "add" button.
    • gives the integrator the ability to set the size and look of that dummy block to match what the real block will get rendered as
    • if a container inits with several empty spots then all can have this dummy chooser block. Allows for a fixed length container as something is always taking up a spot
  • A standard hydra.js rendered add button for adding into an empty block
    • integrator has to ensure the container has a min size so this could get rendered

@djay
Copy link
Member Author

djay commented Aug 25, 2024

I've given it some thought and put what I think is the best approach in the main comment above. Using the idea of a virtual ChooserBlock as the placeholder to be able to render the add button on an empty container.

@MAX-786
Copy link
Member

MAX-786 commented Sep 5, 2024

container block will have multiple instructions and since we using staged approach I will open up a PR and break down these into tasks so that we can tryout containers with each integrations. But first want to discuss few things below.

@djay few things I am not clear with:

  • data-block-container-horizontal shouldn't be the name of attr bcz it already got 'style:horizontal' so doesn't make sense and also from hydra.js perspective it will make it easy to look for data-block-container and check the js object for style.

the integrator customise the add button on a chooser block or turn another block into a chooser block by adding data-chooser attribute an element within that block.

  • see from the comment what ican understand, that if 'default:null' then the hydrajs will add skeleton add block div inside container if no. of blocks is less than 'min' and integrator can customize this by having attr data-chooser in this data-block-container but then in both the cases, how would i add a block if i got maybe more blocks than 'min' but less than 'max' ?

You can use a container hints outside of a block in order to create multiple areas of a page that can contain blocks

  • can you explore this a bit more? like wdym by container hints outside of a block? container block you mean? a bit confused here...

@djay
Copy link
Member Author

djay commented Sep 5, 2024

@MAX-786 the first one was a mistake which I've now fixed.

The rest I've tried to rewrite it to make it clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants