Seleccionar qué posts mostrar en WordPress

22 Mar
2011

Si estamos creando un tema personalizado en WordPress, quizá queramos mostrar sólo unos posts determinados en una zona concreta. Por ejemplo, podemos necesitar mostrar sólo los posts que consideremos importantes en la portada, o quizá tengamos un apartado lateral donde sólo nos interesan mostrar los posts que hablan de nuestra empresa, etc.

Hay varias soluciones, unas que son más sencillas y otras que, aunque más complejas, tiene mayor flexibilidad. Para que sea más fácil de entender, vamos a centrarnos en cómo hacerlo para los posts generados en el index, aunque es fácil trasladar la solución para un sidebar o cualquier otra sección de la web.

1. Seleccionar posts por categorías

En primer lugar deberíamos añadir una categoría en la que incluiremos los posts que queremos mostrar en la portada. Una vez creada, podemos ver su slug en el listado y su ID en el enlace de edición de la categoría (es el valor del parámetro cat_ID de la url).

La función que Worpdress utiliza para seleccionar los posts para mostrar es query_posts. Como vemos en la referencia de wordpress.org, podemos utilizar varios parámetros para definir la selección. En este caso nos interesa uno de los que filtran por categoría. Existen más parámetros que nos permiten realizar filtrados más complejos, pero para este ejemplo utilizaremos el más sencillo:

category_name (string) – el parámetro indica el slug (ojo, no el nombre) de la categoría cuyos posts queremos obtener.

Por tanto, simplemente modificando la función en el archivo de nuestro tema (el index.php o el archivo que utilicemos como plantilla para la portada):

query_posts('category_name=destacados');

obtendremos solamente los posts que pertenezcan a esta categoría.

Aunque es una solución sencilla, la contra es que puede que estemos utilizando una categoría simplemente para filtrar posts, y no para categorizarlos, con lo que ello conlleva.

2. Seleccionar posts por tags

Si no queremos utilizar una categoría, podremos utilizar un tag o etiqueta para marcar los posts que queremos visualizar. La solución es idéntica a la anterior, simplemente la función quedaría:

query_posts('tag=destacado');

Esta es la opción más sencilla, pero de nuevo podemos ver la referencia de la función respecto a tags si necesitamos utilizar filtrados más complejos. Podemos incluso utilizar un filtrado por categoría y por etiqueta simultáneamente.

E igual que en el anterior caso, la solución es sencilla pero puede que estemos utilizando una etiqueta sólo para filtrar posts en un determinado lugar.

3. Marcar explícitamente los posts a través de un checkbox en el backend

La solución más compleja pero funcional y flexible pasa por añadir un checkbox en el panel de edición del post que sirva para establecer una meta_key de Worpdress en los posts que queramos incluír en la portada.

Crear un checkbox en el backend

El archivo del tema functions.php define la configuración de nuestro tema. Podemos incluír en él acciones definidas por WordPress. En este caso, necesitamos ejecutar una función a través de la acción add_meta_boxes, por lo que en nuestro functions.php añadiremos:

add_action('add_meta_boxes', 'add_checkbox_portada');

Con lo que le indicamos a WordPress que en el momento de añadir meta boxes, se acuerde de nuestra función add_checkbox_portada. ¿Y qué queremos que haga? Pues añadir una meta box:

function add_checkbox_portada() {
	add_meta_box('es_portada', 'En portada', 'print_checkbox_portada', 'post', 'side');
}

Puedes consultar la referencia de esta función para ver los parámetros, aunque básicamente son el id del div que aparecerá en el backend, el título del bloque que se mostrará, la función encargada de imprimir el HTML, el tipo de elementos en el que aparecerá, y el lugar en que se mostrará.

Con lo que el siguiente paso será definir la función print_checkbox_portada que tendrá que imprimir el HTML del checkbox. En resumen, todo el código para crear el checkbox:

WP_seleccionar_posts/anadir_checkbox.php

Perfecto, ya tenemos un checkbox en el backend, pero… por ahora no sirve para nada.

Checkbox portada

Asignar el meta_key

