12 secrets du functions.php de WordPress

Vous le savez sans doute, WordPress est un CMS génial et hautement personnalisable. Cet article vise à synthétiser les snippets de code bien utiles qui permettent d’adapter WordPress à nos moindre désirs. Ajouter, modifier, enlever des fonctionnalités, tout est possible !

Beaucoup des ces fonctionnalités sont disponibles via des plugins, cependant, les plugins ralentissent le site. Lorsque les fonctionnalités sont simples et n’ont pas vocations à être modifiées, autant passer par le code. Cependant, rassurez-vous, j’ai moi aussi quelques plugins indispensables.

Ajouter un fil d’ariane

Le fil d’Ariane, ou breadcrumb permet à l’internaute de lui rappeler où il se situe dans le site et de facilement remonter aux niveaux hiérarchiques supérieurs. Le breadcrumb n’est pas une fonctionnalité native de WordPress, cependant, il est facile de l’ajouter. Il suffit pour cela d’ajouter dans le functions.php du thème le code suivant.

function the_breadcrumb() {
  global $post;

  if (!is_home()) {
      echo '<a href="/">Home</a>';

      if (is_category() || is_single()) {
        echo " / ";
        $cats = get_the_category($post->ID);

        foreach ($cats as $cat) {
            echo $cat->cat_name;
            echo " / ";
        }
        
        if (is_single()) {
          the_title();
        }
      }
      
      elseif (is_page()) {

        if ($post->post_parent) {
          $anc = get_post_ancestors($post->ID);
          $anc_link = get_page_link($post->post_parent);

          foreach ($anc as $ancestor) {
            $output = " / <a href=".$anc_link.">".get_the_title($ancestor)."</a> / ";
          }

          echo $output;
          the_title();
        }
        
        else {
          echo ' / ';
          echo the_title();
        }
      }
  }
      
  elseif (is_tag()) {single_tag_title();}
  elseif (is_day()) {echo"Archive: "; the_time('F jS, Y'); echo'</li>';}
  elseif (is_month()) {echo"Archive: "; the_time('F, Y'); echo'</li>';}
  elseif (is_year()) {echo"Archive: "; the_time('Y'); echo'</li>';}
  elseif (is_author()) {echo"Author's archive: "; echo'</li>';}
  elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {echo "Blogarchive: "; echo'';}
  elseif (is_search()) {echo"Search results: ";}
}

Enfin, dans les templates de page où vous voulez afficher le breadcrumb, vous n’avez plus qu’à appeler la fonction the_breadcrumb()

Ajouter une pagination en bas des pages

Il y a un moment où à force d’écrire, vous vous trouvez avec de nombreux articles. Il faut alors un moyen pour vos visiteurs de passer de votre page d’accueil à la page deux de la liste de vos articles. Idem pour les pages d’articles par auteur, catégorie…

function html5wp_pagination() {
  global $wp_query;
  $big = 999999999;
  echo paginate_links(array(
    'base' => str_replace($big, '%#%', get_pagenum_link($big)),
    'format' => '?paged=%#%',
    'current' => max(1, get_query_var('paged')),
    'total' => $wp_query->max_num_pages
  ));
}

Dans les templates de pages concernés, vous n’avez plus qu’à faire un petit appel à la fonction html5wp_pagination(). Comme son nom l’indique, cette fonction fait partie du framework html5_blank, que je recommande.

Comptez (seulement) le nombre de commentaires

Qu’est-ce que je veux dire par là ? Souvent, on affiche le nombre de commentaires pour un article. Seulement, la fonction native de WordPress get_comments_number() retourne le nombre de commentaires incluant les pingbacks et les trackbacks. Ce qui n’est pas tout à fait juste lorsque l’on parle seulement des commentaires et qui peut, dans certains cas, donner des résultats vraiment très différents du nombre de commentaires réel.

function comment_count($count) {
  global $id;
  $comment_count = 0;
  $comments = get_approved_comments($id);
  foreach ($comments as $comment) {
    if ($comment->comment_type === '') {
      $comment_count++;
    }
  }
  return $comment_count;
}

// on ajoute ensuite cette fonction en tant que filtre
add_filter('get_comments_number', 'comment_count', 0);

Et voilà, get_comments_number() retourne dorénavant le nombre de commentaires sans trackbacks et pinbacks !

Définir la tailles des images

Selon le thème que l’on bâti et son utilisation, la tailles des miniatures que l’on peut ensuite choisir via le gestionnaire des médias peut venir à être personnalisé. On peut donc définir les tailles par défaut pour small, médium et large, ainsi qu’ajouter des dimensions personnalisées.

// add_image_size($name, $width, $height, $crop);

// lorsqu'on ne précise que la hauteur ou que la largeur
// la dimension non renseignée est ajustée proportionnellement 
add_image_size('large', 700, '', true);
add_image_size('medium', 285, '', true);
add_image_size('small', 150, 150, true);

// ajoute une taille personnalisée 
add_image_size('slideshow', 1500, 200, true);

Gardez à l’esprit que lorsque vous ajoutez une dimension personnalisée, cela créé une miniature supplémentaire de la taille indiquée à chaque fois que vous importez une image dans WordPress. Attention donc à ne pas trop en ajouter pour ne pas saturer votre serveur.

Désactiver les responsives images (srcset)

