How to include CSS file in Symfony 2 and Twig?

SymfonyTwig

Symfony Problem Overview


I'm playing around with Symfony2, and I have problems including CSS and JS files in Twig template.

I have a bundle named Webs/HomeBundle inside which I have HomeController with indexAction that renders a twig template file:

public function indexAction()
{
    return $this->render("WebsHomeBundle:Home:index.html.twig");
}

So this is easy. Now what I want to do, is to include some CSS and JS files inside this Twig template. Template looks like this:

<!DOCTYPE html>
<html>
<head>  
    {% block stylesheets %}
        <link href="{{ asset('css/main.css') }}" type="text/css" rel="stylesheet" />
    {% endblock %}
</head>
<body>
</body>
</html>

The file I would like to include, main.css file is located in:

Webs/HomeController/Resources/public/css/main.css

So my question is basically, how the hell do I include simple CSS file inside Twig template?

I'm using Twig asset() function and it just doesn't hit the right CSS path. Also, I run this command in console:

app/console assets:install web

This created a new folder

/web/bundles/webshome/...

this is just linking to the

src/Webs/HomeController/Resources/public/

right?

Questions

  1. Where do you place your asset files, JS, CSS, and images? Is it OK to put them in Bundle/Resources/public folder? Is that the right location for them?
  2. How do you include these asset files in your Twig template using asset function? If they are in public folder, how can I include them?
  3. Should I configure something else?

Symfony Solutions


Solution 1 - Symfony

You are doing everything right, except passing your bundle path to asset() function.

According to documentation - in your example this should look like below:

{{ asset('bundles/webshome/css/main.css') }}

Tip: you also can call assets:install with --symlink key, so it will create symlinks in web folder. This is extremely useful when you often apply js or css changes (in this way your changes, applied to src/YouBundle/Resources/public will be immediately reflected in web folder without need to call assets:install again):

app/console assets:install web --symlink

Also, if you wish to add some assets in your child template, you could call parent() method for the Twig block. In your case it would be like this:

{% block stylesheets %}
    {{ parent() }}

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

Solution 2 - Symfony

And you can use %stylesheets% (assetic feature) tag:

{% stylesheets
    "@MainBundle/Resources/public/colorbox/colorbox.css"
    "%kerner.root_dir%/Resources/css/main.css"
%}
<link type="text/css" rel="stylesheet" media="all" href="{{ asset_url }}" />
{% endstylesheets %}

You can write path to css as parameter (%parameter_name%).

More about this variant: http://symfony.com/doc/current/cookbook/assetic/asset_management.html

Solution 3 - Symfony

The other answers are valid, but the Official Symfony Best Practices guide suggests using the web/ folder to store all assets, instead of different bundles.

> Scattering your web assets across tens of different bundles makes it > more difficult to manage them. Your designers' lives will be much > easier if all the application assets are in one location. > > Templates also benefit from centralizing your assets, because the > links are much more concise[...]

I'd add to this by suggesting that you only put micro-assets within micro-bundles, such as a few lines of styles only required for a button in a button bundle, for example.

Solution 4 - Symfony

In case you are using Silex add the Symfony Asset as a dependency:

composer require symfony/asset

Then you may register Asset Service Provider:

$app->register(new Silex\Provider\AssetServiceProvider(), array(
    'assets.version' => 'v1',
    'assets.version_format' => '%s?version=%s',
    'assets.named_packages' => array(
        'css' => array(
            'version' => 'css2',
            'base_path' => __DIR__.'/../public_html/resources/css'
        ),
        'images' => array(
            'base_urls' => array(
                'https://img.example.com'
            )
        ),
    ),
));

Then in your Twig template file in head section:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    {% block head %}
    <link rel="stylesheet" href="{{ asset('style.css') }}" />
    {% endblock %}
</head>
<body>

</body>
</html>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLimeniView Question on Stackoverflow
Solution 1 - SymfonyVitalii ZurianView Answer on Stackoverflow
Solution 2 - SymfonyZhukVView Answer on Stackoverflow
Solution 3 - SymfonyaalaapView Answer on Stackoverflow
Solution 4 - SymfonyPmpr.irView Answer on Stackoverflow