Volvemos a utilizar las actions de Worpress para decirle que queremos que haga algo más cuando guardemos nuestro post. De nuevo incluímos una acción en el functions.php, y una función que se ejecute en esa acción:

WP_seleccionar_posts/save_checkbox_portada.php

Simplemente comentar que el tag debe comenzar por “_” para que Worpress entienda que no debe mostrarlo en el listado de tags (ni en frontend ni en backend).

Filtrar posts por nuestro meta_key

Simplemente nos falta indicar a WordPress que sólo queremos obtener los posts que tengan ese meta_key, por lo que, como en los anteriores apartados, cambiamos la función query_posts:

query_posts('meta_key=_portada');

Pero puede que no queramos utilizarlo en nuestro loop principal, y además, si no tenemos ningún post marcado como “portada”, quizá queramos obtener los últimos, en vez de no poner ninguno. Para ello podemos utilizar las funciones get_posts o crea un nuevo objeto WP_query, para no interferir con el loop principal. Personalmente me es más cómoda la segunda opción, por lo que podríamos crear una nueva función:

WP_seleccionar_posts/get_posts_portada.php

que luego llamaríamos en nuestra plantilla, donde quisiéramos que apareciesen esos posts.:q

En resumen, podemos añadir en nuestro functions.php:

WP_seleccionar_posts/seleccionar_posts.php

Would like to share? These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
  • Reddit
  • Facebook
  • Google Bookmarks
  • Live-MSN
  • Ma.gnolia
  • NewsVine
  • Slashdot
  • Spurl
  • Squidoo
  • TwitThis

21 Responses to Seleccionar qué posts mostrar en WordPress

Avatar

Xavi

March 25th, 2012 at 19:11

Muy buen artículo, justo lo que necesitaba pero tengo una duda que me impide realizar ninguna de las tres opciones.
Mi theme es el de TwentyTen de wordpress, modificado. En el index.php no encuentro donde poner lo de “query_posts(‘meta_key=_portada’);”
ni en el archivo de loop tampoco, ¿sabrias decirme donde o como tengo que añadirlo? Muchas gracias,
saludos

Avatar

Félix Horro Pita

March 26th, 2012 at 10:30

Hola, Xavi.

Eso de tener un “TwentyTen modificado” quizá no sea muy buena idea. Date cuenta que una actualización del tema podría borrar los cambios que hayas hecho. Lo más recomendable es un tema hijo, que herede del TwentyTen, y que puedas modificar. Te recomiendo echar un vistazo a http://codex.wordpress.org/Child_Themes

Respondiendo a tu pregunta, tal y como dices el index.php del TwentyTen no define ninguna búsqueda específica, por lo que obtendrá la búsqueda por defecto, es decir, los últimos posts. Puedes modificarla con la función query_posts, antes de llamar al loop.

En el caso concreto que me planteas, en el index.php de tu tema hijo (o directamente del TwentyTen, aunque como decía no es recomendable), puedes indicar, antes del get_template_part: query_posts(‘meta_key=_portada’).

Un saludo.

Avatar

Xavi

March 31st, 2012 at 21:37

Hola, gracias por la respuesta.

He conseguido hacerlo funcionar! de las 2 formas, usando una categoría y con el checkbox de “En Portada”. Personalmente prefiero usar el checkbox, lo veo mas claro y funcional, lo que pasa que me gustaría que cuando el post ha sido seleccionado para mostrarse en portada y guardado, si vuelvo a entrar a editar el post debería ver el checkbox marcado, porque sinó no recuerdo si lo está o no, quiero decir que wordpress lo marca pero el checkbox no guarda el estado de checked cuando vuelves al backend para editar de nuevo ese post y no sabes si lo marcaste o no y eso despista.
¿hay forma de arreglarlo? con ese ajuste quedaría fino fino…

Este es el código completo que tengo ahora en functions.php (por si alguien más le interesa) con esto ya funciona pero sin dejar marcado visualmente el checkbox cuando vuelves a editar el post…

// FEATURED

add_action(‘add_meta_boxes’, ‘add_checkbox_featured’);

