[Uniform] Prefix filename with data from form

I’m trying to add a dynamic prefix to uploaded files:

            $form->emailAction([
                'to' => esc(page('kontakt')->kontaktFormularEmail()),
                'from' => 'form@website.de',
                'subject' => 'Kontaktformular Nachricht von {{name}}',
                'template' => 'email'
            ])
            ->uploadAction(['fields' => [
                'filefield' => [
                    'target' => './content/storage/',
                    'prefix' => '{{name}}',
                ],
            ]]);

'{{name}}' works for the 'subject', but not as a 'prefix' (just adds {{name}} to the filename). Is there a way to do this? I also noticed the $filefield array doesn’t contain the prefixed name for when 'prefix' => true so there is no way of passing this to my email template.
Thanks!

I don’t know what the expected syntax is, but you can always fetch the field content with get('name'), so I’d try that.

1 Like

That worked (of course it did!). Thanks for the quick reply as ever, and on a Saturday too!

Uniform documents ‘subject’ like this:

The subject supports templates, too, so you can dynamically add form data to it. A template is a name of a form field surrounded by {{}} .

I guess curly bracket syntax is only available for ‘subject’.

It would make sense to slugify the user input: Str::slug(get('name')).

Good idea! What’s the best way to add an ‘_’ after the variable? Something like 'prefix' => Str::slug(get('name') . '_'), but that actually works?

Str::slug(get('name')) . '_'
1 Like

Is there a way I can sluggify the whole filename, not just the prefix? I’m having an issue linking to files with whitespace, but I don’t see a way to rename an uploaded file in the Uniform documentation.

No, looking at the source code, there is no option to change the filename.

What you could do is to copy the upload action and make it a custom action. Then inside the copied code, slugify the filename.

You can find the original upload action here: https://github.com/mzur/kirby-uniform/blob/master/src/Actions/UploadAction.php

I’ve changed the action to this (as I’m always using a prefix it seemed the best place to do it):

    if (is_null($prefix)) {
        $name = $this->getRandomPrefix($name);
    } elseif ($prefix !== false) {
        $name = Str::slug($prefix.$name);
    }

The form is submitting but not uploading the file. I’m using the JS from the AJAX example (https://kirby-uniform.readthedocs.io/en/latest/examples/ajax/), so maybe there’s an issue here? I’m getting this error:

Uncaught TypeError: CreateListFromArrayLike called on non-object

My guess is that Javascript has a different filename because it gets it from the field rather than the renamed version for upload…?

Did it work before you changed those lines? Where did you make those changes? In the source code or in a custom action?

I duplicated the default uploadAction and renamed it to uploadRenameAction with no changes just to test. Storing it in site/plugins/uniform-actions.php as the documentation suggests. With no changes, I am getting that Javascript error, so I guess using AJAX is complicating matters.

Looks like the documentation is outdated here.

Kirby plugins must live in their own folder in an index.php. A random file in the plugins folder won’t be loaded.

Ah, ok. I got it working as a custom action in a plugin with no changes.

I’ve tried this: $name = Str::slug($file['name']); but I’m getting Uncaught TypeError here in the JS:

        for (var key in response) {
          if (!response.hasOwnProperty(key)) continue;
          if (fields.hasOwnProperty(key))
            fields[key].classList.add("error");
          Array.prototype.push.apply(errors, response[key]); //Error here
        }

I feel a bit out of my depth with this form, so thank you so much for your help!

Where are you using this? In the custom action? That wouldn’t make sense unless you defined $file before.

I’m not familiar with using Ajax in conjunction with Uniform, so please try the standard way first, so we can find out what is the issue here.