Jump to content

Recommended Posts

Posted

How small things can make life easier for your site editors

One small (but big) thing we wanted on a recent RPB build: editors should only see the blocks that make sense for the page template they are editing. Project pages get the ~10 project blocks, landing pages get their own set, and nobody has to do per-page fiddling or choose from 25 blocks where they only need 10. 
Repeater Matrix makes this possible via per-template field overrides. RPB needs a little custom nudging here, but that can be pretty straightforward as you will see. 

The nice bit: RPB already has exactly the right hook point. RockPageBuilder::___getAllowedBlocks($field, $page) returns a BlocksArray, so we hook after it in our site/modules/Site.module.php and remove anything that is not in the template's allow-list. This runs with priority 1000, so RPB's own populate hooks have already done their thing.

Shape of that hook:

public function ready(): void
{
  $this->addHookAfter(
    'RockPageBuilder::getAllowedBlocks',
    $this,
    'filterRockPageBuilderBlocksByTemplate',
    ['priority' => 1000]
  );
}

public function filterRockPageBuilderBlocksByTemplate(HookEvent $event): void
{
  $page = $event->arguments(1);

  $allowed = $page->template->get('rpb_blocks_allowed');
  if (!is_array($allowed) || !$allowed) return;

  $allowed = array_flip($allowed);
  $blocks = $event->return;

  foreach ($blocks as $block) {
    if (!isset($allowed[$block->className()])) {
      $blocks->remove($block);
    }
  }

  $event->return = $blocks;
}

Allow-list implementation (the really smart bit)

The allow-list lives on the template itself as a custom property called rpb_blocks_allowed, stored in the templates.data JSON column. Yes, templates support meta data just not exactly like pages. There's no public $template->meta() API. PW is cool nonetheless! 
We set that data declaratively in the template's migration file (config migrations to the rescue). RM picks that up and applies it via `setTemplateData()`. No new field needed, because a field would be per-page data, and that is the wrong tool here. At runtime it is just $page->template->get('rpb_blocks_allowed'). Templates without a list keep the full block palette and are completely unaffected.

What that looks like in the template's migration file:

// site/RockMigrations/templates/project.php
return [
  'fields' => [
    'title' => [],
    // ... the template's normal fields ...
    'rockpagebuilder_blocks' => [],
  ],

  // RPB block allow-list for this template, stored as a custom property
  // in templates.data and read by the getAllowedBlocks hook.
  'rpb_blocks_allowed' => [
    'ProjektHeader', 'TextIntro', 'ImmobilienUeberblick', 'ImageModul', 'Video',
    'BildText', 'Zitat', 'Awards', 'FAQList', 'NewsTeaser',
  ],
];

This also turned out to be nicer than expected: it is enforced in the editor add-menu and for API/programmatic block creation, it still composes with every block's existing info()['show'] selector, all template config stays in one clean migration, and there are zero core edits for RPB updates to clobber.

Tiny gotcha we proved along the way: Template::meta() does not exist. Page has meta(), Template does not. That is exactly why templates.data plus a custom template property is such a neat fit here.

Big thanks to @bernhard for making RPB so hookable. And @ryan for baking in meta data support into the Template class. This is one of those ProcessWire-ish solutions where the final code is boring in the best possible way: hook the right method, keep the config where it belongs, and let the rest of the system keep doing its thing.

Happy blocking!

BTW: RockPageBuilder is awesome and free on github: https://github.com/baumrock/RockPageBuilder. So what are you waiting for?

  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...