/* */

WordPress et ses secrets… tout est déjà dans le cache
11 avril 2013Catégories : WordPress

par Barakadam

Voici un modèle classique de page single.php permettant d’afficher un post (article) WordPress :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php get_header(); ?>
<div id="main">
<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h1><?php the_title(); ?></h1>
<div class="entry-content">

<?php the_content(); ?>
</div><!-- .entry-content -->

<?php comments_template( '', true ); ?>
</div><!-- #post-## -->
<?php endwhile; // end of the loop. ?>

</div><!-- #main -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Vous connaissez cela par coeur. Et vous savez que dans la boucle (while ( have_posts() ) : the_post();), vous pouvez appeler différentes fonctions qui utilisent les données récupérées par la requête principale WordPress dans l’objet $post.

Ainsi

1
the_content();

équivaut à :

1
$post->post_content;

Etc.

WordPress extraie d’emblée une série de données relative au post (article) dans sa requête principale (son titre, son contenu, son extrait, sa date de publication, etc.). Voici un exemple de contenu d’un objet $post pour un article de ce site :

1
2
3
4
5
6
7
8
9
WP_Post Object ( [ID] => 688 [post_author] => 1 [post_date] => 2013-04-10 22:00:06 [post_date_gmt] => 2013-04-10 21:00:06 [post_content] => La barre d'administration, nouveauté apparue avec la version 3.1 de WordPress, s'affiche par défaut à la fois côté administration et côté site dès qu'un utilisateur est connecté et quels que soient ses droits d'accès. Evidemment, un simple abonné qui clique sur la barre d'administration pour passer du côté administration ne verra pas grand chose, mais son impression sera pourtant bien celle d'être "passé de l'autre côte de la barrière". Dans bien des cas, il est logique de faire une différence entre les utilisateurs administrateurs ou éditeurs de WordPress et les utilisateurs de plus bas niveaux (abonnés, etc.) qui accèdent à des fonctions spéciales du site Web et se distinguent en cela des utilisateurs non connectés (simples visiteurs) mais qui n'ont pour autant rien à faire du côté administration. Pour désactiver la barre d'administration en ne l'affichant que si l'utilisateur connecté est un administrateur: if (!current_user_can('manage_options')) { add_filter('show_admin_bar', '__return_false'); // intervient sur le filtre show_admin_bar et retourne false }

Qu'est-ce que ce __return_false? Très utile ! WordPress propose une valeur "spéciale" pour les filtres, qui permet de "court-circuiter" la chaîne des actions de filtre pour retourner directement une valeur, sans se préoccuper des éventuels traitements ultérieurs. En un mot, utiliser  __return_false, dans ce contexte (celui d'un filtre), c'est avoir la certitude que la valeur retournée sera bien false au final (et non une autre valeur, suite aux diverses modifications opérées par les fonctions ultérieures du filtre, qui auraient repris la valeur false et, en lui appliquant d'autres transformations, auraient abouti à une autre valeur). Il en existe d'autres :  __return_true,  __return_zero ou  __return_empty_array.

Par défaut, la capacité manage_options n'
est attribuée qu'aux super-administrateurs ou administrateurs. Donc pas aux éditeurs.  Si vous souhaitez l'afficher aussi pour les éditeurs, vous pouvez par exemple utiliser la capacité moderate_comments.

Référez-vous au tableau des correspondances entre capacités et rôles dans le Codex WordPress : http://codex.wordpress.org/Roles_and_Capabilities#manage_options

[post_title] => Supprimer la barre d'administration pour les utilisateurs WordPress qui ne sont pas des administrateurs [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => supprimer-la-barre-dadministration-pour-les-utilisateurs-wordpress-qui-ne-sont-pas-des-administrateurs [to_ping] => [pinged] => [post_modified] => 2013-04-10 22:26:52 [post_modified_gmt] => 2013-04-10 21:26:52 [post_content_filtered] => [post_parent] => 0 [guid] => http://macadamcodeboys.com/?p=688 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw )

Cela fait pas mal d’informations. En général, dans un template de post, on se sert d’une bonne partie de cela (notamment les informations de contenu).

Mais savez-vous que WordPress récupère bien d’autres données au passage, à l’aide de son propre mécanisme de cache ?

Vous pouvez non seulement manipuler l’objet $post, mais aussi un autre objet qui se trouve à disposition aussi et s’appelle $wp_object_cache. Que contient-il? En refaisant l’essai pour le même article, on obtient 5 ou 6 fois plus de données mises en cache qu’il n’y en a dans l’objet   $post ! Faites l’essai sur l’un de vos articles :

