filyb.info

dimanche 7 octobre 2007

Comment créer une teinte pour le fond d'un site web ?

Afin d'étendre la science de Kazo, voici un petit tutoriel pour appliquer une teinte transparente sur une zone de page web.

Commençons par le problème : La zone de texte sans la teinte Ici, le texte est difficilement lisible, mais on désire ne pas masquer l'image. On va donc appliquer une teinte, de la couleur jaune de la bordure (#f2c56c), avec une opacité de 85%.

La solution du futur

Le W3C est en train de préparer la recommandation CSS 3, qui apporte des améliorations notables pour l'opacité, comme la propriété opacity ou les couleurs RGBA (voir aussi les différences entre opacity et RGBA).

Mais cette recommandation n'est pas terminée, et est susceptible d'évoluer. Certains navigateurs n'ont pas attendu, et ont commencé à l'implémenter, parfois via des attributs propriétaires (-moz- chez Mozilla, etc). Et il n'y a aucun support de cette propriété chez Internet Explorer.

La solution du passé

Cette solution consiste à créer un fichier .gif de 2x2 pixels. Les fichiers .gif sont parfaitement gérés par tous les navigateurs depuis longtemps, aucun problème de ce côté là. Je rappelle que la transparence du format gif est binaire : un pixel peut être totalement transparent, ou totalement opaque avec une couleur. Le principe est de créer un damier de pixel coloré et transparent.

À l'aide de GIMP, il suffit de créer une image (Fichier > Nouveau...) de 2x2 pixel, avec un fond transparent. Nouveau damier dans the GIMP

À l'aide de l'outil crayon avec une brosse de 1 pixel, on crée le damier. Damier dand the GIMP

Il suffit ensuite de l'enregistrer (Fichier > Enregistrer sous) au format gif (en terminant le nom du fichier par .gif).

Pour appliquer ce damier à la page web, il suffit de modifier la feuille de style de la façon suivante :

#content {
    background: url(damier.gif);
}

Voici le résultat : La zone de texte avec le damier gif Je vous l'accorde, c'est loin d'être idéal. Ça peut être utile dans certains cas, mais il faut savoir jouer sur le damier et la police du texte pour avoir un résultat potable. Heureusement, il y a mieux.

La solution actuelle

Au lieu du damier, nous allons utiliser une image au format png. Ce format est bien meilleur que le format gif, notamment grâce à son support d'une couche de transparence. Mais hélas, cette transparence n'est pas très bien gérée par Internet Explorer dans ses versions d'avant la 7.

Création du fond

Nous allons créer un fichier de 1x1 pixel (qui sera répété sur tout le fond de la zone concernée, vu qu'il est uniforme, autant le faire de la taille la plus petite pour accélérer le téléchargement de la page). On commence par choisir nos couleurs dans la fenêtre d'outils de GIMP : Fenêtre d'outils de The GIMP Plaçons dans le premier rectangle (la couleur de premier plan) la couleur à partir de laquelle nous souhaitons réaliser la teinte, et dans le second la couleur qui sera affichée par Internet Explorer 6 et précédent (ici du blanc). On choisit la couleur en cliquant sur le rectangle, notez le cadre qui permet de coller directement une couleur html.

Ensuite, on crée une nouvelle image (Fichier > Nouveau), de 1x1 pixel, en choisissant comme remplissage la couleur de premier plan : Nouvelle image avec the GIMP

Notre petit pixel est créé, il faut jouer avec le zoom (en bas de la fenêtre de l'image) pour y voir quelque chose. Nous allons maintenant appliquer une transparence au calque qui correspond à la couleur de fond, et qui a été créé automatiquement lors de la création de l'image. Il suffit d'aller dans la fenêtre des calques : Transparence du calque dans the GIMP Le réglage opacité permet de choisir la transparence du calque.

Ensuite, on enregistre l'image (Fichier > Enregistrer sous) au format png (en terminant le fichier par .png). Un message demande de fusionner les calques, on accepte. Ensuite une fenêtre d'options apparaît, veillez à ce que l'option Enregistrer la couleur d'arrière-plan, qui permet à Internet Explorer d'afficher la couleur que nous avons affecté à l'arrière plan.

Mise en place du fond pour les navigateurs modernes

Dans la feuille de style de la page, on ajoute :

#content {
    background: url(teinte.png);
}

(content représente le cadre en question sur la page, et teinte.png le chemin du fichier png créé auparavant.)

Et voici le résultat : La zone de texte avec la teinte en png

Et pour Internet Explorer ?

Sans rien faire, Internet Explorer devrait afficher la couleur d'arrière-plan (mais ça n'a pas marché avec mon Internet Explorer 6 émulé pour GNU/Linux, il faudrait le tester sous Microsoft Windows).

