Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

Assets and Cache Busting

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

We (mostly) don’t care about your CSS/JS

We’ll start by talking about CSS and JS files, and just how much Symfony doesn’t care about these. I mean that in a good way - you don’t necessarily need a PHP Framework to help you include a JavaScript file.

Open up your base template and find the weird stylesheets tag there:

{# app/Resources/views/base.html.twig #}
{# ... #}

{% block stylesheets %}
    {# link tag for bootstrap... #}

    {% stylesheets
        'bundles/event/css/event.css'
        'bundles/event/css/events.css'
        'bundles/event/css/main.css'
        filter='cssrewrite'
    %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}

Symfony does have some optional tricks for assets, and this is one of them. For now, just remove this whole block and replace it with 3 good, old-fashioned link tags:

{# app/Resources/views/base.html.twig #}
{# ... #}

{% block stylesheets %}
    {# link tag for bootstrap... #}

    <link rel="stylesheet" href="/bundles/event/css/event.css" />
    <link rel="stylesheet" href="/bundles/event/css/events.css" />
    <link rel="stylesheet" href="/bundles/event/css/main.css" />
{% endblock %}

Login with Wayne and password waynepass (party on) and then open up the HTML source on the homepage.

No Symfony magic here - this is just pure frontend code that points to real files in the web/bundles/event/css directory. And since the web/ directory is the document root, we don’t include that part.

Making Bundle Assets Public

The only thing Symfony is doing is helping move these files from their original location inside EventBundle’s Resources/public directory. But remember from episode 1 that Symfony has an assets:install console command. Run this again with a symlink option:

php app/console assets:install --symlink

Note

Symbolically links src/Yoda/EventBundle/Resources/public to web/bundles/event.

This creates a symbolic link from web/bundles/event to that Resources/public directory. This is just a cheap trick to expose CSS or JS files to the web/ directory that live inside a bundle. This lets us point at a real, physical file with the link tag.

Tip

The --sylmink option may not work on all Windows setups (depending) on your permissions.

You can also just put your CSS and JS files directly into the web/ directory. In fact, that’s a great idea.

The Twig asset Function

Take your simple link tag href and wrap it in a Twig asset function:

{# app/Resources/views/base.html.twig #}
{# ... #}

{% block stylesheets %}
    {# link tag for bootstrap... #}

    <link rel="stylesheet" href="{{ asset('bundles/event/css/event.css') }}" />
    <link rel="stylesheet" href="{{ asset('bundles/event/css/events.css') }}" />
    <link rel="stylesheet" href="{{ asset('bundles/event/css/main.css') }}" />
{% endblock %}

I want you to notice that the path isn’t changing, except that we don’t need the first / anymore. When you’ve got this, refresh. The site still looks great and the HTML source looks exactly as it did before, so asset isn’t doing anything . . . yet.

Leave a comment!

2
Login or Register to join the conversation
Max S. Avatar

Hey!
Using the Assetic {% stylesheets 'bundles ...%} expression produces:
Unexpected "stylesheets" tag (expecting closing tag for the "block" tag defined near line 7) in ::base.html.twig at line 7.
using Symfony 2.8.

Thanks in advance!

Reply

Hey Max,

I think I know the problem. The {% stylesheets 'bundles ...%} tag comes from Assetic bundle, but starting from Symfony 2.8, Assetic is no longer included by default in the Symfony Standard Edition. So you need to install it with Composer and enable it in your AppKernel manually. Check the docs please.

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "~2.4", // v2.4.2
        "doctrine/orm": "~2.2,>=2.2.3", // v2.4.2
        "doctrine/doctrine-bundle": "~1.2", // v1.2.0
        "twig/extensions": "~1.0", // v1.0.1
        "symfony/assetic-bundle": "~2.3", // v2.3.0
        "symfony/swiftmailer-bundle": "~2.3", // v2.3.5
        "symfony/monolog-bundle": "~2.4", // v2.5.0
        "sensio/distribution-bundle": "~2.3", // v2.3.4
        "sensio/framework-extra-bundle": "~3.0", // v3.0.0
        "sensio/generator-bundle": "~2.3", // v2.3.4
        "incenteev/composer-parameter-handler": "~2.0", // v2.1.0
        "doctrine/doctrine-fixtures-bundle": "~2.2.0", // v2.2.0
        "ircmaxell/password-compat": "~1.0.3", // 1.0.3
        "phpunit/phpunit": "~4.1", // 4.1.0
        "stof/doctrine-extensions-bundle": "~1.1.0" // v1.1.0
    }
}
userVoice