1
print_r($wp_object_cache);

Vous aurez quelques surprises! Une foule de données ont été collectées et mises en mémoire. Et il est même possible de récupérer les données insérées dans vos champs personnalisés (custom fields) directement en récupérant les entrées du tableau cache de cet objet, comme ceci :

1
print_r($wp_object_cache->cache['post_meta']);

Voilà tous vos champs personnalisés qui défilent!

Inutile de générer des requêtes supplémentaires pour récupérer les données des champs personnalisés. C’est bien le principe du cache. Ah, mais d’ailleurs WordPress fonctionne précisément ainsi, son objet $wp_object_cache sert à éviter de multiplier les aller-retour vers la base de données. Si vous examinez la fonction get_post_meta dans les fichiers core de WordPress, vous verrez qu’elle appelle get_metadata qui s’occupe elle-même directement de scruter dans l’objet $wp_object_cache et qu’elle ne réalise pas (sauf en l’absence de cache, justement) de nouvelle requête sur la base de données.

Bon très bien. Pourquoi je vous dis tout ça alors? Simplement pour expliquer ce qui se passe à l’arrière-plan et pourquoi, ce qui peut aider notamment quand on se pose des questions. Toutes les fonctions  get_post_meta, get_post_custom et  get_metadata s’appuient sur ce mécanisme de cache (elles vont d’abord vérifier dans l’objet cache si les données s’y trouvent et ne font de véritable requête à la base de données que dans le cas contraire). Ce sont donc des fonctions que vous pouvez utiliser de manière répétitive dans les contextes des boucles : dans une boucle qui charge une série de posts, toutes les métadonnées de tous les articles de la boucle sont mises en cache. Vous pouvez donc appeler 100 fois get_post_meta afin de récupérer des données de champs personnalisés sans paniquer : il n’y aura vraisemblablement aucun appel supplémentaire à la base de données puisque tout est déjà là, dans l’objet $wp_object_cache et ces fonctions opèrent la  vérification pour vous.

La preuve, voici le commentaire, dans le fichier core WordPress post.php, pour la fonction get_post_custom :

1
2
3
* The post meta fields are retrieved from the cache where possible, // les champs personnalisés de post sont récupérés depuis le cache dès que cela s'avère possible

* so the function is optimized to be called more than once. // la fonction est donc optimisée pour être appelée plusieurs fois

C’est tout pour aujourd’hui.

Supprimer la barre d’administration pour les utilisateurs WordPress qui ne sont pas des administrateurs
10 avril 2013Catégories : Sécurité,WordPress

par Barakadam

La barre d’administration, nouveauté apparue avec la version 3.1 de WordPress, s’affiche par défaut à la fois côté administration et côté site dès qu’un utilisateur est connecté et quels que soient ses droits d’accès. Evidemment, un simple abonné qui clique sur la barre d’administration pour passer du côté administration ne verra pas grand chose, mais son impression sera pourtant bien celle d’être « passé de l’autre côte de la barrière ».

Dans bien des cas, il est logique de faire une différence entre les utilisateurs administrateurs ou éditeurs de WordPress et les utilisateurs de plus bas niveaux (abonnés, etc.) qui accèdent à des fonctions spéciales du site Web et se distinguent en cela des utilisateurs non connectés (simples visiteurs) mais qui n’ont pour autant rien à faire du côté administration.

Pour désactiver la barre d’administration en ne l’affichant que si l’utilisateur connecté est un administrateur:

1
2
3
4
5
if (!current_user_can('manage_options')) {

add_filter('show_admin_bar', '__return_false'); // intervient sur le filtre show_admin_bar et retourne false

}

Qu’est-ce que ce __return_false? Très utile ! WordPress propose une valeur « spéciale » pour les filtres, qui permet de « court-circuiter » la chaîne des actions de filtre pour retourner directement une valeur, sans se préoccuper des éventuels traitements ultérieurs. En un mot, utiliser  __return_false, dans ce contexte (celui d’un filtre), c’est avoir la certitude que la valeur retournée sera bien false au final (et non une autre valeur, suite aux diverses modifications opérées par les fonctions ultérieures du filtre, qui auraient repris la valeur false et, en lui appliquant d’autres transformations, auraient abouti à une autre valeur).
Il en existe d’autres :  __return_true,  __return_zero ou  __return_empty_array.

Par défaut, la capacité manage_options n’est attribuée qu’aux super-administrateurs ou administrateurs. Donc pas aux éditeurs.  Si vous souhaitez l’afficher aussi pour les éditeurs, vous pouvez par exemple utiliser la capacité moderate_comments.

