Manipuler les assets avec Cecil
Cecil ·Dans cet article j’explique comment Cecil, mon générateur de site statique, permet de manipuler des assets, sans dépendances à des outils tiers.
<link rel="stylesheet" href="{{ asset('sass/styles.scss')|to_css|minify|fingerprint }}">
Qu’est-ce qu’un asset ?
Un asset est une ressource web, tel qu’un fichier CSS, JavaScript ou encore une image, permettant d’habiller ou de dynamiser un site web.
Ainsi, une feuille de styles peut être chargée en indiquant simplement le chemin vers le fichier correspondant :
<link rel="stylesheet" href="/css/styles.css">
Dans l’exemple ci-dessus l’URL vers le fichier de la feuille de styles est « en dur » dans le template HTML et c’est souvent suffisant dans la plupart des cas.
Néanmoins, on peut rapidement se poser les questions suivantes :
- Comment compresser ma feuille de styles pour gagner en performance ?
- Comment compiler ma feuille de styles au format Sass et modifier des variables ?
- Comment informer les navigateurs web que ma feuille de style à été modifiée et ne pas demander aux internautes de « vider le cache » ?
Cecil, grâce à sa fonction asset()
combinée à quelques filtres Twig, répond à ces besoins.
Créer un asset
Reprenons l’exemple précédent en y appliquant la fonction asset()
:
<link rel="stylesheet" href="{{ asset('css/styles.css') }}">
On crée ainsi un objet « asset » à partir du fichier styles.css
préalablement déposé dans le dossier static/css/
du projet.
Regroupement (bundle)
La fonction asset()
peut également combiner une liste d’assets du même type.
Template :
<link rel="stylesheet" href="{{ asset(['css/styles-a.css', 'css/styles-b.css']) }}">
Rendu :
<link rel="stylesheet" href="/css/styles.css">
Par défaut le fichier bundle porte le nom suivant :
styles.css
pour les fichiers CSSscripts.js
pour les fichiers JavaScript
Il est possible de personnaliser ce nom via l’option filename
.
Template :
<link rel="stylesheet" href="{{ asset(['css/styles-a.css', 'css/styles-b.css'], {filename: 'main.css'}) }}">
Rendu :
<link rel="stylesheet" href="/main.css">
Fichier distant
Si le chemin passé à la fonction asset()
est une URL, le fichier sera téléchargé localement et mis en cache pour les prochaines générations.
Exemple :
{{ asset('https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.3.1/anchor.min.js') }}
Le fichier, lors de la génération du site, sera enregistré de la manière suivante :
/assets/cdnjs.cloudflare.com/ajax/libs/anchor-js/4.3.1/anchor.min.js
Manipuler un asset
Minification
Le filtre minify
réduit la taille d’un asset du type CSS ou JavaScript, en supprimant les espaces, retours à la ligne, etc.
Template :
<link rel="stylesheet" href="{{ asset('css/styles.css')|minify }}">
Rendu :
<link rel="stylesheet" href="/css/styles.min.css">
Compilation Sass
Le filtre to_css
compile un asset de type Sass.
Template :
<link rel="stylesheet" href="{{ asset('sass/styles.scss')|to_css }}">
Rendu :
<link rel="stylesheet" href="/css/styles.css">
Il est possible de paramétrer les règles de compilation via le fichier de configuration du projet (config.yml
par défaut) de la manière suivante :
assets:
compile:
style: expanded # expanded ou compressed
import: [sass, node_modules] # liste des chemins importés, relatifs au dossier static/
Il est également possible de remplacer la valeur des variables :
assets:
variables:
primary: '#5a5a5a'
Documentation : https://cecil.app/documentation/configuration/#assets
Empreinte (fingerprint)
Le filtre fingerprint
crée l’empreinte de la ressource (d’après son contenu) et complète le nom du fichier en conséquence.
Ainsi, si le fichier est modifié il aura une empreinte différente lors de la génération du site : le consommateur du fichier considérera donc que cette ressource est différente de celle qu’il a dans son cache et la téléchargera.
Template :
<link rel="stylesheet" href="{{ asset('css/styles.css')|fingerprint }}">
Rendu :
<link rel="stylesheet" href="/css/styles.e549285c8ffa8af5e6254263c98d4397.css">
Redimensionnement
Le filtre resize
permet de redimensionner une image, selon une nouvelle largeur (si celle-ci est inférieure à la largeur de l’image d'origine).
Template :
<img src="{{ asset('image.jpg')|resize(800) }}">
Rendu :
<img src="/assets/thumbnails/800/image.jpg">
Attributs d’un asset
Un asset expose des attributs (en fonction de son type) :
file
: Chemin du fichier localpath
: Chemin web relatifext
: Extensiontype
: Type de média (ex :image
)subtype
: Sous-type de média (ex :image/jpeg
)size
: Poids (en octets)source
: Contenu avant traitementcontent
: Contenu après traitementintegrity
: Hachage d'intégritéwidth
: Largeur (dans le cas d’un fichier image)height
: Hauteur (dans le cas d’un fichier image)audio
: Tableau Mp3Info (dans le cas d’un fichier MP3)
Exemples :
{% set image = asset('image.jpg') %}
<img src="{{ image }}" width="{{ image.width }}" integrity="{{ image.integrity }}" crossorigin="anonymous">
Durée : {{ asset('title.mp3').audio.duration|round }} min
Documentation : https://cecil.app/documentation/templates/#attributes
Paramétrage par défaut
Par défaut Cecil applique l’ensemble des traitements (compile
, minify
et fingerprint
), désactivables via la configuration :
assets:
compile:
enabled: true # compile automatiquement un fichier Sass
minify:
enabled: true # minifie automatiquement un fichier CSS ou JavaScript
fingerprint:
enabled: true # applique automatiquement l'empreinte du fichier à son nom
Template :
<link rel="stylesheet" href="{{ asset('sass/styles.scss') }}">
Rendu :
<link rel="stylesheet" href="/css/styles.e549285c8ffa8af5e6254263c98d4397.min.css">
Remarque
Dans un contexte d’affichage l’objet « asset » retournera le chemin web relatif (path
) de la ressource.
Vous pouvez utiliser le filtre url
pour manipuler l’URL générée, par exemple :
{{ asset('css/styles.css')|url({canonical: true}) }}