Frontend-rendered layout-builder previews

Created on 3 February 2023, over 1 year ago
Updated 20 October 2023, 8 months ago

We use Layout Builder on our project and would like the Layout Builder UI to reflect the front end rendering.

I've got this working nicely by creating:

  1. Drupal controller that renders the draft override version of the block.
  2. A matching Vue template (will create a separate PR against nuxtjs-ce-drupal to add this to the scaffolding) that just renders it using the blocks normal Vue template.
  3. Pre-processed the block so that if it is "in_preview" the block content is replaced by an iframe to the Nuxt frontend
  4. Added David Bradshaw's iframe auto height script so they appear the correct height in the Layout Builder UI

Merge request to follow.

Example attached.

πŸ“Œ Task
Status

Needs work

Version

1.0

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom Dan.Ashdown

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Dan.Ashdown
  • @danashdown opened merge request.
  • @danashdown opened merge request.
  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    very interesting!

    This seems quite straight forward. It seems to cover "only" inline-blocks with block-content. I wonder whether it would be possible to extend coverage to all kind of blocks?

    Moreover, this would miss frontend styles that apply on section / column layer, e.g. we use that support things like wide vs narrow layout rows. What do you think about our having one large iframe adding in the frontend + attaching layout-builder UI within the rendered frontend? That way we could explore leveraging vue-reactivity for showing API-driven data updates later on as well.

    We could do this by wrapping returned custom-elements for layout-builder-blocks with suiting drupal-layout-builder-ui blocks that add in the drupal JS? Potentially, we could render regular twig-components there and provide resulting markup/JS?

    We've been already discussing on how to add support for this best as well. Also, Fabian Franz has been working on it with https://www.drupal.org/project/spa_admin β†’ - I'm not sure he has it fully working with layout-builder scripts.

  • πŸ‡¬πŸ‡§United Kingdom Dan.Ashdown

    Thanks for the feedback @fago

    I've updated the MR to render other blocks. See the new screenshot showing a system block and a global content block.

    Having 1 large iframe would be better for that, also speed would improve. As you say though that would mean replicating all the LB interactivity within Vue. I.e. the drag and drop, contextual links, moving blocks between page sections etc which would need to broadcast this back to the parent frame, which would require a bunch of glue code to work with Drupal's LB JS. Personally I think that would be lovely but not an insignificant undertaking (I think this is what you mean that Franz is working on?). I think that could come later?

    We're using Tailwind so don't have the issue of needing dom hierarchy for styling but appreciate that a lot of sites will need this. What do you think about adding another URL parameter on the iframe src that allows you to add additional View templates.
    i.e. the Vue template is currently /node/_node/layout/_uuid/_.vue The _.vue currently represents the view_mode. If instead we had /node/_node/layout/_uuid/_view_mode/_.vue The _.vue would be the default, but you could add annother template e.g. /node/_node/layout/_uuid/_view_mode/sidebar.vue which contained the appropriate wrapping divs and classes etc. This could be supported by a hook in lupus_decoupled_layout_builder_preprocess_block() that allowed the template name to be set based on the block data?

    Thoughts?

  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    again, thanks for working on this!

    trying to improve issue title a bit.

    > I think that could come later?
    as discussed, agreed!

    We're using Tailwind so don't have the issue of needing dom hierarchy for styling but appreciate that a lot of sites will need this. What do you think about adding another URL parameter on the iframe src that allows you to add additional View templates.
    i.e. the Vue template is currently /node/_node/layout/_uuid/_.vue The _.vue currently represents the view_mode. If instead we had /node/_node/layout/_uuid/_view_mode/_.vue The _.vue would be the default, but you could add annother template e.g. /node/_node/layout/_uuid/_view_mode/sidebar.vue which contained the appropriate wrapping divs and classes etc. This could be supported by a hook in lupus_decoupled_layout_builder_preprocess_block() that allowed the template name to be set based on the block data?

    As discussed, this seems to be a good addition to allow for more customized previews when needed.

    I took a closer look at the PR, it looks mostly good, but needs some love around dependency-injection / service-traits and access checking. Could you take a look at this?

  • Status changed to Needs work over 1 year ago
  • πŸ‡¦πŸ‡ΉAustria fago Vienna
  • First commit to issue fork.
  • Status changed to Needs review 8 months ago
  • πŸ‡¬πŸ‡§United Kingdom Dan.Ashdown
  • Status changed to Needs work 8 months ago
  • πŸ‡¦πŸ‡ΉAustria fago Vienna

    Thank you, amazing progress!

    Please see my above remarks.

    since it might be little confusing, in regard to:
    > wondering, would it be hard to make it entity-generic? could be a follow-up, but it would make sense to document what we support then
    this is answered by your comment already, to which I replied that one:
    > I see. Let's make a setting for this features in the lupus-decoupled-drupal settings screen then? It can be on by default, but there we can also clarify it only works for nodes atm.

    So I think main thing that is left to be done here is figuring out to treat various kinds of blocks nicely via the decorator. Then we can add the setting and do more testing!

Production build 0.69.0 2024