Hi all!
Iām building a site where the client will be able to create Landing Pages at will. Each Landing Page is made up of:
- a Hero Banner section
- (optional) Information Sections
- a Contact Section
So, the Hero and the Contact sections are compulsory: every page must have one. The Information Sections are optional, and the client may create a Landing page with none, and another with several. Iāve set this up as a āone-pagerā: the Landing Page is the parent, and the sections are child pages.
As suggested by @texnixe in another post, I followed the migration docs - āRemove Blueprint-based subpage builderā section - to create a page.create:after
hook, so the Landing Page auto-creates the Hero Banner and the Contact Section when itās created. But, Iām finding that this solution has a couple of issues Iām not being able to work through.
First, Iād like these sections to always show up in the parent page with a ālistedā status. The hook is supposed to automatically add a sorting num on the pages when it creates them, but it can only do that IF the pages have changeStatus
set to true. This means, unfortunately, that the user will be able to change the status as well, which I donāt want to allow.
Second, I also donāt want to allow the user to delete these 2 sections - they should always be present on the Landing Page. So, I set the delete:
option in their blueprints to false. This, however, stops the parent Landing Page from being deleted altogether, because when it tries to delete its children, it canāt, and so the whole delete operation fails. Iāve tried setting up a page.delete:before
hook, but cannot seem to be able to delete the subpages programatically while their delete
is set to false - even if trying to force-delete using $page->delete(true)
.
What is the proper way to do this? Is there a way to override these page options programatically? Any guidance is most welcome.
I think there is no way to do things programmatically if the blueprint options are set. However, instead of using blueprint options, you could set the correspondingpage.delete.before
and page.changeStatus.before
hooks to prevent those actions. The downside is that these options are then not disabled in the interface, but probably better than nothing.
Iām trying to find a workaround - donāt want to give upā¦ I thought that maybe I could try getting the result I want by swapping templates in the page.create:after
hook.
I started by creating an empty ātemp.ymlā template:
title: Temporary Template
Then, in the page.create hook I do this:
- create the subpage using the ātempā template (which has no option constrains), and
- once the subpage is created and the sort number added, use
changeTemplate()
, to apply a template that has the options with the restrictions I want.
The config.php code looks like this:
<?php
return [
'hooks' => [
'page.create:after' => function ($page) {
$builder = $page->blueprint()->autobuild();
if(!empty($builder)) {
foreach($builder as $build) {
$missing = a::missing($build, array('title', 'template', 'uid'));
if(!empty($missing)) continue;
try {
$subPage = $page->createChild([
'content' => ['title' => $build['title']],
'slug' => $build['uid'],
'template' => 'temp' // use template with no restrictions
]);
} catch (Exception $error) {
throw new Exception($error);
}
if($subPage) {
$subPage->publish();
if(isset($build['num'])) $subPage->sort($build['num']);
// apply correct template:
$subPage->changeTemplate($build['template']);
}
}
}
}
]
];
What happens, however, is very strange: the child page for the Hero Banner is created, but then it cannot change the template, and an error quickly flashes on the screen:
So, I tried to alter my ātemp.ymlā template, like this:
title: Temporary Template
options:
changeTemplate: true
And then, I get this error:
In both cases, the Hero Banner subpage does get created with the ātempā content file, but the hook is unable to changeTemplate().
Should I give up, or am I close?..