Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archive for November, 2007

Niveau :      
Résumé : et peck descendit de la montagne

Aujourd'hui parlons de ce qui fait un bon sysadmin. Le sysadmin est beau, le sysadmin est grand, le sysadmin est fort, mais ce n'est pas tout. Contrairement au mauvais chasseur, le bon sysadmin est celui qui suit les 9 commandements :

  • A chaque problème les logs je lirai
  • Si besoin d'aide, sur la toile je chercherai
  • Mon savoir je diffuserai
  • Automatiser, toujours j'essaierai
  • Au moindre doute, la documentation je lirai
  • L 'utilisateur est stupide, jamais ne lui dirai
  • Chez moi les bugs je chercherai
  • Les débutants j'encouragerai
  • Informé je me tiendrai

Mais tout le monde sait qu'il y a 10 commandements, en fait le dernier a été ajouté récemment :

Niveau :      
Résumé : setlocale ; xgettext ; gettextize

Maintenant vous savez utiliser gettext. Allons un peu plus loin. Vous avez internationalisé votre application et commencé à la traduire. Mais vous voudriez aussi l'installer et la rendre utilisable par tous facilement.

Pour cela il faut choisir la bonne locale en fonction de l'utilisateur. La solution retenue dépendra du type d'application.

Locale web

Si c'est une application web, basez vous sur la langue du navigateur, fournie pendant la négociation http ou la lange du serveur par défaut.

<?php
// locale par defaut (du serveur)
$locale = getenv('LANG');

// locale préférée du client
if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) )
{
        $languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] );
        $language = preg_replace( "/^([^,;]*?)[,;].*$/","$1", $languages );

        if ( $language != "" )
        {
                $locale = $language;
                $locale .= "_";
                // c'est un peu pauvre comme choix du pays et c'est pas garanti que ca marche
                // si vous avez une bonne idée n'hesitez pas
                $locale .= strtoupper($language);
                if ( $charset == "utf8" || $charset == "utf-8" )
                {
                        $locale .= "UTF-8";
                }
        }
}

setlocale(LC_ALL, $locale);
?>

Notez qu'ici on modifie LC_ALL qui impacte tous les éléments de locale (date, monnaie ...). Si vous ne voulez modifier que la locale liée à la traduction utilisez LC_MESSAGES à la place.

Locale locale

Si votre application est un programme local, basez vous sur la locale du système grâce aux variables d'environnement. Pour cela, il suffit d'appeler simplement setlocale :

/* code C, transposable aisément :-) */
setlocale( "LC_ALL", "");

Attention, quel que soit le langage, setlocale doit être appelée avant vos appels à bindtext et textdomain.

Industrialisation

Pour installer vos traductions sur un système unix, mettez les dans /usr/share/locale/fr/LC_MESSAGES.

Il vous faudra aussi maintenir vos traductions, pour cela vous devrez utiliser régulièrement xgettext pour extraire vos chaînes mises à jour. De plus à force de traduire, vous verrez que ce n'est pas toujours drôle de repérer les dernières modifications ou de faire des recherches avec un éditeur de texte normal. C'est pourquoi il vous faudra apprendre à utiliser un outil comme poedit pour éditer les fichiers .po

Niveau :      
Résumé : gettext

Connaissez vous la différence entre internationalisation et localisation (i18n et l10n) ? Hé bien il s'agit tout simplement de deux parties du même processus.

L'internationalisation c'est le fait de développer votre code pour qu'il supporte n'importe quelle locale. Par locale on entend la plupart du temps la langue, mais il ne faut pas oublier qu'il y a quelques autres particularités comme l'heure, la monnaie, l'affichage des dates ...

La localisation, c'est le fait de définir les propriétés locales du logiciel. Contrairement à l'internationalisation, ce n'est pas particulièrement un travail de développeur de s'occuper de la localisation. Il s'agit la plupart du temps de traduire du texte (l'heure et la monnaie étant en général fixe et donc déjà localisées).

Gettext est une bibliothèque pour vous faciliter l'internationalisation et la localisation du texte dans vos programmes. Elle a été pensée pour être utilisée dans du code existant aussi bien que dans du nouveau code. Le principe est de conserver les messages originaux dans le code (en anglais de préférence) et d'externaliser les versions localisées de ces messages dans d'autres fichiers.

Comment l'utiliser ?

La fonction principale de gettext est ... gettext. On lui passe en paramètre une chaîne de caractères et elle retourne la chaîne de caractères traduite correspondante.

Son action est simple, elle connaît la locale en cours, et en fonction de cette locale elle va chercher dans un fichier de texte localisé la chaîne de caractère correspondant à la chaîne en VO qu'on vient de lui passer. Si elle la trouve c'est gagné, sinon elle retourne la VO. Par conséquent, toutes les chaînes non traduites dans un logiciel fonctionnent, elles sont juste en VO.

Commençons par un exemple en php. En php, comme dans la plupart des autres langages, la fonction gettext() existe aussi sous le nom de _(), bien plus rapide à écrire et aussi plus lisible.


continue reading...

Niveau :      
Résumé : tail --retry ; tail --follow ; read

Savez-vous qu'il est possible de faire un tail sur un fichier qui n'existe pas encore (mais qui existera bientôt) ?

$ tail --retry

Savez-vous qu'il est possible de faire un tail sur un fichier qui disparaît et réapparaît (par exemple un fichier de log avec un logrotate intermédiaire) ?

$ tail --follow=name

Les éléments d'un pipe sont nécessairement exécutés dans des processus séparés. Par conséquent, il faut faire attention à vos scripts shell. Par exemple le script suivant ne met rien dans la variable var, même si fichier contient quelque chose (et c'est aussi valable pour les boucles while).

$ cat fichier | read var

Par contre le script suivant fera ce que vous pensez :

$ read var < fichier

Et si vous avez vraiment besoin d'utiliser les pipes, utilisez les pipes nommés :

$ mkfifo pipe
$ ligne | longue > pipe &
$ read var < pipe

Niveau :      
Résumé : const int UN=1

Qui n'a jamais entendu de son chef de projet : pas de constante sans nom dans le code c'est une règle ! Oui, mais comme toute règle, elle a ses exceptions. Plutôt que de l'appliquer bêtement, réfléchissons au pourquoi du comment.

Les constantes constantes

Si vous utilisez le code suivant :

l = 6.2832 * r;

Alors vous êtes dans l'erreur. 6.2832 c'est 2*pi (environ). Vous utilisez une constante connue de tous, vous devez donc l'appeler par son nom. C'est une règle élémentaire de lisibilité. Bon, celle-là vous la connaissiez. En plus définir PI en constante dans votre code vous permettra le jour venu de changer la précision facilement.

Les constantes variables

Si vous utilisez quelque chose comme

char buffer[4096];

Alors là aussi vous êtes dans l'erreur. Non pas parce que définir la constante BUFFER_SIZE aidera à la lecture , mais parce que votre constante n'en est pas vraiment une. Même si vous êtes persuadés que structurellement dans votre algorithme cela représente quelque chose, rien ne dit que sur une autre planète, ou dans 1000 ans tout ceci aura changé (et 1000 ans se réduisent parfois à quelques jours).

D'autre part, si votre constante est calculée, alors cela peut éventuellement servir à la lisibilité :

char buffer[2 * PACKET_SIZE];

continue reading...