Depuis la version 4, WordPress active automatiquement le support des srcset. Il s’agit de la norme html5 pour avoir des images responsives adaptées à la taille et définition de l’écran du terminal. Ainsi, vous ne chargez pas une image de 500k destinée aux desktops avec écran de 5k à super haute densité de pixels sur un smartphone avec un écran de 320px de large… Pour plus de détails sur le fonctionnement du srcset, vous pouvez lire l’article d’Aslacréation sur le sujet.

Donc sur le papier, c’est super. Sauf que… En réalité, si votre thème n’est pas adapté, cela peut provoquer des défauts d’affichage. Il est alors possible de désactiver la fonctionnalité et de n’utiliser que la bonne vieille balise <img src="…"> sans fioritures.

add_filter('wp_calculate_image_srcset_meta', '__return_null');

Écraser les images originales

Il arrive souvent que les utilisateurs finaux ne pensent pas à compresser leurs images avant de les mettre en ligne. N’importe quel smartphone fait aujourd’hui des photos d’environ 3 méga, je ne parle pas des APN et réflexe qui ont vite fait de sortir des jpegs de 20MB…

En plus de ne pas penser à compresser leurs photos, ces utilisateurs insèrent parfois l’image originale en lieu et place de la « large » ou « moyenne »… Cette pratique est doublement désastreuse pour le temps de chargement des pages ainsi que pour l’espace occupé sur le serveur. Il vaut donc parfois mieux tout bonnement remplacer l’image originale par l’image correspondant à la taille « grande » sur le serveur.

function replace_uploaded_image($image_data) {
  // dans le cas où la taille "large" n'est pas définie
  if (!isset($image_data['sizes']['large'])) return $image_data;
 
  // chemin des images uploadées
  $upload_dir = wp_upload_dir();
  $uploaded_image_location = $upload_dir['basedir'] . '/' .$image_data['file'];
  $large_image_location = $upload_dir['path'] . '/'.$image_data['sizes']['large']['file'];

  // on efface l'image uploadée
  unlink($uploaded_image_location);
 
  // on renomme l'image "large"
  rename($large_image_location, $uploaded_image_location);
 
  // on met à jour les metas et on les retourne
  $image_data['width'] = $image_data['sizes']['large']['width'];
  $image_data['height'] = $image_data['sizes']['large']['height'];
  unset($image_data['sizes']['large']);
 
  return $image_data;
}

// on ajoute notre fonction
add_filter('wp_generate_attachment_metadata','replace_uploaded_image');

Optimisations

Au rang des optimisations diverses, que ce soit concernant les performances ou la syntaxe HTML, de nombreux petits morceaux de codes sont également profitables.

// enlève le code injecté pour les emojis
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles'); 

// Enlève 'text/css' des feuille de styles dans head (text/css n'est pas requis en HTML5)
function html5_style_remove($tag) {
  return preg_replace('~\s+type=["\'][^"\']++["\']~', '', $tag);
}

// Enlève les attributs width et height des images insérées
// (empêche le redimensionnement fluide des images)
function remove_thumbnail_dimensions($html) {
  $html = preg_replace('/(width|height)=\"\d*\"\s/', "", $html);
  return $html;
}

// Débarrasse le head des styles css des commentaires récents
function my_remove_recent_comments_style() {
  global $wp_widget_factory;
  remove_action('wp_head', array(
    $wp_widget_factory->widgets['WP_Widget_Recent_Comments'],
    'recent_comments_style'
  ));
}

// Débarrasse les li du menu de navigation des class et ID injectés
function my_css_attributes_filter($var) {
  return is_array($var) ? array() : '';
}

// enlève l'injection de l'admin bar pour les utilisateurs connectés
function remove_admin_bar() {
  return false;
}

if (function_exists('add_theme_support')) {
  // ajoute la fonction d'image à la une
  add_theme_support('post-thumbnails');
}

// il est maintenant temps d'appliquer ces fonctions !

// my_css_attributes_filter peut être appliqué indépendemment à plusieurs endroits
// on peut par exemple choisir de n'enlever que les IDs et de conserver les class dans le menu
// cela permet d'appliquer un style en CSS à la page actuellement visitée grâce à la classe "current_page_item"
add_filter('nav_menu_css_class', 'my_css_attributes_filter', 100, 1);
add_filter('nav_menu_item_id', 'my_css_attributes_filter', 100, 1);
add_filter('page_css_class', 'my_css_attributes_filter', 100, 1);

// on enlève ici "width et "height" des images insérées automatiquements ainsi que par l'éditeur
add_filter('post_thumbnail_html', 'remove_thumbnail_dimensions', 10);
add_filter('image_send_to_editor', 'remove_thumbnail_dimensions', 10);

// permet de désactiver la fonctionnalité d'ajout automatique de HTML
// utile si vous tapez vos articles directement en html dans l'éditeur
remove_filter('the_excerpt', 'wpautop');
remove_filter('the_content', 'wpautop');

add_filter('style_loader_tag', 'html5_style_remove');

// enlève la barre d'administration lorsqu'on visite le site (même pour les users connectés)
add_filter('show_admin_bar', 'remove_admin_bar');

Cet article n’a pas vocation à être exhaustif. Cependant, n’hésitez pas à me faire part de vos petites astuces !

Il n'y a pas encore de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *