Apache not starting and no message in error log?
2 octobre 2014Catégories : Non classé

par mr_mmmmore

A really frustrating situation: Apache refuses to start and the Apache error log says nothing about it.

In many cases, Apache will fail to start up and will write nothing about it in the error log. Without information about what went wrong, troubleshooting might turn into a nightmare.

In such situations, trying to start manually from the command line may give clues about what goes wrong.

Start Apache manually:

apachectl start

Another option would be to test the configuration files with the command:

apachectl -t

 

Envoyer des e-mails test avec Woocommerce
17 septembre 2013Catégories : WooCommerce,WordPress

par Barakadam

Woocommerce permet de créer des e-mails personnalisés grâce à un système de modèles » (templates) très bien conçu. Les modèles par défaut figurent dans le dossier de plug-in Woocommerce et incluent un certain nombre de paramètres programmés (logo, couleur du texte, du fond, etc.) qui se répercutent directement dedans. Quand il s’agit de personnaliser plus encore l’apparence des emails (ou même leur contenu), il suffit de copier les fichiers de modèle situés dans /plugins/woocommerce/templates/emails/ vers un dossier /woocommerce/emails/ placé à l’intérieur de votre dossier de thème.

Problème : l’ajustement des mises en forme d’e-mails est bien plus délicate encore que celle de pages web pour un affichage dans tous les navigateurs. Pour obtenir le même rendu ou un rendu également satisfaisant dans Outlook, Gmail, Thunderbird et autres webmails à la fois, il faut faire beaucoup de vérifications. D’où la question : comment envoyer répétitivement des e-mails depuis Woocommerce. Aucun  bouton ne le permet dans la page de réglages des modèles d’e-mail.

Une solution simple : créer une commande dans votre boutique, puis accédez à la fiche de la commande.

En haut à droite de la page de modification de la commande, vous trouverez un petit bloc « Actions sur la commande », qui permet notamment de renvoyer les différents types d’emails liés à la commande.

WC1

Pas besoin donc de refaire des commandes répétitives pour recréer des emails. Sélectionnez répétitivement l’option de votre choix, cliquez sur le petit bouton Actualiser et pan ! l’email est envoyé…

 

 

L’accès au login WordPress est horriblement lent!
3 septembre 2013Catégories : Optimisation,WordPress

par Barakadam

Voici un phénomène étrange, qu’il m’est arrivé de rencontrer plusieurs fois avec des sites WordPress : la réactivité est très bonne côté site, les pages s’affichent très rapidement et le temps de chargement est bon, mais en accédant au login pour entrer dans l’interface d’administration, WordPress se met soudain à mouliner indéfiniment.

Les mêmes causes produisent les mêmes effets, certes, mais un même effet n’a pas toujours la même cause : l’effet décrit, il faut avoir maintenant qu’il peut avoir des causes diverses selon les cas. Certaines causes sont cependant plus probables que d’autres et en voici deux qui valent la peine d’être vérifiées et peuvent résoudre très rapidement votre problème.

Possibilité n°1 : un plug-in récemment installé?

La cause peut être un plug-in récemment installé. Certains plug-ins opèrent en effet des recherches de mise à jour dès l’initialisation de l’admin – problème : si le site de l’éditeur du plug-in est en berne, l’attente du résultat fait mouliner WordPress – le plug-in étant accroché au « hook » d’initialisation de l’admin, il embarque avec lui tout ce qui suit et provoque un délai indéfini qui pénalise tout le monde. Réfléchissez donc au derniers plug-ins installés.

Possibilité n°1 bis : CMS Tree Page View

Voilà un plug-in très intéressant qui propose un affichage de la liste des pages WordPress très élégant et plus pratique que l’affichage par défaut. En apparence tout va bien.

Malheureusement, ce plug-in peut donner de mauvaises idées, par exemple en laissant croire qu’on peut ainsi utiliser un site WordPress avec des centaines de pages : pratique, c’est hiérarchique, bien organisé, comme des dossiers sous Windows ! Certes, mais il y a un hic : comme elles sont hiérarchiques, les pages requièrent des requêtes très complexes pour en dresser la liste. Paginer les résultats, c’est bien beau (c’est ce que fait WordPress dans l’affichage par défaut Pages > Toutes les pages), mais il faut quand même parcourir toutes les pages pour déterminer les relations de dépendances des unes aux autres et afficher dans le bon ordre les pages dépendantes.

