Not allowed to change file template through $file->changeTemplate() but through $file->update(['template' =>...])

Hi,

I’ve been following this forum for quite a while now and it’s been super helpful to me. Thanks a bunch to all of the contributors and especially TexNixe.

I am working on migrating content and as part of that I need to change the template of some files from ‘default’ to ‘protected’.

Attempting to do that by using $file->changeTemplate(‘protected’) results in an error “You are not allowed to change the template for the file …”

When I change the code to $file->update([‘template’] => ‘protected’) it works.
Here’s the code snippet:

<h1>Bulkupdate</h1>

<ol>
    <?php
    $profiles = page()->children();
    foreach($profiles as $profile)
    {
        echo "<li>". $profile->name();

        kirby()->impersonate('kirby');

        $files = $profile->files();
        foreach($files as $file)
        {
            echo $file->name() . ", ";

            try
            {
                $newfile = $file->update(['template' => 'protected']); // this works
                //$newfile = $file->changeTemplate('protected'); // this results in a permission error
                echo "template = ". $newfile->template();
            }
            catch(Exception $e)
            {
                echo ", ". $e->getMessage();
            }
        }

        echo "</li>";
    }
    ?>
</ol>

The initial template of the files is “default”. I tried adding a “changeTemplate” option to the default template but that didn’t help. I also noticed that though I am using an admin user in the panel, I am not allowed to change the template through the panel. The “Change template” option is grayed-out. Changing a file back from “protected” to default" through the panel and $file->changeTemplate() works though. I am on Kirby 4.6.1.

Could this be a defect or am I just not seeing my mistake?

Best, Jens

The file template changing is a bit complicated, this is what the docs say:

You can change the file template currently assigned to a file to any template that is available for files in the file parent (sections, fields, textareas)

That means that the new template you want to change to must be assigned to some item in the file parent blueprint (page, user…)

Hi Sonja,

Thank you for your swift response.

I do have a corresponding file blueprint called “protected.yml”.

If my understanding is correct, you’re saying the blueprint must be in use by another item. I had that too (I manually assigned it in the txt.file of a file on the server), however, I wasn’t allowed to change the other files to the same assigned blueprint.

Looking into the code I can see that file->changeTemplate() uses file->update() internally. My programming skills are a little rusty so I struggle to understand everything that’s going on in changeTemplate function that would not allow me to change the blueprint while the internally used update() function works.

Best,

Jens

It doesn’t help if you manually assign it to some item. I needs to be defined in a files section/files field/textarea field with allowed update in a page blueprint. That’s what Kirby checks, not the complete content folder text files.

And yes, internally $file->changeTemplate() uses $file->update() but it also does a lot of other things, like checking permissions and checking if the template can be used ($file->rules())…

Thank you Sonja,

It’s a bit complicated indeed - at least for me :wink:

I think I have a better understanding now:

The permission whether to change a file template is handled in protected.yml. That’s similar to page template permissions. At least in my case that alone wasn’t enough in order to change the template of a file to “protected” through the panel.

Only after I added a file section with

template: protected

to the page blueprint I was allowed to change the template of the files to protected. I guess this is to make sure one doesn’t lose files by changing them to templates that aren’t shown.

I can set file permissions to

changeTemplate: true

but I cannot constrain the allowed templates by doing something like

`changeTemplate:

  • allowedtemplate1
  • allowedtemplate2`

Thanks for your help again!