Better download links (with URL rewrite?)

Hi,

I got some downloads on my page at http://tobiw.de/downloads and the download link for the first file ist http://tobiw.de/content/8-downloads/ausrichtungstest_din_a4.pdf but I’d prefer http://tobiw.de/downloads/ausrichtungstest_din_a4.pdf. Is it possible to get theses shorter links working in an automatic way?

Cheers,
Tobi

If you have all your downloads in the same folder you could use this custom route in your site/config/config.php as a kind of quick fix:

c::set('routes', array(
  array(
    'pattern' => 'downloads/(:any)',
    'action'  => function($filename) {
      go('content/8-downloads/' . $filename);
    }
  ),
));

But this is not really an „automatic“ way …

Thanks! But this will only work for hand written links and not for the ones kirby generates; I can change my template though …
Furthermore the visitor will see the real URL after the routing, right? Or is the routing invisible like the rewrites for page URLs?

You might try something like this. The following code is untested though…

array(
    'pattern' => '(:any)',
    'action'  => function($path) {
        $path = pathinfo($path);
        $dir  = $path['dirname'];
        $filename = $path['basename'];

        $file = page($dir)->file($file);
            if($file) {
                go($file->url());
            } else {
                return true;
            }
        }
)

Hi and sorry for the delayed reply!

@flokosiol I testes your code now, and it works but the go($file->url); part reveals the real URL, which I want to keep hidden …

@twirx your code gives me this error:

Fatal error: Call to a member function file() on boolean in /Users/Tobi/Documents/Gewerbe/CI und Werbung/Homepage/kirby (final)/site/config/config.php on line 90

I will have a look at it, but it will take probably one or two days, as I have much to do right now… :wink:

Thanks! There’s absolutely no rush!

The most important thing for me is to hide the real URL (that containing /content/…) from the visitor. If this is not possible with routes maybe an html rewrite can help … at the moment all downloads are in the same folder.

If all downloads are on the same page, the following route works (at least in my tests):

c::set('routes', array(
  array(
    'pattern' => 'downloads/(:any)',
    'action'  => function($filename) {      
      if ($page = site()->index()->findByURI('uri/to/your/page/with/files')) {
        if ($file = $page->file($filename)) {
          $file->download();
        }
      }
    }
  ),
));

The download()method forces the browser to download the file.

I’m not sure if a return false;needs to be added at the end like here: http://getkirby.com/docs/advanced/routing#stopping-the-app

hm … unfortunately your code gives me lots of errors, which have to to with my multi language setup – I guess …

since the download folder is in the first level, I could “fix” this with this route:

c::set('routes', array(
  array(
    'pattern' => 'downloads/(:any)',
    'action'  => function($filename) {      
      if ($page = site()->find('downloads')) {
        if ($file = $page->file($filename)) {
          $file->download();
        }
      }
    }
  ),
));

I’m not sure if I want to prevent that the file is viewed in the browser an directly downloaded, though …


But I had success with mod_rewrite an the following rule:

RewriteRule ^downloads/(.*) content/8-downloads/$1 [L]

This also hides the real URL from the visitor.