Default Values for Parameters

Sometimes it makes sense to have a default value for parameters. This can be done by creating a new file parameters_default.yml (can be any name you like) and adding it to config.yml just before parameters.yml.

    - { resource: parameters_default.yml }
    - { resource: parameters.yml }
    locale: en
    secret: abcdefg1234567890

Now you can overwrite the default values in parameters.yml on demand but you’re not longer forced to define those parameters.

    locale: de

Using Parameters in Routes

You can use parameters from parameters.yml in routes. There are serveral use-cases when this may be useful.

Let’s say you want to localize your routes but you want to store the list of available locales only once. Then you could define a parameter in config.yml:

    allowed_locales: en|de|fr

Now you can use the parameter in your routing.yml:

    resource: "@MyBundle/Controller/"
    prefix:   /{_locale}
    type:     annotation
        _locale: %allowed_locales%

Another use-case is routes based on a hostname. Instead of writing the hostname directly into routing.yml you could use a parameter, as seen in the official documentation.

As fas as I know parameters only work for routes defined in YAML, XML or PHP. If it also works for annotation routes, please let me know.

Importing Routes from a Controller

This is how you import routes from a specific controller (only works if you used annotations):

    resource: "@MyBundle/Controller/WhateverController.php"
    type:     annotation

This is very useful if you have multiple controllers in single bundle but you can’t import the whole Controller directory at once because some routes have to be treated in a special way, e.g. you want a different prefix for every controller.

    resource: "@MyBundle/Controller/WhateverController.php"
    prefix:   /some-bundle/whatever
    type:     annotation

    resource: "@MyBundle/Controller/AnotherController.php"
    prefix:   /some-bundle/another
    type:     annotation

For reference, this is the original documentation of that feature.

Loading assets from a different server

In a production environment you’ll eventually want to load assets (images, CSS and JS) from a different server. Perhaps you’re running your own asset server or you’re even using a CDN. This will require the files to be linked with an absolute URL. But in your development environment you don’t want this – you want assets to be loaded directly from the same server.

So this is what you do. Use Symfony’s asset() function for every asset you want to load from the asset server:

If you’re using Assetic you’ll have to add the asset() function to asset_url:

{% javascripts '@AcmeFooBundle/Resources/public/js/*' %}
{% endjavascripts %}

Now you can have different configuration for your production and development environment:

    engines: ['twig']
    assets_base_urls: ~ # Files are loaded with relative path

Some hints when Assetic is not compiling

We’re sometimes having the problem that Assetic is not compiling for some reason. It tries to compile files, which are actually not referenced anywhere in the project. This especially happens when switching branches while an Assetic dump is running in the background (with watch option enabled).

Here are the steps we usually do to get the problem fixed:

1) Restart Assetic dumper
Ok, that one is obvious. Restart the Assetic dumper to refresh its information. Just like a reboot of Windows ūüėČ

2) Clear cache
Sometimes there is wrong information in the cache directory of the dev environment. Delete the whole app/cache/dev directory to get a clean new build. Then restart the Assetic dumper.

3) Take a look at the temp directory
Assetic writes some files to the temporary directory of your operating system. Search for files named assetic_* .  and delete them. Then restart the Assetic dumper.

Hope this helps!

Decorating Blocks in Twig

This is a simple trick how you can dynamically decorate a block in Twig.

Let’s say your design has a fanzy sidebar but you only want to display it when it has some content. In Twig you would usually solve this creating two seperate base templates. One, which includes a block named “sidebar”, and another one without it. This is quite easy, but then you’ll have to make sure you’re using the right base template. In addition you’ll have to maintain two base templates, even if they’re identical except for the sidebar.

So is there something else we could do, to make life more easy? Sure, we could put some more logic into to base template: Let’s check if the sidebar block has content! In that case we will display the content of the block embedded in some extra HTML.

This is how a base.html.twig might look like:

{% set sidebarContent = block("sidebar") %}
{% if sidebarContent %}
{% endif %}

First we’re fetching the content of the block into a variable with Twig’s block function.¬† Now we can check if there’s some content in it, so we can display the HTML container and the sidebar content on demand. Note that you have to use the raw filter on the block content since it is already sanitized HTML.