keyboard

Hugo Soltys

Symfony developer

Since 2013

How to handle image assets with Symfony 4

Posted on by Hugo - 1496 views - 0 Comments


Symfony 4 provides a lot of changes that can disturb even the regulars of the framework. Assets management is one of them.

In this article, we will see how to handle image assets with Symfony 4.


Unlike Symfony 3, this new version of Symfony uses a new asset management system, the Webpack Encore. Very easy to use, this Javascript library makes working with CSS and JS a pleasure.

Let's start with an example

Let's assume that you want to store the CSS of your website in a file called app.css. In a Symfony 4 directory architecture, you will place this file under the assets/css folder. Once done, open your webpack.config.js file. You will find something like this :

// webpack.config.js
var Encore = require('@symfony/webpack-encore');

Encore
    // the project directory where all compiled assets will be stored
    .setOutputPath('public/build/')

    // the public path used by the web server to access the previous directory
    .setPublicPath('/build')

    // allow legacy applications to use $/jQuery as a global variable
    .autoProvidejQuery()

    // enable source maps during development
    .enableSourceMaps(!Encore.isProduction())

    // empty the outputPath dir before each build
    .cleanupOutputBeforeBuild()

    // show OS notifications when builds finish/fail
    .enableBuildNotifications()

    // create hashed filenames (e.g. app.abc123.css)
    // .enableVersioning()

    // allow sass/scss files to be processed
    // .enableSassLoader()
;

// export the final configuration
module.exports = Encore.getWebpackConfig();

This config file will tell to the JS library where to put your different JS or CSS files. You can find all the configuration options here.

If you want to add your app.css file, add the following line in the webpack.config.js file.

var Encore = require('@symfony/webpack-encore');

Encore
    // the project directory where all compiled assets will be stored
    .setOutputPath('public/build/')

    // the public path used by the web server to access the previous directory
    .setPublicPath('/build')

    // will create public/build/app.js and public/build/app.css
    .addStyleEntry('css/app', './assets/css/app.css')

    // allow legacy applications to use $/jQuery as a global variable
    .autoProvidejQuery()

    // enable source maps during development
    .enableSourceMaps(!Encore.isProduction())

    // empty the outputPath dir before each build
    .cleanupOutputBeforeBuild()

    // show OS notifications when builds finish/fail
    .enableBuildNotifications()

    // create hashed filenames (e.g. app.abc123.css)
    // .enableVersioning()

    // allow sass/scss files to be processed
    // .enableSassLoader()
;

// export the final configuration
module.exports = Encore.getWebpackConfig();

 

Open now a terminal and type the following command

$ yarn encore dev

NB : Yarn is a fast, reliable and secure dependency management. To install it, click here.

Your CSS file is now available under the public/build/css directory. To be clear, moving an asset from the assets/ to the public/ directory in Symfony 4 is the same of moving an asset from the src/ to the web/ directory in the older versions of Symfony (aka the assets:install command).

 

You can now access it in every Twig template with the asset() helper :

{# base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <!-- ... -->
        <link rel="stylesheet" href="{{ asset('build/css/app.css') }}">
    </head>
</html>

 

What about images ?

I can hear you from here : "Okay Hugo, we got it for CSS and JS files, but this is an article about handling images in our Symfony 4 project !".

Yes. Indeed. But you had to understand the bases of Webpack Encore before to go further.

Images management is practically the same, except that you will need to install the copy-webpack-plugin (available on GitHub here). This plugin allows you to copy either individual files or entire directories under the build/ directory.

You can install it with npm using the following command :

$ npm i -D copy-webpack-plugin

 

Once done, you can put all your image assets under the assets/images/ directory.

 

Open now your webpack config file and add the plugin configuration:

var Encore = require('@symfony/webpack-encore');
var CopyWebpackPlugin = require('copy-webpack-plugin'); // this line tell to webpack to use the plugin

Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .addStyleEntry('css/app', './assets/css/app.css')
    .autoProvidejQuery()
    .enableSourceMaps(!Encore.isProduction())
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    // .enableVersioning()
    // .enableSassLoader()

    .addPlugin(new CopyWebpackPlugin([
        { from: './assets/images', to: 'images' }
    ]))
;

// export the final configuration
module.exports = Encore.getWebpackConfig();

 

Now Encore is correctly configured, run the following command to install your image assets.

$ yarn encore dev

 

As you can see, your files have been copied from assets/images/ to public/build/images/

You can now display your images in your Twig templates like in the older versions of your preferred PHP framework.

<img src="{{asset('build/images/my-image.png')}}" title="my image" alt="My image">

 

That's all for this one. If you have any question please leave a comment, I'll answer you quickly.

Hugo.


Hugo Soltys

My name is Hugo, I'm 25 and I'm a Symfony developer since 2013. I love to create websites by myself to learn new technologies or increase my skills.
I love movies, books, music and video games. I also like to drink a few beers with my friends. I'm from Lille (France) and I currently work as Symfony developer at Decathlon since 2016. Before that, I worked as Symfony developer for the IT Room company, in Roubaix, France.


Older articles