Catégorie : Utilisation

Quelques exemples sur l'utilisation de cet exemple de thème enfant

xili-tidy-tags version 1.8.6 dispo avec en sus un exemple de nuage en “popup”…

La sortie de cette version de xili-tidy-tags est liée à celle de WP 3.6 de l’été.
L’ajout majeur est un exemple de “template tag” – xili_tidy_tags_dropdown – qui permet d’afficher un nuage sous forme de “popup” ou “dropdown”. C’est en fait une solution compacte mais un peu bancale car pour que la liste “select” redirige vers la page regroupant les articles liés à cette page, il faut combiner du javascript (ici on a retenu du jQuery).

Le code se situe après la ligne 1009 du source du plugin. Bien sûr un minimun de connaissance en wp php est nécessaire.

C’est aussi un exemple pour récupérer les infos d’un nuage de tags récupérés en tableau.

Cet article sera prochainement complété.

M.

Les filtres/actions clés au démarrage de WP [réservé développeurs]

[NOTE : les exemples sont ici basés sur jetpack v2.3. La version jetpack 2.4+ a revu l’ensemble de l’initialisation selon des règles décrites ici.]

Ce qu’il faut savoir à propos de l’addition de filtres par une extension (plugin) ou via le fichier functions.php du thème actif.
Le cas particulier des filtres présents dans wp-settings.php

La ligne des temps

La suite logique de la mise en place des composants jusqu’à la délivrance de la page visiteur ou auteur (administrateur) telle que visible dans le wp-settings.