Référez-vous au tableau des correspondances entre capacités et rôles dans le Codex WordPress : http://codex.wordpress.org/Roles_and_Capabilities#manage_options

Sécurité : empêcher l’accès direct aux fichiers uploadés dans WordPress
9 avril 2013Catégories : Sécurité,WordPress

par Barakadam

WordPress est de plus en plus souvent utilisé comme système de gestion de contenu (CMS) et non seulement comme un moteur de blog. Selon l’un de ses concepteurs Matt Mullenweg, il serait utilisé pour la gestion de près de 15% des sites de la planète… Parfois, il est aussi utilisé pour créer des sites avec des espaces privés ou de véritables intranets dont l’accès est réservé à des utilisateurs particuliers.

Il est assez facile de définir des sections protégées dans un site WordPress, puisqu’il existe des fonctionnalités par défaut pour cela (comme le statut de visibilité « Privé » ou la protection des articles par mot de passe). Lorsqu’une page est protégée, on ne peut y accéder directement en tapant son URL. L’utilisateur est obligé de se connecter préalablement.

Le problème, c’est qu’il n’en va pas de même de tous les fichiers postés dans la page concernée. Si la page est inaccessible en tapant directement son URL, les fichiers dont l’URL est saisie peuvent être consultés sans connexion préalable. Voilà qui peut poser de sérieux problèmes dans certains cas. Voici une petite astuce simple livrée ici sur Stackexchange (http://wordpress.stackexchange.com/questions/37144/how-to-protect-uploads-if-user-is-not-logged-in) qui permet d’y parer en forçant l’utilisateur qui tente d’accéder directement à un ressource (une image, un PDF, etc.) à se connecter auparavant.

1ère étape : modifier .htaccess

Pour commencer, vous devez ajouter deux lignes au fichier .htaccess qui se trouve à la racine du site WordPress (et se trouve utilisé pour la gestion des permaliens):

1
2
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ protection.php?file=$1 [QSA,L]

Pour information, le fichier .htaccess standard d’une installation WordPress contient généralement les instructions suivantes :

1
2
3
4
5
6
7
8
9
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

2e étape : ajout d’un script php

Ensuite, ajoutez le fichier protection.php à la racine du site WordPress avec le code suivant:

1
2
3
4
5
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
<!--?php <br ?--> /*
* dl-file.php
*
* Protect uploaded files with login.
*
* @link http://wordpress.stackexchange.com/questions/37144/protect-wordpress-uploads-if-user-is-not-logged-in
*
* @author hakre <http://hakre.wordpress.com/>
* @license GPL-3.0+
* @registry SPDX
*/


require_once('wp-load.php');

is_user_logged_in() || auth_redirect();

list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);

$file = rtrim($basedir,'/').'/'.str_replace('..', '', isset($_GET[ 'file' ])?$_GET[ 'file' ]:'');
if (!$basedir || !is_file($file)) {
status_header(404);
die('404 — File not found.');
}

$mime = wp_check_filetype($file);
if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
$mime[ 'type' ] = mime_content_type( $file );

if( $mime[ 'type' ] )
$mimetype = $mime[ 'type' ];
else
$mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );

header( 'Content-Type: ' . $mimetype ); // always send this
if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
header( 'Content-Length: ' . filesize( $file ) );

$last_modified = gmdate( 'D, d M Y H:i:s', filemtime( $file ) );
$etag = '"' . md5( $last_modified ) . '"';
header( "Last-Modified: $last_modified GMT" );
header( 'ETag: ' . $etag );
header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT' );

// Support for Conditional GET
$client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false;

if( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = false;

$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
// If string is empty, return 0. If not, attempt to parse into a timestamp
$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;

// Make a timestamp for our most recent modification...
$modified_timestamp = strtotime($last_modified);

if ( ( $client_last_modified && $client_etag )
? ( ( $client_modified_timestamp >= $modified_timestamp) && ( $client_etag == $etag ) )
: ( ( $client_modified_timestamp >= $modified_timestamp) || ( $client_etag == $etag ) )
) {
status_header( 304 );
exit;
}

// If we made it this far, just serve the file
readfile( $file );

Termes, taxonomies, catégories et mots-clés: comment ça marche?
1 avril 2013Catégories : WordPress

par Barakadam

Les utilisateurs WordPress sont généralement familiarisés avec les notions de taxonomie, de catégories et de mots-clés, en tout cas pour ce qui concerne l’usage de l’interface d’administration. Pourtant, dès qu’on met les mains dans la programmation, la confusion règne parfois, pour une raison bête : on ne sait pas toujours que WordPress gère les « mots » (en anglais dans la langue de WordPress, les « terms ») utilisé dans les catégories et les mots-clés (autrement dit, dans ce qui s’appelle « les taxonomies ») de manière indépendante. Comment ça? Que cela signifie-t-il? Je l’ai expliqué dans un réponse sur StackOverflow, mais  je crois que cela vaut la peine de le réexpliquer ici, en prenant le temps d’éclaircir chaque notion.

Qu’est-ce qu’une taxonomie?

Voilà la première notion simple à comprendre. Les catégories de WordPress sont un type de taxonomie. Autrement dit, des références à des mots (des termes), hiérarchisées (les catégories sont hiérarchisées : une catégorie peut être la parente d’une autre, elle-même parente de plusieurs catégories, etc.). Les mots-clés de WordPress sont un autre type de taxonomie. Sans hiérarchie, cette fois (un mot-clé ne peut-être enregistré comme étant le parent d’un autre mot-clé : tous les mots-clés sont au même niveau).

On peut encore créer des taxonomies personnalisées (avec register_taxonomy : voir ici), pour utiliser d’autres « références de termes » que les catégories ou les mots-clés, selon la même logique (en choisissant si cette taxonomie sera hiérarchisée comme les catégories ou « plate », comme les mots-clés).

Bref. C’est assez simple.

Qu’est-ce qu’un terme?

Un « terme » est un mot ou même un ensemble de mot traité en un bloc, une « unité textuelle » de référence, utilisée dans les taxonomies. Par exemple, j’utilise pour les pages de ce site des catégories : WordPress, JW Player, Flash, etc., pour déterminer les « sujets » dont traitent les articles. « WordPress » est un « terme ». « JW Player » (les deux mots ensemble) est un terme aussi.

Qu’est-ce qu’un slug?

Dans WordPress, on appelle « slug » un identifiant qui est exprimé par des mots et non sous forme de chiffres. En sa qualité d’identifiant, le « slug » est par définition unique. S’il existe un slug appelé wordpress, il n’en existe par définition pas d’autres portant le même nom.

Ok, alors du coup plus précisément, qu’est-ce qu’un terme?

Ah oui, on peut maintenant préciser : techniquement, dans la base de données de WordPress, un terme est l’association d’un nom (nom d’affichage) et d’un slug (un nom « identifiant »).

Dans la base de données WordPress, les termes sont enregistrés dans la table wp_terms.

Les contenus des taxonomies (quels termes en font partie) sont enregistrés la table wp_term_taxonomy.

Les relations entre les posts et les termes sont enregistrés dans la table  wp_term_relationships.

Il faut donc comprendre qu’un terme peut être utilisé dans plusieurs taxonomies. Les termes sont enregistrés dans une table à part. Si un terme WordPress est utilisé à la fois dans les catégories et dans les mots-clés et que vous essayez de le modifier dans l’éditeur des catégories, par exemple, ne soyez pas surpris par le comportement de WordPress :

1. Si vous modifiez le champ « Nom » pour le mot-clé, vous modifiez le « nom d’affichage » du terme. Du coup, ce nom d’affichage, modifié dans les catégories, sera modifié aussi dans les mots-clés! Par exemple, si vous avez remplacé « Voiture » dans les catégories par « Pot de fleur », le même changement aura lieu dans les mots-clés. Et tous les articles qui étaient associés au mot-clé « Voiture » seront associés au mot-clé « Pot de fleur ». Mieux vaut être prévenu.

2. Si vous créez une nouvelle catégorie en utilisant le mot « Voiture » et que ce même mot a déjà été utilisé dans les mots-clés, WordPress le reconnaît et lui applique le même slug (par défaut : « voiture »). Si, ensuite, vous supprimez cette catégorie « Voiture » et tentez plus tard de recréer une catégorie « Camion » en essayant de lui attribuer le slug « voiture », vous ne le pourrez pas si le terme était aussi déjà utilisé dans les mots-clés : WordPress ne peut attribuer le même slug (je rappelle que le slug est un identifiant) à deux noms d’affichage. Il faut pour cela créer deux termes (et utiliser deux slugs distincts).

C’est généralement en effaçant des mots-clés ou des catégories et en tentant de les recréer plus tard, qu’on est surpris par ces restrictions liées au fait que les termes sont utilisés à plusieurs endroits et que l’on n’est donc pas complètement libre sur la manière de les renommer ou de modifier leur identifiant (slug).

Une image valant mieux que de longs discours voici une explication visuelle à partir de la structure de la base de données (cliquez sur l’image pour l’agrandir) :

wpterms_FR

Optimiser WordPress avec no_found_rows : éviter les calculs inutiles pour la pagination
26 mars 2013Catégories : Optimisation,WordPress

par Barakadam

Comme le fait remarquer Flavio Tordini sur son blog,  WordPress utilise SQL_CALC_FOUND_ROWS dans la plupart de ses requêtes, afin d’implémenter la pagination. Et cela, même lorsque vous n’utilisez pas de pagination. SQL_CALC_FOUND_ROWS demande à MySQL de réaliser des opérations supplémentaires afin de compter le nombre total de lignes trouvées, ce qui peut faire une vraie différence avec des bases de données volumineuses.

Il existe cependant un paramètre WordPress dont ne parle nulle part la documentation et qui peut être utilisé avec les fonctions get_posts et  query_posts. Ce paramètre s’appelle  no_found_rows. Il accepte les valeurs booléennes. S’il se voit attribuer la valeur  true (1), il indique à WordPress qu’il n’est pas nécessaire de compter le nombre total de lignes. Voici un exemple d’utilisation :

1
get_posts('no_found_rows=true&cat=1&numberposts=1');

Attention, si vous utilisez le paramètre no_found_rows dans les listes d’articles qui utilisent la pagination, rien ne va plus. Cette optimisation consiste justement à simplifier les requêtes qui ne sont pas destinées à être utilisées avec un affichage paginé.

Rendre un thème compatible avec WooCommerce
19 mars 2013Catégories : Traduction,WooCommerce,WordPress

par Barakadam

Voici une traduction, susceptible d’en intéresser certains, d’une page de la documentation officielle WooCommerce…

Table des matières

  1. Utiliser woocommerce_content()
  2. Utiliser des hooks
  3. Déclarer la prise en charge de WooCommerce

Si le message suivant s’affiche dans votre interface d’administration WordPress :

Votre thème ne déclare pas le support WooCommerce – si vous rencontrez des problèmes d’affichage, veuilelz lire notre guide d’intégration ou choisir un thème WooCommerce :-)

