Get path to assets/images

On a single-language project I wanted a common method to add the URL root of the assets folder, and also wanted to do some simplistic cache busting, so I wrote a method for the $site object:

/**
 * Complete an asset's URL with base directory and timestamp
 * @param Site $site
 * @param string $url
 * @return string
 */
Site::$methods['asset'] = function(Site $site, $url='') {
   if (!is_string($url) or $url == '') {
      return '';
   }

   // Retrieve timestamp, convert to base36 and only keep the last 5 chars,
   // which cover the last 700 days (more than enough for HTTP caches).
   $file = kirby()->roots()->assets() . DS . $url;
   $time = file_exists($file) ? (string) filemtime($file) : '';
   if ($time) $time = substr(base_convert((string) $time, 10, 36), -5);

   // Another, and theoretically better option is to put the timestamp
   // in the filename, e.g. myfile-6rwtq.css, but that would require changing
   // the .htaccess to rewrite those requests (stripping the timestamp).
   $base = kirby()->urls()->assets() . '/' . $url;
   return $time ? "$base?v=$time" : $base;
};

So in my templates I can write:

<link rel="stylesheet" href="<?= $site->asset('css/main.css') ?>">

and get:

<link rel="stylesheet" href="http://domain.tld/assets/css/main.css?v=6jjzs">
1 Like