Cet article est mis à jour régulièrement.
Last update : 27 septembre 2014
INDEX
Contrôler la valeur d’un paramètre natif et envoyer un message d’erreur
Supposons que l’on veuille définir un nombre minimum de posts par page (dans Réglages > Lecture) :
add_filter( 'pre_option_posts_per_page', 'check_posts_per_page' ); add_filter( 'pre_update_option_posts_per_page', 'check_posts_per_page' ); function check_posts_per_page() { if (isset($_POST['posts_per_page'])) { if (!$_POST['posts_per_page'] || $_POST['posts_per_page'] < 10) { $msg = "Erreur, le nombre minimal d'articles par page est 10, car il y a 10 positions prédéfinies dans la grille d'affichage des Actualités."; add_settings_error('posts_per_page', 'error_posts_per_page', $msg, 'error'); return 10; } else { return $_POST['posts_per_page']; } } }
Liste des Hooks filtrables de WordPress
Mettre automatiquement des espaces insécables dans les titres
function insecables_title($title) { $title = str_replace (' « ', ' « ', $title); $title = str_replace (' » ', ' » ', $title); $title = str_replace (' : ', ' : ', $title); $title = str_replace (' ? ', ' ? ', $title); $title = str_replace (' ! ', ' ! ', $title); $title = str_replace (' ; ', ' ; ', $title); $title = str_replace (' = ', ' = ', $title); $title = str_replace (' $ ', ' $ ', $title); $title = str_replace (' € ', ' $ ', $title); $title = str_replace (' £ ', ' £ ', $title); $title = str_replace (' % ', ' % ', $title); return $title; } add_filter('the_title', 'insecables_title');
Oui, ça serait + propre avec un array ou une regex, mais c'est plus lisible comme ça.
Créer automatiquement des liens hypertextes
function autoLink($text) { $pattern = "/\b((?P<protocol>(https?)|(ftp)):\/\/)?(?P<domain>[-A-Z0-9\\.]+)[.][A-Z]{2,7}(([:])?([0-9]+)?)(?P<file>\/[-A-Z0-9+&@#\/%=~_|!:,\\.;]*)?(?P<parameters>\?[A-Z0-9+&@#\/%=~_|!:,\\.;]*)?/ise"; $text = preg_replace($pattern, "' <a href=\"'.htmlspecialchars('$0').'\" target=\"_blank\">$0</a>'", $text); // fix URLs without protocols $text = preg_replace("#href='www#i", "href='https://www", $text); $text = preg_replace("#href=['\"](?!(https?|ftp)://)#i", "href='https://", $text); return $text; }
On pourrait aussi utiliser add_filter
pour appliquer automatiquement le filtre sur the_content
par exemple.
Debug WP_Query : afficher la requête MySQL
echo wordwrap($GLOBALS['wp_query']->request); // SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (2,3,4,5,14) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'recurrent' OR wp_posts.post_status = 'offline' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 2
Database locale/distante
Fichier :/wp-config.php
// ** Réglages MySQL - Votre hébergeur doit vous fournir ces informations. ** // if(strstr($_SERVER['SERVER_NAME'], '.localhost') || strstr($_SERVER['SERVER_NAME'], '192.168')) { define('DB_NAME', 'db_testXXX'); define('DB_USER', 'root'); define('DB_PASSWORD', 'root'); define('DB_HOST', 'localhost'); } else { define('DB_NAME', 'db_testXXX'); define('DB_USER', 'db_testXXX'); define('DB_PASSWORD', 'password'); define('DB_HOST', 'localhost'); } /** Jeu de caractères à utiliser par la base de données lors de la création des tables. */ define('DB_CHARSET', 'utf8'); /** Type de collation de la base de données. * N'y touchez que si vous savez ce que vous faites. */ define('DB_COLLATE', '');
Database locale/distante/staging etc... "on steroids"
<?php $configs = array( // local 'generali.localhost' => array( 'DB_NAME' => 'db_local', 'DB_USER' => 'root', 'DB_USERNAME' => 'root', 'DB_PASSWORD' => 'root', 'DB_HOST' => 'localhost', 'DB_PORT' => 3306, 'DB_COLLATE' => '', 'DB_CHARSET' => 'utf8', 'WP_ALLOW_REPAIR' => true, 'WP_DEBUG' => true, ), // staging 'staging.version-test.com' => array( 'DB_NAME' => 'db_staging', 'DB_USER' => 'db_staging', 'DB_USERNAME' => 'db_staging', 'DB_PASSWORD' => '', 'DB_HOST' => 'localhost', 'DB_PORT' => 3306, 'DB_COLLATE' => '', 'DB_CHARSET' => 'utf8', 'WP_ALLOW_REPAIR' => true, 'WP_DEBUG' => true, ), // pre-prod 'preprod.version-test.com' => array( 'DB_NAME' => 'db_preprod', 'DB_USER' => 'db_preprod', 'DB_USERNAME' => 'db_preprod', 'DB_PASSWORD' => '', 'DB_HOST' => 'localhost', 'DB_PORT' => 3306, 'DB_COLLATE' => '', 'DB_CHARSET' => 'utf8', 'WP_ALLOW_REPAIR' => true, 'WP_DEBUG' => false, ), ); foreach ($configs as $environnement => $parametres) { if(strstr($_SERVER['SERVER_NAME'], $environnement)) { define('DB_NAME', $parametres['DB_NAME']); define('DB_USER', $parametres['DB_USER']); define('DB_USERNAME', $parametres['DB_USERNAME']); define('DB_PASSWORD', $parametres['DB_PASSWORD']); define('DB_HOST', $parametres['DB_HOST']); define('DB_PORT', $parametres['DB_PORT']); define('DB_COLLATE', $parametres['DB_COLLATE']); define('DB_CHARSET', $parametres['DB_CHARSET']); define('WP_ALLOW_REPAIR', $parametres['WP_ALLOW_REPAIR']); define('WP_DEBUG', $parametres['WP_DEBUG']); define('WP_SITEURL', 'https://'.$environnement); define('WP_HOME', 'https://'.$environnement); // Fix bug WordPress erreur 404 sur blog multisite define('NOBLOGREDIRECT', 'https://'.$environnement); define('DOMAIN_CURRENT_SITE', 'https://'.$environnement); } } ?>
Créer un custom post type avec des categories
Fichier : /wp-content/themes/xxxxx/functions.php
function create_post_type() { // custom post type register_post_type('formation', array( 'label' => __('Formations'), 'singular_label' => __('Formation'), 'labels' => array( 'all_items' => __('Toutes les formations'), 'add_new_item' => __('Ajouter une nouvelle formation'), 'edit_item' => __('Éditer une formation'), 'view_item' => __('Voir la page de formation') ), 'public' => true, 'show_ui' => true, 'capability_type' => 'post', 'hierarchical' => false, 'supports' => array('title', 'editor', 'thumbnail', 'custom-fields', 'page-attributes', 'revisions', 'taxonomies') )); // custom taxonomy $labels = array( 'name' => 'Catégories Formations', 'singular_name' => 'Catégorie Formations', 'search_items' => 'Rechercher un type', 'all_items' => 'Tous les types', 'parent_item' => 'Type parent', 'parent_item_colon' => 'Type parent,', 'edit_item' => 'Editer ce type', 'update_item' => 'Mettre à jour ce type', 'add_new_item' => 'Ajouter un nouveau type', 'new_item_name' => 'Nouveau type', 'menu_name' => 'Catégories Formations' ); register_taxonomy('categorie-formation',array('formation'), array( 'hierarchical' => false, 'labels' => $labels, 'show_ui' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'categorie-formation') )); }
Lister les posts d’un custom post type (straight from the doc)
Voir sur le Codex
Fichier : n’importe quel template
$args = array( 'post_type' => 'product', 'posts_per_page' => 10 ); $loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post(); the_title(); echo '<div class="entry-content">'; the_content(); echo '</div>'; endwhile;
Lister les posts issus d’un custom post type triés par catégorie
Fichier : n’importe quel template
$post_type = 'formation'; $tax = 'categorie-formation'; $tax_terms = get_terms($tax); if ($tax_terms) : foreach ($tax_terms as $tax_term) : $args = array( 'post_type' => $post_type, "$tax" => $tax_term->slug, 'post_status' => 'publish', 'posts_per_page' => -1, 'caller_get_posts'=> 1 ); $my_query = null; $my_query = new WP_Query($args); if( $my_query->have_posts() ) : ?> <h1>Catégorie : <?php echo $tax_term->name ?></h1> <ul> <?php while ($my_query->have_posts()) : $my_query->the_post(); ?> <li><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></li> <?php endwhile; ?> </ul> <?php wp_reset_query(); endif; // have_posts endforeach; // tax_terms endif; // tax_term
Lister rapidement les termes d’une taxonomie
Fichier : n’importe quel template
<pre> <?php $taxonomy = 'categorie-formation'; $tax_terms = get_terms($taxonomy); foreach ($tax_terms as $tax_term) { //echo $tax_term->name; print_r($tax_term); } ?> </pre>
Ajouter des tailles d’images personnalisées
Fichier : /wp-content/themes/xxxxx/functions.php
add_image_size( 'sidebar', 156, 104, true ); //(cropped) add_image_size( 'collaborateur', 181, 181, true ); //(cropped) add_image_size( 'hp_consult', 83, 83, true ); //(cropped)
Plugin pour reconstruire les thumbnails en fonction des tailles d’images personnalisées AJAX Thumbnail Rebuild est un bon plugin qui fait ce job. Une fois installé et activé, il vient se loger dans le menu Outils. Il est possible de choisir les tailles que l’on veut reconstruire (pratique si on vient d’en ajouter une nouvelle, cf. ancre ci-dessus), et si on veut redimensionner toutes les images ou seulement les featured ("Image à la une").
Le meilleur plugin de pagination
WP-PageNavi remplace les simples liens par défaut de WordPress "Older posts / Newer posts" par une barre de pagination configurable.
Plugin pour personnaliser l’usabilité de TinyMCE
TinyMCE sert de fondation à la barre de mise en forme WYSIWYG de WordPress.
Pour configurer simplement les outils disponibles, j’ai opté pour le plugin TinyMCE Advanced. Il permet simplement d’ajouter/supprimer des boutons à la barre.
Configurer les Styles et les Formats de TinyMCE
Les menus roulants éponymes permettent de choisir parmi des styles libres, et des mises en formes prédéfinies (balises <h1>
- <h6>
, <p>
, <pre>
, etc...)
Pour configurer quels sont les styles accessibles, il faut le définir en dur.
Fichier : /wp-content/themes/xxxxx/functions.php
function themeit_mce_buttons_2( $buttons ) { array_unshift( $buttons, 'styleselect' ); return $buttons; } add_filter( 'mce_buttons_2', 'themeit_mce_buttons_2' ); function themeit_tiny_mce_before_init( $settings ) { $settings['theme_advanced_blockformats'] = 'p,a,h2,h3,h4,'; $style_formats = array( array( 'title' => 'Button', 'inline' => 'span', 'classes' => 'button' ), array( 'title' => 'Green Button', 'inline' => 'span', 'classes' => 'button button-green' ), array( 'title' => 'Rounded Button', 'inline' => 'span', 'classes' => 'button button-rounded' ), array( 'title' => 'Other Options' ), array( 'title' => '½ Col.', 'block' => 'div', 'classes' => 'one-half' ), array( 'title' => '½ Col. Last', 'block' => 'div', 'classes' => 'one-half last' ), array( 'title' => 'Callout Box', 'block' => 'div', 'classes' => 'callout-box' ), array( 'title' => 'Highlight', 'inline' => 'span', 'classes' => 'highlight' ) ); $settings['style_formats'] = json_encode( $style_formats ); return $settings; } add_filter( 'tiny_mce_before_init', 'themeit_tiny_mce_before_init' );
On voit bien dans le tableau $settings['theme_advanced_blockformats']
qu’il manque, par exemple, le <h1>
(celui-ci est réservé au titre principal de l’article, qui par définition n’a pas sa place dans le cartouche WYSIWYG).
Les éléments qui peuplent le tableau $style_formats
doivent bien entendu correspondre avec les classes définies dans votre CSS.
Plugin permet d’avoir un Excerpt sur une Page (en plus d’un Post)
Il s’agit du bien nommé Page Excerpt, dont l’utilisation simplissime se passe de commentaire. Ce truc devrait être inclus dans la distribution par défaut.
Plugin permettant l’exécution du code PHP
Plus ou moins safe que ça soit, c’est parfois indispensable.
Le plugin qui fait foi dans le métier est Exec-PHP
À noter : une fois activé, un warning s’affichera dans le back-office pour tous les utilisateurs. Ce message peut etre désactivé par l’utilisateur directement :
- se rendre dans son profil
- décocher la case correspondante en bas de page
Le plus simple et flexible des plugins de formulaire de contact
Une fois de plus la simplicité commence par son nom : Contact Form 7 fait le job.
Mettre un label
sur les champs par défaut :
<p> <label for="your-name">Votre nom</label> [text* your-name] </p>
Mettre un placeholder :
<p> [text* your-name placeholder:'Votre nom'] </p>
Un bon skin de formulaire : https://tympanus.net/codrops/2012/03/27/login-and-registration-form-with-html5-and-css3
Créer un template
Voir sur le Codex
Fichier : /wp-content/themes/xxxxx/template-homepage.php
<?php /* Template Name: Homepage */ ?> <?php get_header(); ?> <?php if (have_posts()) : while (have_posts()) : the_post();?> <div class="post"> <h2 id="post-<?php the_ID(); ?>"><?php the_title();?></h2> <div class="entrytext"> <?php the_content('<p class="serif">Read the rest of this page »</p>'); ?> </div> </div> <?php endwhile; endif; ?> <?php get_footer(); ?>
Récupérer la valeur d’un custom field (champ personnalisé)
Voir sur le Codex
Dans l’article courant :
<?php echo get_post_meta(get_the_ID(), 'deadline', true); ?>
Variables / Valeurs / Liens fréquemment utilisées
// retourne l'URI du thème courant <?php echo get_template_directory_uri(); ?>
// récupère le permalink d'un Post <?php echo get_permalink($post_id); ?> // récupère le permalink d'un Post par son slug (et non par son ID) <?php echo get_permalink(get_page_by_path('connexion')) ?>
// récupère le titre d'un Post/Page hors de la Loop <?php echo get_the_title($post_id); ?>
// récupère l'URI de l'image à la une ({featured image}) d'un Post/Page hors de la Loop <?php echo wp_get_attachment_url(get_post_thumbnail_id(8)) ?> // Logout and Redirect to Current Page // Logout and Redirect to Homepage // charge le contenu d'une Page hors de la Loop <?php $id = 8; $p = get_page($id); echo apply_filters('the_content', $p->post_content); ?> // NB : il est impossible de passer directement l'ID à get_page(), il lui faut une variable
<?php $blog_title = get_bloginfo('name'); ?>
<!-- navigation --> <nav> <ul id="nav"> <li <?php if ( is_home() || is_single() || is_search() || is_archive() ) : ?>class="active"<?php endif; ?>><a href="<?php echo home_url( '/' ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home">Accueil</a></li> <?php $list_pages = array(53,56,67,27,65); foreach ($list_pages as $page_id) : ?> <li <?php if ( is_page($page_id) ) : ?>class="active"<?php endif; ?>><a href="<?php echo get_permalink($page_id) ?>"><?php echo get_post_meta($page_id, 'titre menu header', true) ? get_post_meta($page_id, 'titre menu header', true) : get_the_title($page_id) ?></a></li> <?php endforeach ?> </ul> </nav>
Accéder à la base de données de WordPress dans une autre application
Fichier : /wp-content/themes/xxx/lib/app.php
<?php define('WP_USE_THEMES', false); require_once($_SERVER['DOCUMENT_ROOT'].'/wp-load.php'); require_once(dirname(__FILE__) . '/ez_SQL/ez_sql_core.php'); require_once(dirname(__FILE__) . '/ez_SQL/ez_sql_mysql.php'); $db = new ezSQL_mysql(DB_USER,DB_PASSWORD,DB_NAME,DB_HOST); $db->query("SET NAMES UTF8"); $users = $db->get_results("SELECT * FROM wp_users"); foreach ($users as $user) { echo $user->user_email; echo $user->user_login; echo "<br>"; } ?>
Il n’aura échappé à personne que ce script utilise la supercalifragilisticexpialidociousement pratique classe EZ SQL de Justin Vincent
Pour notre utilisation, les fichiers inclus sont :
Fichier : /wp-content/themes/xxx/lib/ez_SQL/ez_sql_core.php
Fichier : /wp-content/themes/xxx/lib/ez_SQL/ez_sql_mysql.php