I have a field "menu card" in my globals' section "menuCard", so I could access my file in the template with menuCard.menuCard.first().url. That is fine, but when the editor changes the menu-card file and it has a different name, the url will be different:

first week:

next week:

As it is a menu-card for a restaurant which gets changed every week it would be awesome to always have the current menu-card pdf available through the same url/slug like myrestaurant.com/menu and also reference the menu within my templates with /menu;

Is there a way to do so in craftcms? For example an alias which points to my global field menuCard.menuCard.first() or something like that?


2 Answers 2


You could create a simple plugin with Pluginfactory and copy the two function I'll give you to create the URL you like

  1. Go to the page, turn on the light switch for "Controller" but leave the name blank, download it, copy it to craft/app/plugins/
  2. Include this function to your plugins main file. If you did not disable preview/example code in the page you'll see there is already a cocktails route there

    public function registerSiteRoutes()
        return [
            'menu' => ['action' => '>>insertYourPluginNameHere<</downloadMenuCard'],
  3. in this case www.exampleurl.de/menu would download your file, you can change the key to whatever you want.

  4. Insert this function in your created Controller

    public function actionDownloadMenuCard()
        $globalSetHandle = 'menuCard'; // change the handle of your global set here if needed
        $fieldHandle = 'menuCard'; // change the handle of your field here if needed
        $globals = craft()->globals->getSetByHandle($globalSetHandle);
        /** @var AssetFileModel $asset*/
        $asset = $globals->$fieldHandle->first(); 
        $source = $asset->getSource();
        $sourcePath = $source->settings['path'];
        $folderPath = $asset->getFolder()->path;
        $assetFilePath = $sourcePath.$folderPath.$asset->filename;
        craft()->request->sendFile($assetFilePath, IOHelper::getFileContents($assetFilePath));

You can include a redirect after that if you want in order to display the landing page or whatever you want. If you don't want to download the file at all and just display it you can do craft()->request->redirect($asset->getUrl()); after you fetched the asset


Another approach without a plugin would be to add the route in your craft/config/routes.php file

return array(
    'menu' => 'download.twig',

And do the redirect in the template

{% set config = craft.globals.getSetByHandle('menuCard') %}
{% set file = config.menuCard.first() %}
{% redirect file.getUrl() 302 %}

You could setup a template at /menu that grabs the PDF you want and redirects with a 302 (not a 301 since it isn't permanent).

The URL would change, but that might be ok if you only care about having an easy link to share.

If redirecting is a deal breaker, you could make a small plugin that returns the file with proper headings, then call that from the /menu template.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.