Internationaliser des images dans les feuilles de style (3/3)

Dans cette série d’articles, nous tentons de trouver une solution élégante au problème de l’internationalisation des images dans les feuilles de style.

Dans la partie précédente, je montrais qu’en utilisant SASS, il était possible d’internationaliser proprement les feuilles de style. Néanmoins, il est parfois possible de faire encore mieux.

 
Dans notre cas, toutes les valeurs que nous mettons dans les fichiers localisées (chemin vers l’image et largeur de l’image) seraient en théorie calculables automatiquement en fonction de la langue. Pour éviter de les écrire à la main, il est possible de générer automatiquement ces fichiers (avec n’importe quel langage de script) ou bien de profiter de la possibilité offerte par SASS de définir ses propres fonctions en Ruby.

Par exemple, pour définir une fonction qui calcule l’URL relative d’une image :
module Sass::Script::Functions
  # Return the url of the given image (given as a filename) for the given language
  def image_url(sass_lang, sass_filename)
    assert_type sass_filename, :String
    assert_type sass_lang, :String
 
    filename = sass_filename.value
    lang = sass_lang.value
 
    url = '/images/locales/' + lang + '/' + filename
 
    return Sass::Script::String.new(url)
  end
end

La fonction commence par vérifier le type des arguments qui lui sont passés puis les « transforme » en type système Ruby. Ensuite l’URL est calculée puis renvoyée sous forme de chaîne de caractère SASS.

De la même manière, vous pouvez écrire une fonction qui va automatiquement calculer la taille de l’image, par exemple grâce au gem image_size (simple à manipuler mais qui ne fonctionne pas sous Windows) ou à ImageMagick.

Avec ImageMagick, voici la fonction de calcul de la taille de l’image (modifiable facilement pour pouvoir également retrouver la hauteur) :
module Sass::Script::Functions
  # Return the width in pixels of the given image (given as a filename) for the given language
  def image_width_px(sass_lang, sass_filename)
    assert_type sass_filename, :String
    assert_type sass_lang, :String
 
    filename = sass_filename.value
    lang = sass_lang.value
 
    path = 'public/images/locales/' + lang + '/' + filename
    size_array = (`identify -format %wx%h #{path}`).chomp.split("x")
    size = {:width => size_array[0].to_i, :height => size_array[1].to_i}
    width = size[:width]
 
    return Sass::Script::Number.new(width, 'px')
  end
end

Le calcul dynamique des tailles des images ne pose pas de réel problème de performance car les fichiers CSS ne sont générés que lorsqu’il y en a besoin (configuration SASS réglable). Néanmoins, si vous avez peur que ça prenne trop de temps, notamment en mode développement dans lequel on force souvent le SASS à générer le CSS plus souvent, ou si vous souhaitez éviter le risque de calculer deux fois la même chose (si une même image est utilisée plusieurs fois), il est toujours possible, à chaque calcul, de stocker le résultat dans une variable de classe pour servir de cache.

Lorsque vous avez écrit un module de ce type, n’oubliez pas de faire en sorte de charger ce fichier au démarrage de Ruby ou de votre application pour qu’il soit pris en compte par SASS. Pour une application Ruby on Rails, cela revient à ajouter la ligne suivante dans « config/environnement.rb » :

config/environnement.rb
(...)
require "#{RAILS_ROOT}/lib/sass_extension.rb"

(Dans l’hypothèse où vous avez appelé le fichier « sass_extension.rb » et que vous l’avez placé dans le repertoire « lib » de votre application.)

 
Voyons à présent ce que deviennent nos fichiers de styles. En premier lieu le fichier « fr.sass » est réduit à sa plus simple expression :

fr.sass
$lang: fr
@import _styles.sass

Quant au fichier « _styles.sass », il reste relativement lisible :

_style.sass
form#setup button.validate
  background: transparent url(image_url($lang, “validate_button.png”)) no-repeat
  height: 25px
  width: image_width_px($lang, " validate_button.png ")

Sans compter qu’avec les possibilités du SASS, vous pourrez factoriser la plus grande partie des lignes ci-dessus. La formation du bouton peut se réduire aux lignes suivantes :

_style.sass
form#setup button .validate
  +button(“validate_button.png”)
(...)

À partir du moment où vous avez défini le mixin qui suit :

_style.sass
(...)
@mixin button($filename)
  background: transparent url(image_url($lang, $filename)) no-repeat
  height: 25px
  width: image_width_px($lang, $filename)

Cela permet de ne s’occuper d’internationalisation que dans quelques endroits bien identifiés de votre feuille de style.

 
Avec le système décrit, l’ajout d’une langue est simple, l’ajout d’une image est simple, la modification d’un sélecteur aussi. Que demander de plus ?

Pas de commentaire »

Pas encore de commentaire.

Laisser un commentaire

Nous ne revendons pas les adresses collectées