gebeer Posted 12 hours ago Posted 12 hours ago 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? 2 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now