alors que vous utilisez un WooTheme, procédez à la mise à jour vers la dernière version de votre thème, en la téléchargeant depuis votre tableau de bord WooThemes. Nos thèmes WC ont tous été mis à jour afin d’offrir une prise en charge complète de WooCommerce 2.0.
En général, les modèles WooCommerce s’intègrent harmonieusement avec les thèmes WordPress. Il se peut que vous rencontriez des problèmes quand les conteneurs WooCommerce par défaut ne correspondent pas au thème que vous avez choisi. Le résultat peut être une mise en page perturbée dans les pages WooCommerce et des problèmes de position des barres latérales.

Ces problèmes sont susceptibles d’affecter la page boutique, la page de produit unique et les pages de taxonomie (catégories et mots-clés) parce que WooCommerce utilise des modèles personnels pour afficher ces pages (et il est impossible pour WooCommerce de connaître exactement le balisage que votre thème utilise). Les autres pages (règlement, panier, compte) ne sont pas affectées parce qu’elles utilisent le modèle page.php de votre thème.

Il existe deux moyens de résoudre ce problème : en utilisant des hooks (pour les utilisateurs ou développeurs avancés) ou en utilisant notre fonction attrape-tout woocommerce_content() à l’intérieur de votre thème.

Utiliser woocommerce_content()

Cette solution vous permet de créer une nouvelle page de modèle dans votre thème, qui peut être utilisée pour tout le contenu WooCommerce. C’est une solution simple et passe-partout, mais son inconvénient tient à ce que ce modèle est alors utilisé pour toutes les pages WooCommerce (les catégories de produits, la page de boutique, les produits individuels, …). Les développeurs sont invités à se servir plutôt des hooks.

Pour configurer cette page de modèle, suivez ces étapes :

Dupliquez page.php

Dupliquez le fichier page.php de votre thème et nommez-le woocommerce.php. Ce fichier devrait se trouver à l’emplacement suivant : wp-content/themes/VOTRETHEME/woocommerce.php.

Modifiez votre page (woocommerce.php)

Ouvrez votre page woocommerce.php nouvellement créée dans un éditeur de texte (ou l’éditeur de votre choix).

Remplacez la boucle

Vous devez ensuite trouver la boucle (voir La boucle). La boucle commence généralement par :

1
<?php if( have_posts() ) :

et se termine généralement par :

1
<?php endif; ?>

Ce code varie selon les thèmes. Une fois que vous l’avez trouvé, supprimez-le. A sa place, tapez ceci:

1
<?php woocommerce_content(); ?>

Ce code remplace la boucle par celle de WooCommerce. Enregistrez le fichier. Vous avez terminé.

Utiliser des hooks

