Frontent Page Creation: Save User to created page

How can I save the current user to a created page?

Description

  1. user is logged in
  2. user goes to /projekte/einreichen
  3. fills in form and submits it
  4. project (page) is created (draft)

My goal
I would like to save the user to the created page.

Found out
If I change the “author” field in the blueprint to type: users, the value is also not saved when creating the page. If I make the type: text, the hash is stored by the user but in the backend I don’t get an assignment. There is only the hash in the text field.

Form

Created page

Backend

templates/add-project.php

<?php snippet('header') ?>

<?php if(isset($alert)): ?>
  <?php foreach($alert as $a): ?>
  <?= $a ?>
  <?php endforeach ?>
<?php endif ?>

<main class="max-w-xl mx-auto px-4 mt-12" role="main">
  <h1 class="text-3xl sm:text-4xl font-black font-display leading-snug">Projekt einreichen</h1>
  
  <form action="<?= $page->url() ?>" method="POST">
    <h2 class="text-2xl font-display font-bold mt-12">Allgemeine Informationen</h2>

    <div class="mt-4">
      <label for="title">Name des Projektes</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="title" name="title" value="<?= $data['title'] ?? null ?>"/>
    </div>

    <div class="mt-4">
      <label for="text">Beschreibung</label>
      <textarea class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="text" name="text" value="<?= $data['text'] ?? null ?>"></textarea>
    </div>

    <div class="mt-4">
      <label for="problems">Welche Probleme gab es?</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="problems" name="problems" value="<?= $data['problems'] ?? null ?>"/>
    </div>

    <div class="mt-4">
      <label for="place">Ort</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="place" name="place" value="<?= $data['place'] ?? null ?>"/>
    </div>
    
    <div class="mt-4">
      <label for="website">Webseite</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="website" name="website" value="<?= $data['website'] ?? null ?>"/>
    </div>

    <div class="mt-4">
      <label for="state">Bundesland</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="state" name="state" value="<?= $data['state'] ?? null ?>"/>
    </div>

    <div class="mt-4">
      <label for="tipp">Hast du einen Tipp?</label>
      <textarea class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="tipp" name="tipp" id="tipp" value="<?= $data['tipp'] ?? null ?>"></textarea>
    </div>

    <h2 class="text-2xl font-display font-bold mt-12">Finanzierung</h2>

    <div class="mt-4">
      <label for="financeneeds">Bilder</label>
      <input type="file" multiple />
    </div>

    <h2 class="text-2xl font-display font-bold mt-12">Finanzierung</h2>

    <div class="mt-4">
      <label for="financeneeds">Finanzierungsbedarf</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="financeneeds" name="financeneeds" value="<?= $data['financeneeds'] ?? null ?>"/>
    </div>

    <div class="mt-4">
      <label for="financetext">Wie wurde das Projekt finanziert?</label>
      <textarea class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="financetext" name="financetext" id="finance" value="<?= $data['financetext'] ?? null ?>"></textarea>
    </div>

    <h2 class="text-2xl font-display font-bold mt-12">Informationen über den Initiator</h2>

    <div class="mt-4">
      <label for="initiatorname">Name</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="initiatorname" name="initiatorname" value="<?= $kirby->user()->name() ?>"/>
    </div>

    <div class="mt-4">
      <label for="initiatormail">E-Mail Adresse als Kontakt</label>
      <input class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="text" id="initiatormail" name="initiatormail" value="<?= $kirby->user()->email() ?>"/>
    </div>

    <div class="mt-4">
      <label for="initiatortext">Beschreibung</label>
      <textarea class="py-2 px-4 border-2 block rounded-lg w-full mt-1 focus:border-primary-600 focus:outline-none focus:ring-4 focus:ring-primary-100" type="initiatortext" name="initiatortext" id="initiatortext" value="<?= $kirby->user()->description() ?>"></textarea>
    </div>



    <input class="w-full mt-4 block font-bold px-5 py-2 border border-primary-base hover:border-primary-700 text-center rounded-lg bg-primary-base hover:bg-primary-700 appearance-none text-white transition-all duration-200 ease-linear" type="submit" name="register" value="Projekt einreichen" />

  </form>
</main>

<?php snippet('footer') ?>

controllers/add-project.php

<?php

return function ($kirby, $page) {

    // if the form has been submitted…
    if ($kirby->request()->is('POST') && get('register')) {

        // check the honeypot and exit if is has been filled in
        if(empty(get('website')) === false) {
            go($page->url());
            exit;
        }

        $data = [
            'title' => get('title'),
            'text' => get('text'),
            'problems' => get('problems'),
            'tipp' => get('tipp'),
            'place' => get('place'),
            'website' => get('website'),
            'author' => $kirby->user()
        ];

        $rules = [
            'title'  => ['required'],
            'text' => ['required'],
        ];

        $messages = [
            'title'  => 'Please enter your (link: #title text: title)',
            'text' => 'Please enter a valid (link: #email text: email address)',
        ];

        // some of the data is invalid
        if ($invalid = invalid($data, $rules, $messages)) {
            $alert = $invalid;

        } else {

            // authenticate as almighty
            $kirby->impersonate('kirby');

            // everything is ok, let's try to create a new registration
            try {
                // we store registrations as subpages of the current page
                $project = page('projekte')->createChild([
                    'slug'     => md5(str::slug($data['title'] . microtime())),
                    'template' => 'projekt',
                    'content'  => $data
                ]);

                $project->changeStatus('unlisted');
                $project->update([
                    'author' => $kirby->user()
                ]);

                if ($project) {
                    // store referer and name in session
                    $kirby->session()->set([
                        'referer' => $page->uri(),
                        'regName'  => esc($data['title'])
                    ]);
                    go('projekte/success');
                }

            } catch (Exception $e) {
                $alert = ['Your registration failed: ' . $e->getMessage()];
            }
        }
    }

    // return data to template
    return [
        'alert' => $alert ?? null,
        'data'  => $data ?? false,
    ];
};

