Limit a Page Type or Area to certain Block Types
Permalink
I am looking for a Way to control what Block Types that are available to insert in a certain Page Type or Area.
A practical Example:
I have a PageType called "newsletter" that i use to let the user Create HTML Content. This Content will be processed by my Package and later sent by E-Mail.
Since there are quite a few Block Types that rely on Javascript or for other reasons wouldn't render right in a E-Mail Client i want to prevent the User from inserting them in the first place.
I've looked through the API and Permission System but couldn't find a way to achieve that.
Does anyone have an Idea on how i can get this done?
I wouldn't mind doing it programmatically and hardcode the Block Type Handles i want to disallow. My Page Type already has a custom controller and template with some stuff that's unrelated to this requirement.
A practical Example:
I have a PageType called "newsletter" that i use to let the user Create HTML Content. This Content will be processed by my Package and later sent by E-Mail.
Since there are quite a few Block Types that rely on Javascript or for other reasons wouldn't render right in a E-Mail Client i want to prevent the User from inserting them in the first place.
I've looked through the API and Permission System but couldn't find a way to achieve that.
Does anyone have an Idea on how i can get this done?
I wouldn't mind doing it programmatically and hardcode the Block Type Handles i want to disallow. My Page Type already has a custom controller and template with some stuff that's unrelated to this requirement.
If advanced permissions are enabled you can limit block types to an area by clicking on an area in edit mode and then click on permissions. This will not limit the area for the Super User (admin) but it will for the other registered users of the site.
Thanks for the quick reply!
This is basically what i want. I had suspected it would work somehow with advanced permissions. I woudn't know because of the "no advanced permissions" policy we follow for our projects.
Is there i way to set this programmatically from the page type controller or in my package installation?
Since this will be part of a package i want it to work "out of the box" without having to explain to the User: "you have to enable advanced permissions and alter the permission like this and that."
This is basically what i want. I had suspected it would work somehow with advanced permissions. I woudn't know because of the "no advanced permissions" policy we follow for our projects.
Is there i way to set this programmatically from the page type controller or in my package installation?
Since this will be part of a package i want it to work "out of the box" without having to explain to the User: "you have to enable advanced permissions and alter the permission like this and that."
I would also be interested in how to set available blocks per area, or by page type, programmatically.
Here's a partial solution working in version 8.3.2.
Add an area in the template normally, setting the block limit:
Add a controller, in my case packages/mytheme/controllers/page_types/home.php.
In the controller, use the view method add a block of your choice to the area if there isn't one already:
This puts a default block (in this case a Content block) in the target area when there are
no other blocks in the area. in edit mode, only the one block is allowed in the area. But! ... if the block is deleted in Edit mode, then a block of the user's choice can still be added.
For reference, see also https://documentation.concrete5.org/tutorials/concrete5-7-add-pageli...
Add an area in the template normally, setting the block limit:
$a = new Area('Banner Header'); $a->setAreaDisplayName('Banner Header'); $a->setBlockLimit(1); $a->display($c);
Add a controller, in my case packages/mytheme/controllers/page_types/home.php.
In the controller, use the view method add a block of your choice to the area if there isn't one already:
<?php namespace Concrete\Package\Mytheme\Controller\PageType; use Concrete\Core\Block\BlockType\BlockType; use Concrete\Core\Page\Controller\PageTypeController; use PageType; use Page; use Concrete\Core\Area\Area; class Home extends PageTypeController { public function on_start() { $this->page = \Page::getCurrentPage(); $this->pageType = PageType::getByID($this->page->getPageTypeID()); } public function view() {
Viewing 15 lines of 24 lines. View entire code block.
This puts a default block (in this case a Content block) in the target area when there are
no other blocks in the area. in edit mode, only the one block is allowed in the area. But! ... if the block is deleted in Edit mode, then a block of the user's choice can still be added.
For reference, see also https://documentation.concrete5.org/tutorials/concrete5-7-add-pageli...
By the way for anyone that's interested. I've found another, somewhat hacky method to get what i wanted:
I include a snippet of JavaScript to catch the "PanelOpen" Event and manipulate the DOM in order to hide the undesired block types like this:
I include a snippet of JavaScript to catch the "PanelOpen" Event and manipulate the DOM in order to hide the undesired block types like this:
(function($) { window.ConcreteEvent.bind('PanelOpen', function (e, data) { $('.ccm-panel-add-block-draggable-block-type').parent().hide(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="content"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="html"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="image"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="file"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="horizontal_rule"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="page_title"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="page_list"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="mesch_filter_list"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="mesch_newsletter_button"]').parent().show(); $('.ccm-panel-add-block-draggable-block-type[data-block-type-handle="mesch_spacer"]').parent().show(); });
Viewing 15 lines of 16 lines. View entire code block.
I don't prevent, but instead if block is on the wrong page, i tell the user.
my view.php looks like this
my view.php looks like this
if ( $c->getCollectionTypeHandle() <> 'my_pagetype_handle' ) { echo '<div><p>This block is useful only for pages of type <strong>MyPagetype</strong></p></div>'; } else { ... do the normal view stuff .... }