Nest files section inside file template

Hi!

Is it possible to have an image section within a file template?
I’m trying the following: if a video file is uploaded, the user should be able to upload a poster image.

My “outer” blueprint (note: although I named it “images”, it’s actually a images and video file section):

images:
  type: files
  headline: Bilder/Video
  layout: cards
  size: small
  template: image

My image blueprint/template:

posterimage:
type: files
headline: Poster Bild
layout: cards
max: 1

My template code:


It’s actually outputting the url of the poster image file, but only the folder and filename + extension. Unfortunately it’s omitting the first part of the url. Here it’s outputting: “- home/example.jpg”.

Do I have to delete the minus and add the first part of the url manualy, or am I missing something?

Thanks!

You have to make it a file object:

<?php if ($file->images()->toFile()): ?>
<!-- code -->
<?php endif ?>
1 Like

Lol, thanks :smiley:

Old thread, but I am trying to do the exact same thing, also to add an poster image to a video. However, the “inner” fields section somehow does not let me add a new image and gives me the error bla.jpg The object "field" cannot be resolved.

My outer file template is:

# blueprints/files/media.yml

title: Media

accept:
  mime: image/*, video/*
  maxsize: 80000000 # size in byte = 80 MB

columns:
  - width: 1/2
    sections:
      posterimage:
        type: files
        headline: Poster Image
        layout: cards
        template: poster
        max: 1

and then my poster template that I want to use inside:

# blueprints/files/poster.yml

title: Poster

accept:
  mime: image/*

Any idea, what is going wrong here?

Thank you!

20200720-152325_Screenshot_GoogleChrome

Is there any more information in the browser console?

You are using a section instead of a field, maybe that’s causing the issue.

Hi @pixelijn, thanks for looking into this. Yes, turns out there is a message in the browser console, however I cannot make much sense of it:

app.js:1 POST http://bla.test/api/pages/bla+something/files/theparentvideofile.mp4/files 400 (Bad Request)

Looks like it tries to access the files of the parent file, which does not make much sense of course. Is there any way to ‘redirect’ this section to the parent page instead? I actually need a section I think, because I want to have the ability to delete the image again amongst other things.

Hm, but somehow that doesn’t make sense, because a file cannot be a parent of other files. So I think you have to use a files field.

If you look at the API, you will see that there is no such route as in your error message.

I am still struggling with how and why files sections and files fields are different. Could you then please advice me, how I could allow for a fields field that

A) does not allow to open the “pick files” dialog, but only to upload them and
B) deletes the file once I remove them from the field, instead of leaving them in the contents folder?

Thank you.

That’s not possible, because a files field is basically a select field and as such, a field without a select option is pretty useless. The purpose of a field is to store something in the content file.

B could be achieved via a hook.

Well, it still would have the upload option, wouldn’t it? For uses like that, it would be great if the “pick” option could be turned off to only leave the upload option in place.

But yes, my issue is basically that I need to associate one file with another file and the best for that would be a files section, but apparently that is not possible …

Even if you could use a files section, there would be no connection between your file and the file uploaded via the section at all. Because, where would this file be stored? In the page folder along with all other files. That’s why you have to store this connection in the file meta data content file and therefore you need a field, not a section. And therefore you need the pick option.

I still don’t understand this part. As long as the files field comes with an upload option, why would I (in my case) need a pick option? I would be perfectly happy if I could just upload a single file, that file gets assigned a certain template and automatically becomes a child of the parent page (as it currently already happens with the upload option) and is placed into that field. So for my scenario, I don’t need a file picker (the one that selects between already uploaded files at all). Therefore it would be good, if this could be turned off somehow.

Maybe you can hide the option via custom styles.

Was thinking about something like that. But as the field currently works, it would be best for me to both get rid of popup that appears on Hinzufügen (add?), as well as somehow associate the event listener that triggers the file upload with both the Hinzufügen button as well as the empty field area. Hm, I will look around if I can find a way to switch these event listeners.

20200721-102455_Screenshot_GoogleChrome

Hm, the event listeners and such are all kind of deeply embedded into the vue framework, so I cannot for the life of me figure out, how to transfer them from one element to the other. :disappointed:

I don’t know what you tried to do, but imo you need a custom files field.

How would I go about this hook that would delete the file once I remove it from the files field? I thought it might work like this, but it does not delete the file:

    'file.update.after' => function ($newFile, $oldFile) {

      if($oldFile->type() == "video" &&
         $oldFile->template == "media" &&
         $oldFile->poster()->isNotEmpty()) {
        $oldFile->poster()->toFile()->delete();
      }
    },

There is an error in this line: missing () after template

Thanks, but even after adding the (), it still does not work. :disappointed_relieved:

The line $oldFile->poster()->toFile()->delete(); is generally correct? Or am I doing something wrong there?

The general rule applies to first check if this bit $oldFile->poster()->toFile() gives you a file, before trying to delete it.