Global Images for all pages

Yes! yes i have! And the cheetsheets massive… i miss stuff when i look at it.

    <?php
    $srcpath = page('gimages')->root();
    $destpath = $page->root();

    symlink($srcpath, $destpath);

    ?>

That did it.

But I get the above mentioned error with that code, because of linking to an existing path.

Oh… i didnt mean it worked… i meant it got the same result more concisely then my effort. Sorry, it was a poor choice of words.

Fine, then we are on the same page.

What you can do is this:

<?php
foreach(page('gimages')->files() as $file) {

symlink($file->root(), $page->root() . '/' . $file->filename());
}
?>

But only once for existing files…

anddddd thats beyond me but hooks does sound like the way to go.

Ok so i had a stab at this but it doest seem to work:

No errors but no symlinks created either :frowning:

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

  // symlink nuker
  foreach($page->files() as $file) {
        // delete symlinks if they exist
        if(is_link($file)) {
            unlink($file);
        }
  }

  // set symlinks for all images
  foreach(page('gimages')->files() as $symfile) {

    // set some paths
     $infile = $symfile->root();
     $outfile = $page->root() . '/' . $symfile->filename();

     symlink($infile, $outfile);
  }

});

My tiny brain thinks that should work. @texnixe, is there something wrong with my logic? how can i wrap it in a if check for the gimages folder - dont want the hook to run on that page, just all others i guess.

Well, without having a deeper look because of the late hour, the first issue is

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

which should be

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

and then you don’t have to loop through all files, because there is only the file you uploaded.

But keep going, you’ll learn a lot doing this kind of stuff :smiley:

Gosh! is that the time… flies when your having fun. I guess tomorrows another day.

Not sure i understand what you mean.

Heres the deal as i see it:

  1. We have a content folder full of images as a global stash (gimages).
  2. We want these to show up on any other page in the site via symlinks

To my mind that means generating the symlinks on new page create.

When a new file gets uploaded to the gimages folder, it needs to recursively rip the content folder, and update existing symlinks.

Thats the problem as i see it and my challenge for tomorrow. Time for bed.

Sleep well :sleeping: But there are two different problems to take care of: first, creating a symlink to all files whenever a new page is created, using panel.page.create hook. Secondly, updating all links of all pages when a new file is uploaded via panel.file.uploadhook.

So I’ve been messing with this some more, but theres a snag. I have the symlinks being created on page creation, which is great:

    kirby()->hook(['panel.page.create'], function($page) {

      // set symlinks for all images
      foreach(page('gimages')->files() as $symfile) {

         // set some paths
         $infile = $symfile->root();
         $outfile = $page->root() . '/' . $symfile->filename();

         symlink($infile, $outfile);

      }

    });

The problem is if you then delete the page, Kirby refuses to delete it because it still has the symlinks in it and it cant delete them for some reason. I thought a page delete hook would do the trick to unlink() the files so i did this…

    kirby()->hook(['panel.page.delete'], function($page) {

      // symlink nuker
      foreach($page->files() as $file) {
          if(is_link($file)) {
              unlink($file);
          }
      }
    });

Unfourtiunatly, unlink() insists in removing the original images in gimages folder, NOT the symlinks that point to those files in my test article. Bummer.

Am I missing something?

The panel.page.delete hook is triggered after the page has been deleted, not before. So it’s a bit surprising that unlink is executed at all if the page is not deleted.

Are you sure? By page do you mean literally the page as in the text file, or the whole content folder for that page? What i’m seeing is the text file disappears, the ORIGINAL images disappear, then i get a Kirby popup telling me there was error deleting the page, and a button to force deletion. The button does nothing because the symlink files are still in the content folder.

This is the delete() method:

  public function delete($force = false) {

    // check if the delete option is available
    if($this->options()->delete() === false) {
      throw new PermissionsException();
    }

    // create the delete event
    $event = $this->event('delete:action');

    // check for permissions
    $event->check();

    // delete the page
    parent::delete(true);

    // resort the siblings
    $this->sorter()->delete();

    // remove unsaved changes
    $this->changes()->discard();

    // delete all associated thumbs
    $this->removeThumbs();

    // hit the hook
    kirby()->trigger($event, $this);
}

As you can see, the hook is triggered right at the end.

Well, it seems as if the page is indeed deleted, but not fully, so the hook is indeed triggered. Very strange behavior.

Actually, I think this symlink stuff has to many downsides to be usable.

Another side effect is that the Panel gets really slow.

Weird, huh? so how can i get rid of the symlinks because the unlink command actually follows the link and deletes the target, not the link it self.

Possibly, but i think it was worth a shot.

It is not the unlink command that deletes the original files, it happens when the page is deleted.

Ah - its hard to tell, i’ve tried dozens of things. So Kirby is deleting them not the hook. Damn.

@puppet Well it was a bold effort but it seems the idea i had is a no go.

You can still get something similar though. If you make a content page to hold your global images and combine it with the Kirby Builder plugin, you can in effect setup global albums by adding the gallery field to Kirby builder.

Then, you can create Kirby tags to render those albums into other content pages.