function add_checkbox_featured() {
add_meta_box(‘is_featured’, ‘Featured’, ‘print_checkbox_featured’, ‘post’, ‘side’);
}

function print_checkbox_featured() {
global $post;
$checked = get_post_meta($post->ID, ‘_featured’, true) ? ‘checked=”checked”‘ : ”;
echo ‘Show at front page ‘;
}

add_action(‘save_post’, ‘save_checkbox_featured’);

function save_checkbox_featured($post_id){
if (defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) return $post_id;

if ( !current_user_can( ‘edit_post’, $post_id ) )
return $post_id;

if ($_POST['is_featured']){
add_post_meta($post_id, ‘_featured’, ’1′);
}else{
delete_post_meta($post_id, ‘_featured’);
}
}

He cambiado la palabra “portada” por un “featured”, soy así de freaky… espero que nos importe!

Gracias y saludos ;)

Avatar

Xavi

March 31st, 2012 at 22:00

Bueno y ahora que lo pienso, también debería poder desmarcarlo, por si algun dia quiero que deje de aparecer ese post en la home.
Pero con el código que tengo ahora no se puede desmarcar…

Avatar

Xavi

March 31st, 2012 at 22:05

Bueno, lo siento por comentar antes de tiempo. Si que se puede desmarcar, checkeando y des-chekeando el checkbox. :)
Ahora solo faltaría que guarde el estado del checkbox visualmente, para saber si esta seleccionado para aprecer en la home o no,

Saludos!

Avatar

Félix Horro Pita

April 3rd, 2012 at 09:45

Hola, Xavi.

Tal y como defines la función que imprime la checkbox :

function print_checkbox_featured() {
global $post;
$checked = get_post_meta($post->ID, ‘_featured’, true) ? ‘checked=”checked”‘ : ”;
echo ‘Show at front page ‘;
}

no va a funcionar. En primer lugar, y supongo que será porque estabas en proceso de debug, eso no dibuja un checkbox, sino la frase “Show at front page”. La tercera línea debería ser:
echo ‘Mostrar en portada ‘;

En segundo lugar, ojo con las comillas al determinar si el ítem debe estar marcado o no. Me refiero a que la segunda línea dentro de la función debería ser:
$checked = get_post_meta($post->ID, ‘_featured’, true) ? ‘checked=”checked”‘ : ”;

Básicamente lo que hago ahí es asignar a la variable $checked el valor checked=”checked” si el post tiene el tag _featured, y en caso contrario asignarle un string vacío: ” (dos comillas simples).

Si este es el error, debería aparecer algo en el log de tu servidor cuando está mal.

Avatar

Xavi

April 3rd, 2012 at 22:39

Hola Félix, gracias por la ayuda :)
pero uso tu código y no me acaba de funcionar. Las comillas las tengo bien, no se porque no se publicó el trozo de código que imprime el checkbox.
Pero como te digo el checkbox funciona y los post se muestran correctamente solo los que tocan, es decir que funciona el asunto, el único problema es que el checkbox no se queda marcado como te expliqué, los marcas y funciona el asunto pero luego si vuelves a editar el post no aparecen chequeados visualmente y si que lo estan…

este es el código:

add_action(‘add_meta_boxes’, ‘add_checkbox_featured’);

function add_checkbox_featured() {
add_meta_box(‘is_featured’, ‘Featured’, ‘print_checkbox_featured’, ‘post’, ‘side’);
}

function print_checkbox_featured() {
global $post;
$checked = get_post_meta($post->ID, ‘_featured’, true) ? ‘checked=”checked”‘ : ”;
echo ‘Show at front page ‘;
}

add_action(‘save_post’, ‘save_checkbox_featured’);

function save_checkbox_featured($post_id){
// Si la llamada es un autosave, no queremos hacer nada
if (defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) return $post_id;

// Comprobamos los permisos del usuario
if ( !current_user_can( ‘edit_post’, $post_id ) )
return $post_id;

if ($_POST['is_featured']){
// Si el checkbox está marcado, añadimos el meta key
add_post_meta($post_id, ‘_featured’, ’1′);
}else{
// Si no está marcado, borramos el meta key
delete_post_meta($post_id, ‘_featured’);
}
}

