Añadir class a la lista de categorías descriptivo en WordPress

Uno de las cosas que no me gustan de WordPress es la costumbre de añadir las clases a los elementos basados en el ID del mismo y no en su slug. Esto ocurre en todo, pero en este caso es con la lista de categorías generadas por wp_list_categories, devolviendo un HTML parecido a este:

  • Mi categor&iactute;a
  • Si queremos indicar estilos específicos para estas categorías, por ejemplo para añadir un icono a cada categoría, no nos sirve el class basado en ID, porque nos encontramos con que dependiendo de cuando se genere esta categoría, habrá que cambiar el css, siendo más lógico obtener un código como este:

  • Mi categor&iactute;a
  • Para poder conseguir esto, deberíamos añadir en nuestro functions.php lo siguiente.

    
    add_filter('wp_list_categories', 'mete_slug_en_class', 10, 2);
    function mete_slug_en_class($output, $args) {
      return preg_replace_callback('#]+)class="([^"]+)"([^>]*)>]+)>([^<]+)<\/a>#', function($m) {
        return ''.$m[5].'';
      }, $output);
    }
    
    |

    Añadir clase a la imagen destacada de WordPress según el tamaño

    Hace bastante que no escribía, sobre todo por falta de tiempo, pero quería escribir sobre este pequeño truco de WordPress. Cuando añadimos una imagen destacada en un post de WordPress nos podemos encontrar con que la imagen ocupa todo el ancho (lo más normal) o que no ocupa tanto, con lo que nos encontramos que la imagen queda muy sola y el diseño queda feo.

    Para solucionar esto, deberemos añadir un filtro, comprobar el tamaño de la imagen y el del ancho del contenido y en el caso de que creamos que es conveniente (por ejemplo la mitad del ancho del contenido) añadir una clase a la imagen:

    function mi_post_thumbnail_html($html) {
      // Se suele recomendar definir la variable $content_width para ocasiones como esta
      global $content_width;
      preg_match('#width="([^"]+)"#', $html, $s);
      if (isset($s[1]) && $s[1] < $content_width/2) {
        preg_match('#class="([^"]+)"#', $html, $c);
        if (isset($c[1]) && strpos($c[1], "right") === FALSE) {
          return str_replace('class="'.$c[1].'"', 'class="'.$c[1].' right"', $html);
        }
      }
      return $html;
    }
    add_filter('post_thumbnail_html', 'mi_post_thumbnail_html');

    Realizar búsquedas en WordPress únicamente por el título

    Si por un casual necesitas que tu WordPress realice las búsquedas por el título del post y que ignore el contenido, tan sólo hay que añadir un filtro a tu functions.php, lo cual también sirve para editar las condiciones de búsquedas y añadirle o quitarle condiciones:

    add_filter('posts_search', 'mi_search_title');
    function mi_search_title($search) {
      preg_match('/%([^%]+)%/', $search, $m);
      if (isset($m[1])) {
        // Original
        // " AND (((wp_posts.post_title LIKE '%termino%') OR (wp_posts.post_content LIKE '%termino%')))  AND (wp_posts.post_password = '') "
        return " AND wp_posts.post_title LIKE '%$m[1]%' AND (wp_posts.post_password = '') ";
      } else {
        return $search;
      }
    }

    Modificar las búsquedas en WordPress

    Si queremos modificar las búsquedas que ofrece WordPress para que devuelva lo que nosotros queremos tan solo hay que hacer dos funciones para dos filtros:

    add_filter('posts_results', 'mi_search');
    function mi_search($posts) {
      $s = get_query_var('s');
      if (condicion($s)) {
        $posts = array();
        $paged = intval(get_query_var('paged'));
        if ($paged < 1) $paged = 1;
        $posts_per_page = intval(get_query_var('posts_per_page'));
        $from = ($paged-1)*$posts_per_page;
        global $wpdb;
        $_posts = $wpdb->get_results("select post_id from $wpdb->posts where loquesea order by post_id desc limit $from, $posts_per_page");
        foreach($_posts as $p) {
          $posts[] = get_post($p->post_id);
        }
      }
      return $posts;
    }
    
    add_filter('found_posts', 'mi_found_posts');
    function mi_found_posts($n) {
      $s = get_query_var('s');
      if (condicion($s)) {
        global $wpdb;
        $res = $wpdb->get_results("select count(*) as n from $wpdb->posts where condicion ");
        $n = $res[0]->n;
      }
    
      return $n;
    }