Auto-populate static page field

Hi! How can I automatically populate the “uid” field in a static page using the RainLab Static Pages plugin before the page is saved, but only if the field is empty? The field is located inside a repeater.

For regular models, I would use the beforeSave method, but since static pages are file-based rather than database models, what is the correct way to achieve this behavior?

This is kinda hacky… but… static pages use the Halcyon (file-based) model, but they still support the same lifecycle events as database models. The RainLab\Pages\Classes\Page class already uses beforeCreate and beforeValidate, so the pattern is the same.

The recommended approach is to listen for the beforeSave event on the Page model from a plugin’s boot() method. The viewBag holds the custom fields (including repeater data), so you’d iterate the repeater items and populate any empty uid values there.

// In your Plugin.php boot() method
\RainLab\Pages\Classes\Page::extend(function ($page) {
    $page->bindEvent('model.beforeSave', function () use ($page) {
        $viewBag = $page->getViewBag();
        $items = $viewBag->property('my_repeater') ?: [];

        $modified = false;
        foreach ($items as &$item) {
            if (empty($item['uid'])) {
                $item['uid'] = str_random(8); // or Str::uuid(), etc.
                $modified = true;
            }
        }

        if ($modified) {
            $viewBag->setProperty('my_repeater', $items);
            $page->fillViewBagArray();
        }
    });
});

The key points:

  • Static pages are Halcyon models, but they fire the same beforeSave/afterSave lifecycle events as database models
  • Custom field values (including repeater data) live in the viewBag — access them via $page->getViewBag()->property('field_name')
  • After modifying viewBag properties, call $page->fillViewBagArray() to sync the changes back to the model attributes before save
1 Like