La méthode des hooks est plus complexe que celle qui utilise woocommerce_content, mais elle est aussi plus flexible. Elle est similaire à celle utilisée pour développer ses propres thèmes. C’est aussi cette méthode que nous adoptons pour une intégration harmonieuse avec les thèmes Twenty Ten et Eleven.

En insérant quelques lignes dans le fichier functions.php de votre thème, commencez par délier les conteneurs WooCommerce :

1
2
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);

Ensuite, liez vos propres fonctions afin d’afficher les conteneurs que votre thème requiert:

1
2
3
4
5
6
7
8
9
10
add_action('woocommerce_before_main_content', 'my_theme_wrapper_start', 10);
add_action('woocommerce_after_main_content', 'my_theme_wrapper_end', 10);

function my_theme_wrapper_start() {
echo '<section id="main">';
}

function my_theme_wrapper_end() {
echo '</section>';
}

Assurez-vous que le balisage correspond à celui de votre thème. Si vous n’êtes pas certain des classes et des ID à utiliser, référez-vous au fichier page.php de votre thème.

Déclarer la prise en charge de WooCommerce

Une fois que vous êtes satisfait de la prise en charge de WooCommerce par votre thème, vous devez le déclarer dans le code afin de masquer le message “Votre thème ne déclare pas le support WooCommerce”. Pour cela, ajoutez la ligne suivante au fichier functions.php de votre thème :

1
add_theme_support( 'woocommerce' );

Si tout cela échoue…

Si vous ne parvenez à faire fonctionner aucune des méthodes précédentes et que vous n’avez pas de développeur sous la main, nous vous recommandons de tester nos thèmes WooCommerce afin d’en trouver un qui fonctionne d’emblée pour vous.

Youtube, Vimeo, DailyMotion, Flickr, Twitter : incorporez vos vidéos, images et sons automatiquement dans les articles WordPress
7 février 2013Catégories : Audio,Vidéo,WordPress,YouTube

par Barakadam

Le saviez-vous? Depuis WordPress 2.9, il n’est quasiment plus nécessaire de s’appuyer sur des plug-ins (ou des implémentations personnelles) pour incorporer des vidéos YouTube,  DailyMotion ou Vimeo, des images Flickr ou des sons de SoundCloud : WordPress permet d’intégrer ces éléments multimédia par défaut et qui plus est, avec une simplicité époustouflante !

La détection est automatique. Par exemple ce code tapé dans l’éditeur :

1
http://www.youtube.com/watch?v=_7CHtCiXEa8

donne automatiquement ceci !

Vous entrez l’URL de la vidéo YouTube, c’est tout ! WordPress se charge du reste.

Depuis WordPress 3.5, les incorporations automatiques sont activées par défaut et ne peuvent être désactivées par une option dans l’administration. Avant la version 3.5, une case à cocher « Incorporations automatiques » était proposée dans Administration > Réglages > Médias.

Idem pour Instagram

1
http://instagram.com/p/UjxLrxjWeh/

donne :

@lilystockman @kerentaggar

Ou encore Flickr…

1
http://www.flickr.com/photos/16887118@N04/2963550699/

donne :

Hélène Bohy et Olivier Caillard

Et la liste continue ainsi pour :

Limiter vos requêtes WordPress en ne récupérant que les identifiants (ID) des articles ou des pages
3 janvier 2013Catégories : WordPress

par Barakadam

Il y a parfois des choses si simples et pourtant si fondamentales. J’ai déjà écrit dans ce blog un article sur l’optimisation des requêtes WordPress. Si l’on observe bien des cas d’usage des boucles WordPress, on peut en fait se rendre compte qu’il est possible de les simplifier grandement.

Souvent, on exécute des requêtes de type get_posts() uniquement pour déterminer quels articles répondent à tels ou tels critères, sans qu’on ait pour autant besoin d’afficher toutes les données (et notamment le contenu) de l’article.

On ne le sait pas nécessairement, mais il existe un paramètre fields qui peut être utilisé parmi les arguments des requêtes get_posts() afin de limiter les données récupérée aux seuls identifiants (ID) des articles. C’est très utile quand la requête sert uniquement à retrouver des articles particuliers en vue d’opérer une autre action ultérieure (par exemple, en excluant les articles concernés dans la requête suivante, etc.). Dans ces cas là, les ID suffisent puisque les articles ne seront pas affichés, il est donc inutile de récupérer toutes les informations les concernant  (contenu, extrait, date de publication, etc.).

Voici comment procéder :