Avatar

Xavi

April 3rd, 2012 at 22:40

He separado las palabras porque no publica la segunda parte de echo

function print_checkbox_featured() {
global $post;
$checked = get_post_meta($post->ID, ‘_featured’, true) ? ‘checked=”checked”‘ : ”;
echo ‘Show at front page ‘;
}

Avatar

Xavi

April 3rd, 2012 at 22:40

jolin…

‘Show at front page ‘

Avatar

Xavi

April 3rd, 2012 at 22:41

label for=”checkbox_is_featured”>Show at front page <input id="checkbox_is_featured" name="is_featured" type="checkbox" value="1"

Avatar

Xavi

April 3rd, 2012 at 22:44

y lo que abre y cierra label e input lo tengo bien… es que sinó no se posteaba el comentario,
disculpas

Avatar

Xavi

April 3rd, 2012 at 22:50

Vale, lo he conseguido, que bien!!
faltaba esto: ‘.$checked.’
es que copié el código de la primera parte de la explicación supongo…
muy contento, mil gracias, super buen aporte.

Saludos

Avatar

Félix Horro Pita

April 4th, 2012 at 09:34

Ok, Xavi, efectivamente primero determino si el checkbox tiene que estar marcado, y guardo el ‘checked=”checked”‘ en la variable $checked.
Después hay que pintar esa variable con el input.

Me alegro que te haya resultado útil.

Un saludo.

Avatar

Xavi

April 15th, 2012 at 12:45

Hola de nuevo,
tengo otra duda. He creado tipos de post personalizado (custom post type) con una herramienta online, que va de maravilla por cierto
se llaman “projects” y el singular “project”

Pues ahora no consigo hacer que los post que se muestren en la home no sean “posts” sinó “projects”
Sabrias decirme como?

muchas gracias!
Saludos

Avatar

Félix Horro Pita

April 16th, 2012 at 13:46

Hola, Xavi.

Siento no poder ayudarte, pero no conozco esa herramienta. Hay varias formas de hacer lo que me comentas, por lo que en este caso es difícil orientarte.

Espero que lo resuelvas.

Un saludo.

Avatar

Carolina

June 12th, 2012 at 03:20

Justo lo que necesitaba, muchas gracias por tu ayuda!

Avatar

jhosh petrovich

October 5th, 2012 at 10:58

primero qu e todo agradezco la atención a mi pregunta que tiene que ver con el tema que estan tratando por acá

la cuesti´lon es que quisiera que en vez de post en mi index, aparecieran paginas, como hago ese cambio?

Avatar

Félix Horro Pita

October 8th, 2012 at 10:02

Hola, Jhosh.

Lo que comentas se puede hacer tal y como explican en el manual:

http://codex.wordpress.org/Creating_a_Static_Front_Page

Un saludo.

Avatar

Bruno L.

November 23rd, 2012 at 13:46

Capo. Llevaba 5 horas dándole vueltas al tema. Lo rondaba, casi lo tenía, pero hasta que no he llegado a tu artículo no lo he comprendido…

¡Muchas gracias!

Avatar

Enrique

May 26th, 2013 at 14:14

Gracias por el artículo. Es estupendo.
Tengo un problema. Estoy utilizando un meta key para seleccionar entradas de la portada. Funciona bien, pero cuando pulso anteriores me sale las mismas entradas, es decir no pagina.
¿Podéis ayudarme?

Avatar

Félix Horro Pita

June 17th, 2013 at 13:55

Hola, Enrique.

Te recomiendo echar un vistazo a la referencia: http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters

Básicamente, habría que comprobar el campo de paginación al crear el WP_Query. Quedaría algo como:

$paged = get_query_var(‘paged’) ? get_query_var(‘paged’) : 1;
$args = array(
‘meta_key’ => ‘_portada’,
‘paged’ => $paged
);

$portada = new WP_query($args);

El código lo escribo de memoria y sin comprobar el funcionamiento, puedes utilizar la referencia para comprobar los errores (si hay).

Espero que te sirva.

Comment Form

top