Archives de
Mois : janvier 2009

Zdmultilang v1.2.2 est sorti

Zdmultilang v1.2.2 est sorti

Une nouvelle version de zdmultilang est sortie. Pour plus d’info, allez voir sur son site officiel.

J’ai regardé les modifications qui ne remettent pas en cause le travail que j’avais fait pour gérer les widgets. J’ai toutefois fait un diff des 2 versions et je peux fournir un nouveau fichier : zd_multilang avec support multilingue des widgets.

Il doit permettre une installation sur une v.1.2.2 et inférieur de zdmultilang.

Travail autour du plugin zdmultilang

Travail autour du plugin zdmultilang

Après avoir testé plusieurs plugins multilingues pour wordpress (xLanguage, qTranslate et gengo), je me suis arrêté sur zdmultilang.

Ce dernier correspondait à ce que je recherchais : la possibilité de gérer les traductions pratiquement comme de nouvelles pages/articles mais avec une relation particulière avec la source. Par ailleurs, afin de respecter au mieux l’esprit plugin, je cherchais aussi quelque chose qui laisse la plate-forme directement opérationnelle en cas de désactivation.

Les seuls points qui manquaient par rapport à mon usage tournaient autour de la gestion des widgets. Je me suis donc attelé à ajouter cette fonctionnalité que je décris ici.

La normalisation des widgets

WordPress utilise toujours le même schéma pour le stockage des données de widgets : il s’agit d’un tableau associatif nom du paramètre/valeur qui est enregistré dans la table wp_option de la base à travers les fonctions get_option et update_option. Aussi dans un premier temps, j’ai remis au format le widget zd_multilang pour se conformer à ce standard.

Vers des options par langue

Zdmultilang gère déjà des options par langue : blogname et blogdescription dans la table wp_zd_ml_langs. Néanmoins, si nous souhaitons gérer les paramètres de widget par langue nous allons devoir changer d’architecture. Mon choix a été de créer une table wp_zd_ml_options dont la structure se base sur la table wp_options où j’ai ajouté un champ LanguageID. Cette table contiendra toutes les options dont je souhaite conserver une version spécifique par langue. J’en ai profité pour y mettre blogname et blogdescription, cet emplacement me semblant désormais plus légitime.

Comment construire dynamiquement les hooks pour nos widgets ?

Comme indiqué plus haut, les paramètres des widgets sont stockés dans la table wp_options. Afin de rester au plus proche de l’architecture WordPress, il m’a semblé judicieux d’associer des fonctions aux hooks pre_option_... et pre_update_option_...... correspond au nom du widget. L’utilisation des hooks « pre » permet de sortir des fonctions initiales get_option ou update_option presque immédiatement. Cela nécessite par contre de réécrire des fonctions analogues dans le plugin. Par souci d’homogénéité, presque toutes les fonctions d’accès aux options ont été réécrites : get_option, update_option, add_option, load_alloptions. Elles l’ont été en s’inspirant des fonctions WordPress initiales afin de tirer parti des outils de cache alloption et notoption évitant autant de requêtes vers la base de données. Ceci est d’autant plus utile dans notre cas que tous les widgets n’ont pas de paramètres, or comme nous ne pouvons le savoir à l’avance nous sommes obligés de créer des hooks pour tous les widgets enregistrés (voir plus quand leur dénomination ne suit pas la nomenclature WordPress). Si un widget n’a pas de paramètre, on ressortira alors très vite des fonctions que nous avons réécrites sans solliciter plus la base de données que les fonctions initiales.

Ensuite, il reste à associer ces fonctions aux hooks. Pour cela nous parcourons le tableau de hachage $wp_registered_widgets et pour chaque widget enregistré nous construisons dynamiquement une fonction triviale qui pointera vers les fonctions réécrites dont il est question plus haut.

foreach($wp_registered_widgets as $widget_name => $widget) {
	$funcname = 'zd_multilang_get_option_'.$widget['classname'];
	$function = "function $funcname".'() {
			$option=str_replace("zd_multilang_get_option_","",__FUNCTION__);
			return zd_multilang_get_option($option);
			}');
	eval($function);
	add_filter('pre_option_'.$widget['classname'], $funcname);
}

Notons qu’une fois tous ces hooks installés, on peut relancer la commande wp_widgets_init() qui réinitialise tous les widgets. Cependant, cette fois-ci, compte tenu des filtres installés, on ira chercher les paramètres dans notre table wp_zd_ml_options. Ça tombe bien : c’était notre objectif.

Comment conserver nos « sidebars » par langue ?

Les colonnes latérales s’enregistrent dans les thèmes.A priori, nous ne savons pas combien il y en a. L’idée est de conserver dans une option supplémentaire un équivalant de l’option sidebars_widgets qui contient les informations sur le contenu des colonnes latérales. Notre option contiendra les informations de nb de sidebars dans le thème x nb de langues gérées par zd_multilangue. Ensuite, il s’agira de reconstruire à la volée le résultat que WordPress s’attend à trouver en fonction du contexte (lecture simple ou paramètrage des widgets).

Comment permettre l’enregistrement des informations de widget pour les utilisateurs ?
À l’origine je souhaitais faire un écran de configuration des widgets par langue un peu comme zdmultilang gère les catégories, les étiquettes… Cependant, la gestion des widgets par WordPress (wp-adminwidgets.php) est loin d’être évidente (possibilité de javascript ou non, récupération des données de modification dans la même page que la présentation…). Aussi, j’ai fini par me résigner à ajouter un sélecteur de langue à la page traditionnelle d’administration des widgets. Là encore, les hooks mis à disposition par WordPress ne sont pas des plus pratiques, mais on finit toutefois par y arriver.
Copie d'écran du sélecteur de langue dans le gestionnaire de widget
Comment tester ces modifications du plugin ?
Vous pouvez accéder à mon code en suivant ce lien : zd_multilang avec support des widgets en multilingue, mais attention il est fourni avec le statut : it works for me. Par ailleurs, vous risquez de perdre vos données blogname et blogdescription par langue si vous décidez de revenir à une version antérieure.

N’hésitez pas toutefois à laisser vos commentaires.

De retour sur la Toile

De retour sur la Toile

Chers amis, si vous saviez comme je suis heureux de vous retrouver. Pourquoi un tel silence ? L’envie de me mettre au blog a germé dans mon précédent travail où je bénéficiais d’un peu plus de temps pour m’intéresser à ces choses là. En plus de cela, l’arrivée de Lucile a bien changé la donne.

Et puis, il fallait que je me sente à l’aise avec l’outil. Cela passait par une maîtrise de WordPress. Nous partions de loin : un WordPress installé à la va-vite basé sur un style récupéré sur le net (clean-cut de mémoire) légèrement modifieé. Assez vite, je me suis senti contraint par la pagination et le manque d’un outil de traduction pour pouvoir écrire des billets très techniques en informatique à la fois en français et en anglais. J’ai essayé de regarder directement ce que l’on pouvait faire avec des idées simples mais qui ne répondaient pas véritablement à mon besoin et et puis un soir, tard, un peu au hasard je suis tombé sur zdmultilang.

Il correspondait bien à ce que je voulais faire mais il manquait quelques éléments rédhibitoires pour moi (en particulier la gestion des widgets). J’ai passé une bonne partie de mes soirées de Noël sur le sujet et je suis parvenu à quelque chose de satisfaisant le 11 janvier 2009.

Quelques jours après, s’en suis donc cette reprise. Rappelez-vous, c’était hier : mon premier blog.

Copie d'écran de mon premier blog