1
2
3
4
5
6
$args = array( 'post_type' => 'post',
'category' => 20, // Par exemple, nous cherchons tous les articles associés à la catégorie dont l'ID est 20
'fields' => 'ids',
'post_status' => 'publish',
);
$liste_articles = get_posts( $args );

Voici un exemple de résultat  :

1
Array ( [0] => 621 [1] => 626 [2] => 253 [3] => 678 [4] => 661 [5] => 650 [6] => 2049 [7] => 1821 [8] => 522 [9] => 1983 [10] => 1627 [11] => 2004 [12] => 1089 [13] => 1997 [14] => 1954 [15] => 1894 [16] => 572 [17] => 631 [18] => 811 [19] => 1748 [20] => 1930 [21] => 1933 [22] => 836 [23] => 782 [24] => 654 [25] => 771 [26] => 1928 [27] => 795 [28] => 681 [29] => 523 [30] => 634 [31] => 1906 [32] => 680 [33] => 784 [34] => 1903 [35] => 1892 [36] => 1073 [37] => 1868 [38] => 1927 [39] => 1771 [40] => 620 [41] => 1895 [42] => 677 [43] => 1896 [44] => 619 [45] => 407 [46] => 676 [47] => 1423 [48] => 1616 [49] => 1897 [50] => 1826 [51] => 1870 [52] => 1088 [53] => 519 [54] => 1878 [55] => 327 [56] => 1724 [57] => 1822 [58] => 348 [59] => 506 [60] => 656 [61] => 812 [62] => 1093 [63] => 1460 [64] => 1350 [65] => 1014 [66] => 672 [67] => 1459 [68] => 629 [69] => 738 [70] => 504 [71] => 787 [72] => 1026 [73] => 1028 [74] => 625 [75] => 627 [76] => 837 [77] => 814 [78] => 1032 [79] => 833 [80] => 563 [81] => 762 [82] => 516 [83] => 511 [84] => 515 )