Et CMS Tree Page View fait plus encore : il affiche toutes les pages dans une unique arborescence exhaustive. Très pratique: on peut cliquer pour dérouler les sous-pages, etc., mais la requête pour produire cette liste est très coûteuse. Et pis ! Le plug-in permet maintenant d’utiliser cet affichage amélioré avec toutes sortes de posts, dont les custom posts types ou les articles standard. Et là, c’est le début de la fin. Faites un essai avec un site bourré de custom post types ou d’articles : cochez ces options d’affichage en liste dans les réglages de CMS Tree Page View: je vous garantis un accès difficile à l’admin (en attendant peut-être des optimisations dans de prochaines versions du plug-in ? Aujourd’hui : 1.2.13).

Alors la solution? Désinstallez le plug-in ou, à tout le moins, ne l’installez que pour les posts hiérarchiques (pages) : et rappelez-vous que WordPress n’est pas fait (ou pas optimisé) pour gérer des centaines de posts hiérarchiques.

Une autre possibilité moins attendue, mais bien réelle : la base de données doit être réparée ou optimisée…

Les bases de données WordPress travaillent de manière conséquente en raison de très nombreuses interactions dues à l’activité sur le site, aux commentaires, aux réorganisations des pages, aux effets de plug-ins, des options, etc. Dans certains cas, la solution magique consiste à faire une petite opération d’optimisation. Je l’ai personnellement expérimenté, à ma grande surprise : un site auquel on ne parvenait plus à se connecter (mais qui s’affichait parfaitement) s’est trouvé débloqué. Voici les étapes à suivre:

  1. Direction phpmyadmin
  2. Sélectionnez toutes les tables WordPress opt1
  3. Cliquez sur « Réparer la table »opt2
  4. Sélectionnez à nouveau toutes les tables, puis cliquez sur « Optimiser la table »opt3

Comment WordPress mémorise-t-il le modèle associé à une page?
29 mai 2013Catégories : WordPress

par Barakadam

Voilà une question bien tirée par les cheveux, me direz-vous, mais elle a toute son importance en termes de conséquences sur la gestion de vos modèles… Je commence donc par bien expliquer la question (ou mieux la poser).

Les modèles de page

Que sont les modèles de page? Il s’agit de modèles (ou templates) que l’on inclut dans le dossier d’un thème WordPress et qui incluent, au début du fichier, quelques lignes de commentaires qui déclarent notamment le nom du modèle, comme ceci:

1
2
3
/*
Template Name:  Modèle de page avec en-tête et sans menu
*/

Dès que ce fichier est placé dans le dossier du thème WordPress, il devient possible de sélectionner le modèle nommé dans la liste déroulante Modèle dans l’administration WordPress :

modeles2

C’est un moyen très utile de pouvoir appliquer un même modèle de page, de manière sélective, à une série de pages dans un site WordPress.

Ce fichier de modèle de page peut porter n’importe quel nom (mapage.php, monmodele.php, cequevousvoulez.php), il sera listé par son nom (défini par la ligne de commentaire commençant par Template Name).

Que se passe-t-il si on change un modèle de page?

La grande question qui se pose ensuite, en termes de maintenance de site, est de savoir ce qui arrive quand on doit changer un modèle de page. Que se passe-t-il si je modifie le titre indiqué dans le commentaire après Template Name ? Que se passe-t-il si je renomme mon fichier de modèle en l’appelant montemplate.php alors qu’il s’appelait avant monmodele.php ? Vous avez déjà « associé » le modèle à des dizaines de page dans WordPress, que va-t-il se passer? Les liaisons vont-elles être perdues?

D’où la question, bien posée : « Comment WordPress mémorise-t-il le modèle associé à une page?  »

Réponse : il enregistre le chemin du fichier (avec le nom de fichier). La preuve :

modeles

La conséquence est simple :

1. Si vous changez le « titre » du modèle  (en modifiant le commentaire après Template Name), vous verrez un nouveau titre apparaître dans toutes les pages WordPress qui sont associées à ce modèle et la liaison ne sera pas rompue.

2. Si vous changez le nom du fichier ou son emplacement, vous rompez la liaison entre les pages qui étaient associées au modèle et le modèle.

Il importe donc moins de bien nommer le titre du modèle dans son commentaire (ce qui peut être changé à tout moment sans risque) que de choisir adéquatement son nom de fichier et son emplacement.

 

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.