Microsoft a aussi publié un bricolage pour que les png s'affichent bien. Sauf que ça ne me semble pas vraiment donner du code valide, mais c'est le dernier des soucis de Microsoft (et mettre du code spécifique à Internet Explorer n'est jamais plaisant).

Il existe aussi la possibilité d'encadrer le code dans la feuille de style par des commentaires conditionnels. Là aussi, c'est un vilain bricolage. On peut trouver une bonne explication sur les commentaires conditionnels chez Blog and Blues. Ainsi, on peut afficher en image de fond un machin hideux avec écrit Changez de navigateur !.

jeudi 2 novembre 2006

Tutoriel : traduire un programme en python (et glade)

Créer un programme c'est bien. Encore faut-il que les utilisateurs puissent y accéder. Et malheureusement, les utilisateurs ne sont pas forcément des gens ayant exactement le même schéma de pensée et les mêmes connaissances que les développeurs. Conséquence : il faut s'adapter aux utilisateurs, notamment il faut que le programme soit disponible dans leur langue.

Lorsque le-dit programme est réalisé en python, et éventuellement son interface avec glade, c'est relativement trivial, encore faut-il savoir comment faire... et la documentation manque ou date un peu. Voici donc la méthode - je l'espère - complète, si vous avez des suggestions, n'hésitez pas, les commentaires sont là pour ça.

Les informations de ce document sont principalement tirées de la documentation du module gettext de python, du How do I internationalize a PyGTK and libglade program? de la FAQ de PyGTK, et du wiki de wxPython.

Introduction

La traduction d'un programme va se dérouler en deux phases. En premier, la préparation du programme (i18n), phase qu'il est préférable de poursuivre tout au long du développement, qui consiste à écrire le programme en anglais (générallement), et à marquer tous les textes et toutes les données qui sont spécifiques à l'anglais ou au Royaume-Unis. Et en second la traduction et l'adaptation à chaque langue ou pays (l10n).

Pour réaliser tout ça, nous allons utiliser les outils GNU gettext, et le module python gettext.

Les outils GNU gettext sont fournis avec certains systèmes comme les distributions GNU/Linux. Ils vont nous servir à réaliser les opérations des développeurs et des localisateurs, mais ne sont pas utiles sur la machine de l'utilisateur, où notre programme n'aura besoin que du module python gettext, fourni en standard avec la distribution python.

Les outils GNU gettext sont très pratiques, s'ils ne sont pas installés sur votre système, je vous recommande de vous rendre sur leur site officiel et de les télécharger. Néanmoins, si vous souhaitez vous en passer, il existe deux programmes fournis en standard avec votre distribution python, pygettext et msgfmt.py qui peuvent éventuellement remplacer xgettext et msgfmt des outils GNU gettext. Mais ces outils ne remplissent pas toutes les fonctions des outils GNU gettext, et sont considérés comme obsolètes (malgré que la documentation python officielle les conseille). En particulier, si vous voulez traduire une interface réalisée avec glade, vous devrez utiliser les outils GNU gettext.

Dans tous les cas, je recommande les outils GNU gettext, ce tutoriel sera fait pour eux.

Internationalisation

La première étape consiste à marquer dans les différents modules python les chaînes de caractère à traduire. Pour cela, on les passera comme argument à une fonction nommée par convention _ (le caractère de soulignement). Par exemple :

print "Hello world"

va devenir :

print _("Hello world")

Vous devez aussi faire attention aux chaînes de caractères qui contiennent des parties variables. Par exemple, n'écrivez pas :

print _("Hello ") + name + _("!")

qui obligerait le traducteur à traduire d'abord "Hello " (avec une espace), puis "!", mais plutôt :

print _("Hello %s!") % name

Et si plusieurs variables doivent être insérées dans la chaîne, nommez-les et utilisez un dictionnaire et non une liste, ce qui permettra au traducteur d'intervertir les variables. Par exemple, n'écrivez pas :

print _("Hello %s, today is %s") % (name, day)

mais plutôt :

print _("Hello %(name)s, today is %(day)s") % {'name': name, 'day': day}

Faites aussi attention aux formats de nombre, de date, de monnaie, qui dépendent évidement du pays de l'utilisateur. Si vous utilisez glade pour réaliser votre interface, vous pouvez choisir quels textes sont à ne pas traduire (ils sont traduisibles par défaut).

La seconde étape consiste à modifier le programme pour définir la fonction _() en utilisant le module gettext de python. Cela se fait simplement sous un système de type GNU/Linux, mais demande bien plus de code sous Microsoft Windows, aussi vous trouverez un exemple uniquement pour GNU/Linux, et un exemple multi-plateforme.

Dans tous les exemples qui suivent, notre application s'appelle coincoin, est lancée par coincoin.py, et son éventuelle interface glade est contenue dans le fichier coincoin.glade.

Le seul fichier à modifier est le fichier qui sera exécuté (coincoin.py). S'il importe des modules avec des chaînes marquées par _(), celles-ci seront aussi traduite (si vous ne voulez pas que cela ait lieu, consultez la documentation python).

Les localisations seront stockées dans un dossier locale. Celui-ci est en général placé dans /usr/share/locale dans les systèmes GNU, et détecté automatiquement par le module gettext, mais devra être précisé sous Microsoft Windows (j'utiliserai le dossier locale du dossier parent où est exécuté le programme, mais vous pouvez en choisir un autre).

Exemple uniquement pour les systèmes GNU/Linux (et probablement autres systèmes non Microsoft Windows) :

# i18n
application = 'coincoin'
import gettext
gettext.install(application)

[...]

# Si votre programme utilise glade, précisez bien le domaine gettext application:
gui = gtk.glade.XML(fname="coincoin.glade", domain=application)

Exemple multi-plateforme :

# i18n
application = 'coincoin'
import gettext
if os.name == 'nt':
    # Code pour Microsoft Windows

    # Chemin du dossier locale sous windows
    win_local_path = os.path.abspath(os.path.join(os.path.pardir, 'locale'))
    
    # Code pour une éventuelle interface glade
    gtk.glade.bindtextdomain(application, win_local_path)
    gtk.glade.textdomain(application)
    
    # Code pour le programme python (le module local permet de déterminer la langue actuelle)
    import locale
    lang = locale.getdefaultlocale()[0][:2]
    try:
        cur_lang = gettext.translation(application, localedir=win_local_path, \
                                   languages=[lang])
        cur_lang.install()
    except IOError:
        # Si la langue locale n'est pas supportée, on définit tout de même _()
        # On le fait dans les __builtins__ pour que la fonction soit définie dans
        # les modules importés (c'est ce que fait gettext.install()).
        __builtins__._ = lambda text:text
else :
    # Code pour les autres systèmes d'exploitation
    gettext.install(application)

[...]

# Si votre programme utilise glade, précisez bien le domaine gettext application:
gui = gtk.glade.XML(fname="coincoin.glade", domain=application)

Il reste une dernière étape : la création d'un modèle de traduction. Celui-ci servira pour créer de nouvelles traductions ou les mettre à jour. Nous allons utiliser l'outil xgettext. Dans un terminal, rendez-vous dans le dossier où sont stockés vos modules python et vos éventuels fichiers glade, et lancez la commande :

xgettext -k_ -kN_ -o coincoin.pot *.py *.glade

Vous allez obtenir un fichier coincoin.pot, qui est le modèle de vos futures traductions. À chaque changement du programme vous devrez le mettre à jour en relançant cette commande (vous avez bien sûr le droit de ne le faire que lorsque votre release est terminée, pas la peine de vous embêter à le faire tous les caractères modifiés).

Localisation

Cette partie devra être refaite pour chaque langue.

La communauté francophone des utilisateurs de coincoin râle : coincoin est en anglais, et ils aimeraient que ça change. Un gentil traducteur se propose. Voilà ce qu'il devra faire :

  1. Créer une nouvelle localisation, en utilisant par exemple msginit. Dans un terminal et dans le dossier où se trouve coincoin.pot :

    msginit -i coincoin.pot -o locale/fr/LC_MESSAGES/coincoin.po

    Dans cet exemple, locale qui représente le dossier locale du programme, et fr le code de la lange (les caractères avant le _ dans $LANG). Le programme msginit va créer une nouvelle traduction basée sur la langue actuelle de l'utilisateur (si vous souhaitez créer une traducion pour une autre langue, lisez man msginit), et demander quelques informations comme l'adresse mail du traducteur.

  2. Ouvrir le fichier coincoin.po avec un éditeur de texte (il existe aussi des logiciels dédiés à l'édition de fichier po), et traduire les différentes chaînes de caractères. Un fichier po s'organise de la façon suivante :

    #: fichiers_de_la_chaine:position
    msgid "Original string"
    msgstr "Chaîne traduite"
    
    #: coincoin.py:1024
    msgid "Coin coin string"
    msgstr ""
    "Cette chaîne s'étend "
    "sur plusieurs lignes."
    

    N'oubliez pas d'informer votre traducteur de la signification en python de %s et %(bidule)s.

  3. Si votre programme a été modifié depuis la création de la traduction, le traducteur devra mettre à jour son fichier depuis le modèle pot (que vous aurez pris soin de recréer) à l'aide de la commande (lancée depuis le dossier où se trouve le modèle) :

    msgmerge -U locale/fr/LC_MESSAGES/coincoin.po coincoin.pot

    Celle-ci commentera (par ajout de dièse # en début de ligne) les traductions obsolètes et rajoutera les nouvelles chaînes à traduire. Le fichier devra être relu et complété.

  4. Enfin, pour être utilisable par le programme, la traduction doit être compilée. Cela s'effectue par la commande (dans le dossier où se trouve le fichier po) :

    msgfmt coincoin.po -o coincoin.mo

    Le fichier mo produit devra être distribué dans les paquets binaires de votre application, dans l'arborescence correspondante du dossier local de votre programme.

Ça y est, la communautée francophone des utilisateurs de coincoin est contente ! Le programme fonctionne dans leur langue.

samedi 1 avril 2006

Filelight

Peut-être êtes-vous familier avec le message suivant :

Message d'erreur indiquant qu'un disque est plein.

Et alors vous vous mettez à chercher frénétiquement comment gagner les quelques megaoctets nécessaires... Et clique-droit > propriété sur tous les dossiers que vous rencontrez, et vous n'avez pas envie de supprimer les photos du chien, et votre musique. Et tout cela ne remplit que la moitié de votre partition ! Où est passé la place restante ?

Heureusement, il existe un utilitaire très pratique qui va vous permettre de repérer immédiatement les dossiers qui prennent le plus de place sur votre disque : Filelight !

Icone de Filelight

Filelight (site web officiel : methylblue.com/filelight) nécessite Qt (version 3.2 au minimum) et KDE (version 3.2 au minimum).

Suivant la distribution que vous utilisez, il est probable que ce programme soit disponible avec votre gestionnaire de paquets. Par exemple, pour Ubuntu, vous pourrez trouver le paquet filelight avec apt-get ou synaptic (dépôt universe activé).

Sinon, vous pouvez compiler Filelight en suivant les instructions d'installation.

Ce programme est prévu pour s'intégrer dans l'interface KDE, mais il devrait fonctionner aussi sous d'autres interfaces, telles que GNOME.

Après lancement de filelight, une fenêtre devrait s'ouvrir, vous présentant vos différents disques, avec peut-être des diagrammes circulaires (sinon agrandissez la fenêtre) représentant l'espace libre (free) et l'espace utilisé (used) :

Fenêtre de démarrage de Filelight

Pour examiner un dossier, vous pouvez soit cliquer sur l'espace occupé d'un disque, soit utiliser le menu scan :

Menu scan

Une fois le dossier choisit, Filelight va le scanner. Cela peut prendre du temps, tout dépend de la vitesse de votre disque-dur, du nombre de fichier du dossier, etc. Une fois cela fait, Filelight affiche un diagramme présentant la hiérarchie des sous-dossiers et fichiers du dossier examiné, en fonction de leur taille (les plus petits sont ignorés). En passant la souris sur un dossier, vous aurez des informations sur celui-ci, notament sa taille et le pourcentage de place sur le disque :

Affichage d'un dossier dans Filelight

Ainsi, vous pourrez facilement repérer les fichiers et dossiers les plus volumineux présent sur votre disque. Pour examiner un dossier en particulier, vous pouvez cliquer dessus, le diagramme s'affichera à partir de ce dossier, sans qu'un nouveau scannage soit nécessaire. Vous pouvez de plus cliquer avec le bouton droit sur un dossier, et choisir Open Konqueror Here pour ouvrir ce dossier dans Konqueror. Toujours avec un clique droit, l'action Delete vous permet de supprimer le dossier. Attention : cela supprime définitivement le dossier, sans le copier dans la corbeille ! Et idem pour les fichiers : un clique permet de les ouvrir, un clique droit permet de les supprimer.

Vous pouvez aussi utiliser la barre d'outils (Image de la barre d'outils) et la barre d'adresse (Image de la barre d'adresses) pour naviguer comme dans votre gestionnaire de fichier préféré.

Et grâce à l'intégration des applications de KDE, vous pouvez aussi utiliser Filelight dans Konqueror : soit en cliquant sur le menu Affichage > Type d'affichage > RadialMap View ou en cliquant sur l'icone correspondant dans la barre d'outils (si disponible)

Désormais, vous allez pouvoir maîtriser pleinement votre espace disque ! Le programme est encore dans une version beta, et sujet à quelques plantages, mais il est très prometteur.