Pour comparaison voici « l’objet » d’un seul de ces articles retourné par une requête standard (exemple tiré de ce blog) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
WP_Post Object ( [ID] => 662 [post_author] => 1 [post_date] => 2012-12-28 12:07:34 [post_date_gmt] => 2012-12-28 11:07:34

[post_content] => Je vous livre cette astuce simple surtout après avoir constaté avec effroi qu'il circule partout des solutions pas très orthodoxes à ce problème.

Dans les fragments de code proposés, on trouve des remove_actionqui supprime la fonction wp_admin_bar_render et finalement, font disparaître la barre d'administration non seulement côté site, mais également côté administration !

En outre, l'espace en haut de l'en-tête censé laisser la place à la barre d'administration reste toujours présent. Franchement pas propre. La solution est pourtant toute simple : [cc lang="php"] add_filter('show_admin_bar', '__return_false');  La barre d'administration sera retirée et l'espace regagné au niveau de l'en-tête... côté site! et non côté administration, fort heureusement.

Pourquoi vouloir faire une chose pareille? Le plus souvent, ce besoin survient quand on crée des sites ou utilise des thèmes qui offrent accès à des contenus aux utilisateurs connectés.

Quand ce système de connexion se fait via la gestion des utilisateurs de WordPress, on se retrouve avec la barre d'administration de WordPress, même quand un simple utilisateur "Abonné" (et non administrateur) est connecté.

Or souvent, le but est de présenter une interface "WordPress" uniquement aux administrateurs et non aux utilisateurs (même abonnés) du site...

[post_title] => Masquer la barre d'administration WordPress [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => masquer-la-barre-dadministration-wordpress [to_ping] => [pinged] => [post_modified] => 2012-12-29 21:50:54 [post_modified_gmt] => 2012-12-29 20:50:54 [post_content_filtered] => [post_parent] => 0 [guid] => http://macadamcodeboys.com/?p=662 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) WP_Post Object ( [ID] => 659 [post_author] => 2 [post_date] => 2012-12-20 10:11:32 [post_date_gmt] => 2012-12-20 09:11:32 [post_content] =>
Le problème
C'est parfois bien pratique de pouvoir rajouter un petit
dans les titres longs, pour pouvoir décider de l'emplacement du retour à la ligne. Cela marche très bien avec le champ titre des articles, pages et custom posts, mais certains widgets appliquent un traitement au champ titre qui supprime tout code HTML et PHP (avec la fonction striptags). Résultat, les balises disparaissent systématiquement lorsque l'on sauvegarde.

C'est le cas par exemple du widget "texte" par défaut.
La solution : un shortcode sur mesure pour les retours à la ligne
Comme les balises html seront supprimées, il faut utiliser un shortcode qui lui ne sera pas reconnu comme balise html et donc pas nettoyé. Il sera ensuite retransformé en la balise
par ce petit traitement facile à mettre en place (dans functions.php of course) : [cce lang='php' ] add_filter('widget_title','my_widget_title',10,3); function my_widget_title($title) { $title = str_replace("[br]", "
", $title); return $title; } Et voilà ! La fonction my_widget_title remplace le shortcode [br] par
et le tour est joué.

J'utilise [br] comme shortcode mais n'importe quoi de pas trop commun fera l'affaire (pour éviter l'interférence avec les shortcodes d'autres plugins ou thèmes). À noter : certains widgets n'utilisent pas le filtre widget_title, dans ce cas notre petit traitement ne sera pas exécuté. La solution pourrait alors passer par un autre hook, widget_display_callback, qui permet de traiter les données du widget juste avant leur affichage. C'est une action, donc il faut enregistrer la fonction callback avec add_action.

Multipliez ce résultat par le nombre d’articles de la liste précédente et vous comprendrez tout l’intérêt de bien veiller à spécifier 'fields' => 'ids' dans vos requêtes get_posts()

Seul regret : WordPress aurait pu proposer de spécifier n’importe quel champ, et non seulement les identifiants. Les valeurs pour fields sont : 'ids' (identifiants uniquement),  'id=>parent' (qui retourne un tableau associatif de type [ parent1 => ID1, parent2 => ID2...], donc permet de récupérer à la fois les ID de parent et les ID d’articles. Toute autre valeur ramène à la requête normale, qui renvoie un tableau d’objets posts (articles).

Voir aussi l’astuce avec no_found_rows.

Masquer la barre d’administration WordPress
28 décembre 2012Catégories : WordPress

par Barakadam

Je vous livre cette astuce simple surtout après avoir constaté avec effroi qu’il circule partout des solutions pas très orthodoxes à ce problème. Dans les fragments de code proposés, on trouve des remove_action qui supprime la fonction wp_admin_bar_render et finalement, font disparaître la barre d’administration non seulement côté site, mais également côté administration ! En outre, l’espace en haut de l’en-tête censé laisser la place à la barre d’administration reste toujours présent. Franchement pas propre.

La solution est pourtant toute simple :

1
add_filter('show_admin_bar', '__return_false');

La barre d’administration sera retirée et l’espace regagné au niveau de l’en-tête… côté site! et non côté administration, fort heureusement.

Pourquoi vouloir faire une chose pareille? Le plus souvent, ce besoin survient quand on crée des sites ou utilise des thèmes qui offrent accès à des contenus aux utilisateurs connectés. Quand ce système de connexion se fait via la gestion des utilisateurs de WordPress, on se retrouve avec la barre d’administration de WordPress, même quand un simple utilisateur « Abonné » (et non administrateur) est connecté. Or souvent, le but est de présenter une interface « WordPress » uniquement aux administrateurs et non aux utilisateurs (même abonnés) du site…

 

Des retours à la ligne dans les titres des widgets
20 décembre 2012Catégories : WordPress

par mr_mmmmore

Le problème

C’est parfois bien pratique de pouvoir rajouter un petit <br/> dans les titres longs, pour pouvoir décider de l’emplacement du retour à la ligne. Cela marche très bien avec le champ titre des articles, pages et custom posts, mais certains widgets appliquent un traitement au champ titre qui supprime tout code HTML et PHP (avec la fonction striptags). Résultat, les balises disparaissent systématiquement lorsque l’on sauvegarde. C’est le cas par exemple du widget « texte » par défaut.

La solution : un shortcode sur mesure
pour les retours à la ligne

Comme les balises html seront supprimées, il faut utiliser un shortcode qui lui ne sera pas reconnu comme balise html et donc pas nettoyé. Il sera ensuite retransformé en la balise <br/> par ce petit traitement facile à mettre en place (dans functions.php of course) :

1
2
3
4
5
6
add_filter('widget_title','my_widget_title',10,3);
function my_widget_title($title)
{
$title = str_replace("[br]", "<br/>", $title);
return $title;
}

Et voilà ! La fonction my_widget_title remplace le shortcode [br] par <br/> et le tour est joué. J’utilise [br] comme shortcode mais n’importe quoi de pas trop commun fera l’affaire (pour éviter l’interférence avec les shortcodes d’autres plugins ou thèmes).

À noter : certains widgets n’utilisent pas le filtre widget_title, dans ce cas notre petit traitement ne sera pas exécuté. La solution pourrait alors passer par un autre hook, widget_display_callback, qui permet de traiter les données du widget juste avant leur affichage. C’est une action, donc il faut enregistrer la fonction callback avec add_action.