Rename images on upload

In the panel, it would be convenient for me to have the images automatically renaming themselves matching the page title on upload.

For example:

My page title is: product-title

I upload 3 images by dragging them on the page view in the panel.

They automatically get renamed to:
product-title-01.jpg
product-title-02.jpg
product-title-03.jpg

I then upload 2 images more. They get renamed to:
product-title-04.jpg
product-title-05.jpg

Can I have some hints on how to achieve it?

First of all, yes, you can do that with a panel.file.upload hook, the problem is the numbering of the images. Since images can be added and deleted, you cannot rely on the number of images in the folder to number your images correctly. So you would have to get the numbering string from each of the filenames, get the highest number and then add 1. To make it easier, I would probably put the number in front of the title.

Thank you, it worked!

I may update the code later to account for more edge cases, but for now it solves my need.

This is the code I ended up using:

kirby()->hook('panel.file.upload', function($file) {
    $page = $file->page();
    $title = $page->title();
    $count = 0;
    try {
        $count = $page->images()->count();
        $count++;
        // Add 0 before $count so that it is two digits
        $count = str_pad($count, 2, '0', STR_PAD_LEFT);
        $filename = $title . "-" . $count;
        $file->rename($filename);
        echo 'The file has been renamed';
    } catch(Exception $e) {
        echo 'The file has been renamed';
        // optional reason: echo $e->getMessage();
    }
});

Yes, but as I said above, this is unreliable and the hook will fail silently, if an image name already exists.

Example: There are three images in the folder: image-01,image-02, image-03. $count+1 will then be 4, and the next uploaded image will be renamed image-04. All is fine.

Now, someone deletes an image. $count+1 will again be 4; since image-04 already exists, renaming fails silently, the image will not be renamed. The user will not get a message and has to check in the sidebar, if the image was renamed successfully, and if not, rename the image manually.

I did add the following Hook too, so that it automatically rename all the files on page-update:

// Rename and sanitize file names on panel save
kirby()->hook('panel.page.update', function($page) {
    $count = 0;
    $title = $page->title();
    $images = $page->images();
    foreach ($images as $image) {
        $count++;
        // Add 0 before $count so that it is two digits
        $count = str_pad($count, 2, '0', STR_PAD_LEFT);
        $old_filename = $image->filename();
        $filename = $title . "-" . $count;
        if (strpos($old_filename, 'box') !== false) {
            $filename = $filename . "-box";
        }
        $image->rename($filename);
    };
});

Also, I’m not sure why, but I had to remove from the initial code $count++.

If the $page has already 2 $images, the new uploaded file was numbered 4 (instead of 3), and then next 5 etc…
Not sure why it was counting one image more then the ones I had.

So now I have the following code

// Auto rename photos

kirby()->hook('panel.file.upload', function($file) {

    $page = $file->page();
    $title = $page->title();
    $count = 0;
    $old_filename = $file->filename();
    
    try {
        $count = $page->images()->count();
        // $count++;
        // Add 0 before $count so that it is two digits
        $count = str_pad($count, 2, '0', STR_PAD_LEFT);
        $filename = $title . "-" . $count;
        if (strpos($old_filename, 'box') !== false) {
            $filename = $filename . "-box";
        }
        $file->rename($filename);
        echo 'The file has been renamed';
    } catch(Exception $e) {
        echo 'The file has been renamed';
        // optional reason: echo $e->getMessage();
    }

});
1 Like

Well, the hook is triggered after the file is uploaded, so the new file is already included in $count.

Oh that makes sense! Thank you!