['onFormValidationProcessed', 0], 'onFormProcessed' => ['onFormProcessed', 0], ]; } /** * Server-authoritative active-trip parent injection. * * The post form no longer hardcodes `pageconfig.parent`; instead the write * target is derived from `site.active_trip` at submit time and injected into * the form data. add-page-by-form reads `$form->value()->toArray()['parent']` * (add-page-by-form.php:521) and honours it over any pageconfig/header parent. * * Fail closed: if `active_trip` is unset/empty we throw a ValidationException * so the `add_page` action never runs. Merely leaving `parent` unset is unsafe — * with `pageconfig.parent` removed, add-page-by-form's `getParentPage('')` * resolves to the /post page itself and the entry would silently land there. */ public function onFormValidationProcessed(Event $event): void { $form = $event['form']; if (!$form || $form->getName() !== 'new-entry') { return; } $activeTrip = $this->grav['config']->get('site.active_trip'); $activeTrip = is_string($activeTrip) ? trim($activeTrip) : ''; if ($activeTrip === '') { throw new ValidationException('No active trip is set — cannot post an entry. Set site.active_trip first.'); } $form->setData('parent', $this->resolveDailiesParent($activeTrip)); } /** * Normalise `active_trip` to its dailies container route. * * Accepts either a full route ("/trips/italy-2026-demo") or a bare slug * ("italy-2026-demo") and returns "/trips//dailies". */ private function resolveDailiesParent(string $activeTrip): string { $trip = trim($activeTrip, '/'); if (strpos($trip, 'trips/') !== 0) { $trip = 'trips/' . $trip; } return '/' . $trip . '/dailies'; } public function onFormProcessed(Event $event): void { $form = $event['form']; if (!$form) { return; } if ($form->getName() === 'new-entry') { $this->grav['cache']->deleteAll(); } } }