blueprints/pages/projekt.yml

title: Projekt
num: date
icon: 📖
status:
  draft:
    label: Draft
    text: The note is still in draft mode. It can only be seen by editors with panel access.
  unlisted:
    label: In Review
    text: The note is online and can be visited with the direct URL. The team must still give the final go to publish it.
  listed:
    label: Published
    text: The note is online and listed in the blog
tabs:
  content:
    label: content
    icon: text
    columns:
      - width: 2/3
        fields:
          author:
            label: Author
            type: users
          seoHeadline:
            label: SEO
            type: headline
          metaTitle:
            label: Meta Title
            type: text
          metadescription:
            label: Meta Beschreibung
            type: text
          projectdetailsHeadline:
            label: Details zum Projekt
            type: headline
          columnsize:
            label: Größe der Zelle
            type: select
            options:
              large: large
              small: small
          text:
            label: Beschreibung
            type: textarea
            size: large
          tipp:
            label: Tipp
            type: textarea
          problems:
            label: Probleme
            type: structure
            fields:
              problem: 
                label: Problem
                type: text
          map:
            label: Karte
            type: locator
            language: de
          place: 
            label: Ort
            type: text
            size: small
          state:
            label: Bundesland
            type: select
            options: 
              Niedersachsen: Niedersachsen
              Nordrhein-Westfalen: Nordrhein-Westfalen
              Thüringen: Thüringen
              Bayern: Bayern
              Hessen: Hessen
              Berlin: Berlin
              Hamburg: Hamburg
              Bremen: Bremen
              Sachsen: Sachsen
              Sachsen-Anhalt: Sachsen-Anhalt
              Saarland: Saarland
              Brandenburg: Brandenburg
              Mecklenburg-Vorpommern: Mecklenburg-Vorpommern
              Schleswig-Holstein: Schleswig-Holstein
              Rheinland-Pfalz: Rheinland-Pfalz
              Baden-Württemberg: Baden-Württemberg
          website:
            label: Website
            type: url
          financeheadline:
            label: Finanzierung
            type: headline
          financeneeds:
            label: Finanzierungsbedarf
            type: text
          financetext:
            label: Text zur Finanzierung
            type: textarea
          finance:
            label: Finanzierungsbausteine
            type: structure
            fields:
              type:
                label: Art der Finanzierung
                type: text
              sum:
                label: Summe
                type: text
          initiatorheadline:
            label: Initiator
            type: headline
          initiatorAvatar:
            label: Profilbild
            type: files
            multiple: false
            query: page.images
          initiatorName:
            label: Name
            type: text
          initiatorMail:
            label: E-Mail
            type: email
          initiatorText:
            label: Text
            type: textarea

      - width: 1/3
        sections:
          meta:
            type: fields
            fields:
              gallery:
                label: Galerie
                type: files
                multiple: true
                query: page.images
  test:
    label: Bilder
    icon: text
    sections:
      gallery:
        headline: Alle Bilder
        type: files
        layout: cards

Data in a users field has to be stored yaml encoded, and also you cannot pass the object as value but need the user id

 'author' => Data::encode($kirby->user()->id(), 'yaml'),

You should check for an existing user though, before calling id()

If I take your code, the value is still not saved to the page - in the blueprint the type users is defined. If I change it, it at least saves the value, but doesn’t show me the author.

fields:
          author:
            label: Author
            type: users

The users field stores the id (which is the folder name in the accounts folder), not the author name…

Sorry if I misunderstand. I am looking for a solution not an explanation of how the data is stored. So what do I need to do to solve my problem: not only store the user as an ID in the form of a string, but have it visible in the panel on the side?

What does get stored in the author field in the content file if you use the code I suggested above?

It is always kirby:

Change from textfield to users field:

Sorry for the trouble. I have found the error. I have updated the user or the page again below and thus created the page twice. On one it has now saved the user correctly. Your solution was correct!

I removed this:

$project->changeStatus('unlisted');
    $project->update([
        'author' => $kirby->user()
    ]);

I have updated my code and would like to write the PageID to the user. I would later show all the projects the user has created in the profile.

$kirby->user()->update([
    'projects' => 'test'
]);

When I write this code in the controller, I get on the form page: “The Kirby user cannot be changed”.

Does anybody have an idea?

If you want to update etc. stuff from the frontend, you need to authenticate

When you take a look on my code above you can see I use the $kirby->impersonate(). Because of this I am not sure how to handle it.

Ok, the context is never quite clear in such a long thread…

What sort of a field do you want to update?