• mise en place des dropins et des mu-plugins (#157) (mu = must use).

• mise en place des fichiers des extensions ( #196 ) qui semble se faire dans le sens alphabétique. Deux situations : soit seuls les éléments sont installés et le filtre (action) est mis en queue (ce filtre pourra alors permettre le moment venu l’instantiation de la classe du plugin) – soit déjà des initialisations, instanciations sont lancées (elles ne sont dès lors plus filtrables au préalable par d’autres plugins).

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin )
	include_once( $plugin );
unset( $plugin );
 
// Load pluggable functions.
require( ABSPATH . WPINC . '/pluggable.php' );
require( ABSPATH . WPINC . '/pluggable-deprecated.php' );
 
// Set internal encoding.
wp_set_internal_encoding();
 
// Run wp_cache_postload() if object cache is enabled and the function exists.
if ( WP_CACHE && function_exists( 'wp_cache_postload' ) )
	wp_cache_postload();
 
do_action( 'plugins_loaded' );

Pourquoi il est important de définir la priorité du filtre dans la queue afin de maîtriser les effets désirés ?

Par défaut, la priorité d’un filtre est ajoutée au niveau 10. C’est donc sa position sur la ligne des temps de l’adjonction qui va déterminer sa place. Cela n’est donc pas parfait, on ne peut pas toujours se fier à l’ordre alphabétique du nom de l’extension. D’où la nécessité de définir précisément, en déclarant des priorités successives, par exemple que XILI-LANGUAGE sera lancée avant XTT et XD car ces deux dernières ne fonctionnent que dans l’environnement multilingue préalablement créé par XILI-LANGUAGE.

Exemple de JetPack et de bbPress pour le maîtrise du language côté admin:

Comme on le lit dans wp-settings.php, la réalisation (do_action) plugins_loaded (#209) se fait avant que les informations sur l’utilisateur connecté soient connues. Celle des filtres init (#306) est par contre activée alors que WP connait les rôles du visiteur ou de l’administrateur.

580
581
582
583
584
585
// line 4580 et suivantes
add_action( 'init', array( 'Jetpack', 'init' ) );
add_action( 'plugins_loaded', array( 'Jetpack', 'load_modules' ), 100 );
add_filter( 'jetpack_static_url', array( 'Jetpack', 'staticize_subdomain' ) );
 
Jetpack_Sync::sync_options( __FILE__, 'widget_twitter' );

La réalisation (do_action) plugins_loaded (#209) précède celle de init (#306). Mais en sus, ce qui pose problème, dans le cas de jetpack la fonction qui appelle Twitter ( Jetpack_Sync::sync_options( FILE, ‘widget_twitter’ ); ) instancie la classe lors de l’include de jetpack… c’est donc redondant – le filtre init n’a donc pas de raison d’être puisque la fonction twitter a instancé la classe dès l’include du fichier jetpack.php … Une mise à plat s’impose.

Chaque chose en son temps et au bon moment… une bonne architecture n’est pas automatique. Il faut donc bien séparer ce qui tient de l’infrastructure (inclusion des fichiers de l’extension), de sa modification par les extensions activées (filtre plugins_loaded) et de sa personnalisation selon la personne connectée et des rôles qui lui sont attribués (filtre init) ; pour ces deux filtres cités, bien assigner les priorités.

A propos des fonctions et objets ajoutées dans functions.php du thème.

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
$GLOBALS['wp_locale'] = new WP_Locale();
 
// Load the functions for the active theme, for both parent and child theme if applicable.
if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) {
	if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
		include( STYLESHEETPATH . '/functions.php' );
	if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
		include( TEMPLATEPATH . '/functions.php' );
}
 
do_action( 'after_setup_theme' );
 
// Set up current user.
$wp->init();
 
/**
 * Most of WP is loaded at this stage, and the user is authenticated. WP continues
 * to load on the init hook that follows (e.g. widgets), and many plugins instantiate
 * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.).
 *
 * If you wish to plug an action once WP is loaded, use the wp_loaded hook below.
 */
do_action( 'init' );
 
// Check site status
if ( is_multisite() ) {
	if ( true !== ( $file = ms_site_check() ) ) {
		require( $file );
		die();
	}
	unset($file);
}

Ce fichier est inclus après la génération des rôles et la mise en place des locales. Le fichier du thème enfant est inséré avant celui du thème parent. (# 287) – Ensuite intervient la réalisation (do_action) after_setup_theme (#294) qui précède celle de init (#306). Cas particulier si thème enfant : comme le fonctions.php du thème enfant est activé avant celui du thème parent. L’adjontion du filtre/action after_setup_theme doit se faire en position 11. Les fonctions de ce filtre recouvront alors celle du thème parent.

On peut donc dans le thème adapter certaines actions ou filtres générés au préalable par les extensions. Cela ne sera donc actif que si le thème est affecté au site (thème courant). Pour ce qui concerne les filtres du wp-settings, on voit que seul les filtres ‘init’ peuvent être modifiés (changement de la fonction associée ou de sa priorité via remove_filter suivi d’un add_filter avec de nouveaux paramètres,…)

(à suivre… patience…)

Options pour les auteurs et éditeurs

Ce thème enfant de 2013 utilise une classe qui inclut des fonctions pour aider les auteurs pendant la génération des articles traduits.

Aujourd’hui, par défaut, si vous créez un article en anglais à partir d’un article en français, toutes les catégories de l’article d’origine sont attachées au nouvel article – gestion de contenu (cms) oblige…

Selon les règles que vous vous fixez, il est possible de copier d’autres attributs et qualités d’un post. Il y en a 7:

  1. Post Format: par défaut c’est une simple copie, mais un développer peut, via un filtre, définir d’autre règles
  2. Modèle de page
  3. Autorisation des commentaires
  4. Autorisation des pings et rétroliens
  5. Parent: Dans ce cas, il faut s’assurer que l’article ait bien un parent et que ce parent ait déjà sa traduction… cms oblige 😉 !!!
  6. Ordre: ne concerne que les posts hiérarchiques comme le CPT page,
  7. Image à la une : L’article (la page) traduite aura la même image (essaie de trouver celle liée avec les éléments descriptifs traduits).

Ces nouvelles options sont visibles à partir du menu Apparence/Xili-Options/, copie d’écran ci-dessous:

Options pour les auteurs
Options pour les auteurs

functions.php : ligne par ligne

Cet article est destiné aux personnes ayant quelques connaissances en php et en WP (thème, modèle, …).

La fonction twentythirteen_xilidev_setup actionnée par le filtre “after_setup_theme” après (11) celui du parent va permettre de mettre en place les bons fichiers, instancier la classe “xili_language_theme_options” avec des paramètres personnalisés (nom du thème parent, nom du domaine pour la traduction,…) et rendre compte d’éventuelles erreurs. La classe “xili_language_theme_options_admin” n’est activée que du côté admin.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
define( 'TWENTYTHIRTEEN_XILI_VER', '1.0'); // as style.css
 
// main initialisation functions
 
function twentythirteen_xilidev_setup () {
 
	$theme_domain = 'twentythirteen';
 
	load_theme_textdomain( $theme_domain, STYLESHEETPATH . '/langs' ); // now use .mo of child
 
	$xl_required_version = false;
 
	if ( class_exists('xili_language') ) { // if temporary disabled
 
		$xl_required_version = version_compare ( XILILANGUAGE_VER, '2.8.7', '>' );
 
		global $xili_language;
 
		$xili_language_includes_folder = $xili_language->plugin_path .'xili-includes'; 
 
		$xili_functionsfolder = get_stylesheet_directory() . '/functions-xili' ;
 
		if ( file_exists( $xili_functionsfolder . '/multilingual-classes.php') ) {
			require_once ( $xili_functionsfolder . '/multilingual-classes.php' ); // xili-options created by developers
 
		} elseif ( file_exists( $xili_language_includes_folder . '/theme-multilingual-classes.php') ) {
 
			require_once ( $xili_language_includes_folder . '/theme-multilingual-classes.php' ); // ref xili-options based in plugin
		}
 
		if ( file_exists( $xili_functionsfolder . '/multilingual-functions.php') ) {
			require_once ( $xili_functionsfolder . '/multilingual-functions.php' );
		}
 
		if ( file_exists( $xili_functionsfolder . '/multilingual-permalinks.php') && $xili_language->is_permalink ) {
			require_once ( $xili_functionsfolder . '/multilingual-permalinks.php' ); // require subscribing premium services
		}
 
 
	//register_nav_menu ( 'toto', 'essai' );
 
		global $xili_language_theme_options ; // used on both side
	// Args dedicaced to this theme named Twenty Thirteen
		$xili_args = array (
	 		'customize_clone_widget_containers' => true, // comment or set to true to clone widget containers
	 		'settings_name' => 'xili_2013_theme_options', // name of array saved in options table
	 		'theme_name' => 'Twenty Thirteen',
	 		'theme_domain' => $theme_domain,
	 		'child_version' => TWENTYTHIRTEEN_XILI_VER
		);
 
		if ( is_admin() ) {
 
		// Admin args dedicaced to this theme
 
			$xili_admin_args = array_merge ( $xili_args, array (
		 		'customize_adds' => true, // add settings in customize page
		 		'customize_addmenu' => false, // done by 2013
		 		'capability' => 'edit_theme_options'
			) );
			if ( class_exists ( 'xili_language_theme_options_admin' )  ) {
				$xili_language_theme_options = new xili_language_theme_options_admin ( $xili_admin_args );
				$class_ok = true ;
			} else {
				$class_ok = false ;
			}
 
 
		} else { // visitors side - frontend
 
			if ( class_exists ( 'xili_language_theme_options' )  ) {
				$xili_language_theme_options = new xili_language_theme_options ( $xili_args );
				$class_ok = true ;
			} else {
				$class_ok = false ;
			}
		}
	}
 
	// errors and installation informations
 
	if ( ! class_exists( 'xili_language' ) ) {
 
		$msg = '
		<div class="error">
			<p>' . sprintf ( __('The %s child theme requires xili-language plugin installed and activated', $theme_domain ), get_option( 'current_theme' ) ).'</p>
		</div>';
 
	} elseif ( $class_ok === false )  {
 
		$msg = '
		<div class="error">
			<p>' . sprintf ( __('The %s child theme requires <em>xili_language_theme_options</em> class to set multilingual features.', $theme_domain ), get_option( 'current_theme' ) ).'</p>
		</div>';
 
	} elseif ( $xl_required_version )  {
 
		$msg = '
		<div class="updated">
			<p>' . sprintf ( __('The %s child theme was successfully activated with xili-language.', $theme_domain ), get_option( 'current_theme' ) ).'</p>
		</div>';
 
	} else {
 
		$msg = '
		<div class="error">
			<p>' . sprintf ( __('The %s child theme requires xili-language version 2.8.8+', $theme_domain ), get_option( 'current_theme' ) ).'</p>
		</div>';
	}
	// after activation and in themes list	
	if ( isset( $_GET['activated'] ) || ( ! isset( $_GET['activated'] ) && ( ! $xl_required_version || ! $class_ok ) ) )
		add_action( 'admin_notices', $c = create_function( '', 'echo "' . addcslashes( $msg, '"' ) . '";' ) );
 
	// end errors...	
 
}
add_action( 'after_setup_theme', 'twentythirteen_xilidev_setup', 11 );

Le message en couleur jaune indique que tout va bien, les messages en rouge indique que l’extension xili-language n’est pas activée ou que sa version est ancienne. Idem si la classe n’est pas présente.

La function ‘special_head’ actionnée par le filtre ‘wp_head’ va agir sur la circonstance où l’on décide d’avoir un formulaire de recherche enrichi des langues disponibles pour cibler cette recherche. Une autre tâche est – selon les préférences – d’injecter dans une balise style les lignes css dans le header pour avoir le nom des langues remplacé par une image (drapeau).

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/**
 * define when search form is completed by radio buttons to sub-select language when searching
 *
 */
function special_head() {
 
	// to change search form of widget
	// if ( is_front_page() || is_category() || is_search() )
	if ( is_search() ) {
	 	add_filter('get_search_form', 'my_langs_in_search_form_2013', 10, 1); // in multilingual-functions.php
	}
	$xili_theme_options = get_theme_xili_options() ; 
 
	if ( !isset( $xili_theme_options['no_flags'] ) || $xili_theme_options['no_flags'] != '1' ) {
		twentythirteen_flags_style(); // insert dynamic css
	}
}
if ( class_exists('xili_language') )  // if temporary disabled
	add_action( 'wp_head', 'special_head', 11);
 
/**
 * dynamic style for flag depending current list and option no_flags
 *
 * @since 1.0.2 - add #access
 *
 */
function twentythirteen_flags_style () {
 
	if ( class_exists('xili_language') ) {
		global $xili_language ;
		$language_xili_settings = get_option('xili_language_settings'); 
		if ( !is_array( $language_xili_settings['langs_ids_array'] ) ) { 
			$xili_language->get_lang_slug_ids(); // update array when no lang_perma 110830 thanks to Pierre
			update_option( 'xili_language_settings', $xili_language->xili_settings );
			$language_xili_settings = get_option('xili_language_settings');
		}
 
		$language_slugs_list =  array_keys ( $language_xili_settings['langs_ids_array'] ) ;
 
		?>
		<style type="text/css">
		<?php 
 
		$path = get_stylesheet_directory_uri();
 
		$ulmenus = array();
		foreach ( $language_slugs_list as $slug ) {
			echo "ul.nav-menu li.menu-separator { margin:0; }\n";
			echo "ul.nav-menu li.lang-{$slug} a { background: transparent url('{$path}/images/flags/{$slug}.png') no-repeat center 16px; margin:0;}\n";
			echo "ul.nav-menu li.lang-{$slug}:hover {background: #AD9065}\n"; // find menu bk
			echo "ul.nav-menu li.lang-{$slug} a:hover {background: transparent url('{$path}/images/flags/{$slug}.png') no-repeat center 17px !important;}\n";
			$ulmenus[] = "ul.nav-menu li.lang-{$slug} a";
		} 
			echo implode (', ', $ulmenus ) . " {text-indent:-9999px; width:24px;  }\n";
		?>
		</style>
		<?php
 
	}
}

Le thème Twenty Thirteen autorise avec son filtre ‘twentythirteen_credits’ de personnaliser le crédit en bas de page.

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
function twentythirteen_xili_credits () {
	printf( __("Multilingual child theme of Twenty Thirteen by %s", 'twentythirteen' ),"<a href=\"http://dev.xiligroup.com\">dev.xiligroup</a> - " );
}
 
add_action ('twentythirteen_credits','twentythirteen_xili_credits');
 
 
// examples to help authors
 
// propagate post_formats
add_action( 'xl_propagate_post_attributes', 'xili_propagate_post_format', 10, 2);
 
function xili_propagate_post_format ( $from_post_ID, $post_ID ) {
	if ( $format = get_post_format( $from_post_ID ) ){
		set_post_format( (int)$post_ID , $format);
	}
}
 
// propagate page templates
add_action( 'xl_propagate_post_attributes', 'xili_propagate_page_template', 10, 2);
 
function xili_propagate_page_template ( $from_post_ID, $post_ID ) {
	if ( 'page' == get_post_type( $from_post_ID ) ) { // post_type_supports( 'page', 'page-attributes' );
 
		$template = get_post_meta ( $from_post_ID, '_wp_page_template', true ) ;
		update_post_meta ( $post_ID, '_wp_page_template', $template );
 
	}
}

La version xili-language propose le filtre ‘xl_propagate_post_attributes’. Donc selon le thème et la politique éditoriale, il est possible de choisir ce qui est copié lors de la création d’un article dans une autre langue. Le travail de l’auteur/traducteur est ainsi facilité : ici le post_format est recopié, idem pour le template en cas de page. Il est tout à fait possible d’imaginer que le format (ou le template ) ne soit pas le même selon chaque langue… c’est l’avantage de pourvoir coder.

2013-05-09 MS

Developpeur : quels sont les éléments essentiels pour fabriquer un thème enfant multilingue ?

Depuis la version 2.8.8, xili-language contient une classe (dans un fichier) qui contient tous les éléments nécessaires pour créer un thème enfant multilingue. Cette intégration a été initiée – à titre d’exemple – pour le futur thème Twenty Thirteen (2013) qui est annoncé avec WP 3.6. Ces acquis ont été depuis intégrés aux autres “enfants” xili des thèmes “officiels” comme TwentyTwelve et les précédents (bientôt mis en ligne)…

Quels sont les composants du thème dans son dossier (ici Twenty Thirteen) ?

2013 xili dossier et fichiers
2013 xili dossier et fichiers

Comme dans tout thème enfant, le fichier style.css est indispensable.

Le dossier image contient le favicon et l’icone pour iPad / iPhone, le dossier avec les drapeaux, et le dossier avec les images d’entête spécifiques du thème enfant (elles s’ajoutent à celles du thème parent).
apple-touch-icon

Seules quelques fichiers ‘template’ (category, sidebar) sont présents car ils incluent des petites modifications nécessaires pour le contexte multilingue.

Le fichier functions.php est ici le plus important car il contient des fonctions très puissantes pour faire un site multilingue facilement et de façon très adaptée à la ligne éditoriale du site.