Add field to page creation modal

Hi,
Is there a way to add another field than Title, URI and Template when creating a new page?

My point is to allow to have an Author field and be able to fill Title or Author (but not always both). The URI would be the combination of the two fields or only the filled one.

Thanks in advance,
Luc

You can’t change Kirby’s default page creation modal.

It is, however, possible to create a custom add form. You can find an example for such a custom add form here: https://github.com/lukaskleinschmidt/kirby-custom-add-form/blob/master/talks.php

It overrides the default panel route for a specific page.

Thanks for your reply.
I tried to instal the plugin in a ‘talks’ folder and create a parent page called ‘talks’ but nothing append when I create sub pages. Did I miss something?

The plugin is just an example of hijacking the route, it uses the same form fields as the default modal. You would have to add the form fields you want in the form.php file and add the data to the page creation code in talks.php.

Sorry I was expecting the plugin to show something différent. It’s working perfectly!
So I added a new field. Any idea of how to create the UID from the combination of Title and the new field?

You can access the form data from the $data array.
And do something like this depending on your field key.

// route action line 26

$data  = $form->serialize();
$field = $data['field_key'];
$title = $data['title'];
$uid   = str::slug($title . '-' . $field);

$page = $parent->children()->create($uid, $data['template'], array(
  'title' => $title
));

EDIT:

Another way would be to update the uid with JavaScript. I used this in a form for team members. There are additional fields called name and surename in the add form.

The form view (template.php) looks like this:

<div class="modal-content modal-content-medium" data-slug-table="">
  <?php echo $form ?>
</div>

<script>

(function() {

  $.slug.table = <?php echo slugTable() ?>;

  var modal    = $('.modal-content');
  var title    = modal.find('[name=title]');
  var uid      = modal.find('[name=uid]');
  var surename = modal.find('[name=surename]');
  var name     = modal.find('[name=name]');

  surename.add(name).on('keyup', function() {
    var value = surename.val() + ' ' + name.val();
    uid.val($.slug(value));
    title.val(value);
  });

  uid.on('blur', function() {
    uid.val($.slug(uid.val()));
  });

})();

</script>

I have been with the JavaScript solution and it works nicely.
Thanks a lot!

How could I trigger it for all pages with a particular template?
At the moment it’s only for sub-pages of a named page.

if(!function_exists('panel')) return;
panel()->routes(array(
  array(
    'pattern' => 'pages/curator/add',
    'action'  => function() {
      $controller = new Kirby\Panel\Controllers\Base();
      $parent     = panel()->page('curator');
      if($parent->ui()->create() === false) {
        throw new PermissionsException();
      }

Guess you could fetch a collection of all parent pages with this template and use these in your pattern.

Edit: Like this:

<?php

if(!function_exists('panel')) return;
$slugs = panel()->site()->pages()->filterBy('intendedTemplate', 'whatever')->pluck('slug');

panel()->routes(array(
  array(

    'pattern' => 'pages/(' . implode('|', $slugs) .')/add',
    'action'  => function($slug){

      $controller = new Kirby\Panel\Controllers\Base();
      $parent     = panel()->page($slug);

      // rest of code

I fiddled a bit and it seems that you can to something like this.

<?php

if(!function_exists('panel')) return;

panel()->routes(array(
  array(
    'pattern' => 'pages/(:any)/add',
    'action'  => function($id) {
      $panel  = panel();
      $parent = $panel->page($id);

      // call the default controller
      if($parent->intendedTemplate() !== '[your-page-template]') {
        require_once $panel->roots()->controllers() . DS . 'pages.php';
        $controller = new PagesController();
        return $controller->add($id);
      }

      $controller = new Kirby\Panel\Controllers\Base();

      if($parent->ui()->create() === false) {
        throw new PermissionsException();
      }

      $form = $panel->form(__DIR__ . DS . 'form.php', $parent, function($form) use($parent, $controller) {
        try {

          $form->validate();

          if(!$form->isValid()) {
            throw new Exception(l('pages.add.error.template'));
          }

          $data = $form->serialize();
          $page = $parent->children()->create($data['uid'], $data['template'], array(
            'title' => $data['title']
          ));

          $controller->notify(':)');
          $controller->redirect($page, 'edit');

        } catch(Exception $e) {
          $form->alert($e->getMessage());
        }
      });

      $content = tpl::load(__DIR__ . DS . 'template.php', compact('form'));

      return $controller->layout('app', compact('content'));
    },
    'filter' => 'auth',
    'method' => 'POST|GET',
  )
));

Texnixe solution is working fine.
I can’t make Luka solution work. I should miss something.
Thanks a lot to both of you.