1

I often use multiple Entry Types in a Structure so that the 'Landing page' and 'Entries' are in the same place in the admin for the site editor... e.g.

  • L1 Landing Page (header image, introduction etc) = entryType1
    • L2 Entry = entryType2
    • L2 Entry = entryType2
    • L2 Entry = entryType2
    • L2 Entry = entryType2
    • L2 Entry = entryType2

...etc...

I then set entryType2 (regular entry) as default as this is likely the one most often used by the editor and helps prevent confusion.

However, when an entry (entryType2) is saved it automatically defaults to Level 1 in the Structure and then needs to be manually 'dragged' into the Level 2 position. Editors always forget this step and then wonder why their post is not showing on the front end.

So... my question... Is there a better way to do this that I am missing? Is there a plugin which could help?

I think the ideal scenario would be an option in the CP when creating an Entry Type to choose which Level the Entry Type should be associated with.

I hope that makes sense?

Many thanks

2 Answers 2

1

I don't know of a plugin that could help here.

Here's what I could find in the Craft codebase:

  • The position of a new entry in a structure section is controlled by 3 query params when clicking the "Create" button: parentId, before or after. These params are used to either set the parent with $entry->setParentId(...) or Craft::$app->getStructures()->moveBefore(...) or ...->moveAfter(...). See EntriesController.php:128 and EntriesController.php:186.

    • If you could manage to manipulate one of those query params you could control the position of the new entry.
  • Another way could be using events: There is the EVENT_BEFORE_SAVE_ELEMENT event which you could use to override the parent ID of the new entry that is about to be saved. You'd have to create a small module and register a new event handler that takes care of that.

(Anyways, Craft must know the exact parent entry of the level 1 entry. How would you decide that? Would you take the first level 1 entry in the structure?)

1

In my opinion, the best (and simplest) approach to this problem is to use a custom validation rule to prevent authors from creating (i.e. publishing) entries using the wrong entry type at the wrong level.

Adding a custom validation rule is relatively straight-forward, but requires a (private) plugin (Craft 4.4+ only) or a custom Yii module. For this use case, a module will suffice and would be my recommendation – but assuming you're running Craft 4.3.5 or later, scaffolding either one is quite easy using the official Craft Generator package._

Here's how you could add a custom validation rule that would prevent authors from creating entryType2 entries at the root level of the structure, and entryType1 entries below the root level (this should be added to your module or plugin's init() method:

use craft\elements\Entry;
use craft\events\DefineRulesEvent;
use yii\base\Event;

Event::on(
    Entry::class,
    Entry::EVENT_DEFINE_RULES,
    function(DefineRulesEvent $event) {
        /** @var Entry $entry */
        $entry = $event->sender;

        if ($entry->getSection()->handle != 'structureSectionHandle') {
            return;
        }

        $event->rules[] = ['typeId', function () use ($entry) {
            if ($entry->getType()->handle === 'entryType2' && $entry->level === 1) {
                // Prevent entries with the entry type "entryType2" from being created at level 1 in the structure
                $entry->addError('typeId', Craft::t('site', 'Entry type 2 entries must have a parent entry. Select a parent entry in the "Parent" field below.'));
            } else if ($entry->getType()->handle === 'entryType1' && $entry->level > 1) {
                // Prevent entries with the entry type "entryType1" from being created as a child entry (i.e. below level 1 in the structure
                $entry->addError('typeId', Craft::t('site', 'Entry type 1 entries cannot have a parent. Remove the parent entry in the "Parent" field below.'));
            }
        }, 'on' => Entry::SCENARIO_LIVE];
    }
);

With the above validation rule, any entryType2 entries without a parent, or entryType1 entries with a parent, will fail validation and cannot be created as a live entry (they can be saved as drafts, though).

enter image description here

Note: If the validation error doesn't display, make sure your Craft install is upgraded to 4.4.9 or later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.