Método de encadenamiento de paginación para tipo de entrada personalizada
Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)
¿Te deprimió la paginación para el tipo de entradas personalizadas? No ha habido nada más frustrante en el desarrollo de WordPress que conseguir que la paginación de tipo de entrada personalizada funcione. He desarrollado un método que ha resuelto mis problemas y creo que también resolverá los tuyos.
Introducción
A medida que he comenzado a crear más temas premium de WordPress he empezado a desarrollar un tema base a modo de framework a partir del cual construir cada nuevo proyecto. El proceso iba bien hasta que empecé a trabajar con tipos de entradas personalizadas. Fue entonces cuando inevitablemente me enfrenté al que fue mi enemigo durante mucho tiempo, la paginación personalizada de los tipos de entradas.
Desde el lanzamiento de los tipos de entradas personalizadas en WordPress 2.9 su paginación ha resultado difícil dependiendo de las circunstancias. Hasta los profesionales de WordPress más potentes se han quedado perplejos en alguna ocasión.
Afortunadamente, siento que finalmente he superado la paginación de los tipos de entradas personalizadas de una vez por todas. Me imagino flexionando sobre ello en el resplandor de la luz de la luna, mi rostro cincelado en la conquista, un pie plantado en el suelo y el otro firme sobre su pecho.
Mi clave para paginar fácilmente los tipos de entradas personalizadas consiste en usar la plantilla archive-posttype.php para hacer algo que yo denomino encadenamiento, lo cual significa que las usamos incluyéndolas en otros archivos de plantilla de WordPress donde se necesite la paginación. Lo que hace esto es reducir el desarrollo personalizado para diferentes circunstancias en las que un desarrollador desee usar la paginación. Concíbelo como el empleo de la plantilla de archivo de tipo de entrada personalizada a modo de índice o algo que lo abarca todo. Hay algunos giros en el camino, pero esa es la idea principal. Empecemos.
Paso 1 La paginación
Dado que la codificación es una ciencia de cimentación vamos a empezar con el asunto de la paginación en sí. A pesar de que me inclino ante la grandeza del plugin de paginación, WP PageNavi, como Jacob Goldman señaló recientemente, realmente su uso no es necesario. WordPress tiene su propia función de paginación llamada paginate_links() y aparentemente la mayoría de los desarrolladores no saben nada al respecto. Asegúrate de leer su documentación, pero para ahorrarte el tiempo que implicaría la elaboración de tu propio código para el archivo functions.php, aquí tienes el mío que es muy similar al ejemplo del Codex:
1 |
function paginate() { |
2 |
global $wp_query, $wp_rewrite; |
3 |
$wp_query->query_vars['paged'] > 1 ? $current = $wp_query->query_vars['paged'] : $current = 1; |
4 |
$pagination = array( |
5 |
'base' => @add_query_arg('page','%#%'), |
6 |
'format' => '', |
7 |
'total' => $wp_query->max_num_pages, |
8 |
'current' => $current, |
9 |
'show_all' => true, |
10 |
'type' => 'plain' |
11 |
);
|
12 |
if ( $wp_rewrite->using_permalinks() ) $pagination['base'] = user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'page/%#%/', 'paged' ); |
13 |
if ( !empty($wp_query->query_vars['s']) ) $pagination['add_args'] = array( 's' => get_query_var( 's' ) ); |
14 |
echo paginate_links( $pagination ); |
15 |
}
|
Mi método de encadenamiento ha sido desarrollado teniendo en cuenta esta función. Usar WP PageNavi para la paginación de tipo de entrada personalizada se vuelve realmente complejo, así que no te enseñaré a hacerlo por la misma razón que los amigos no dejan que sus propios amigos conduzcan borrachos. De nada. Pero pasemos a lo que realmente viniste a hacer, averiguar finalmente cómo evitar que la paginación de tipo de entrada personalizada devuelva un error 404 o vuelva siempre a la primera página.
Paso 2 Plantilla de archivo de tipo de entrada personalizada
Dado que los tipos de entradas personalizadas no tienen sus propias páginas de índice, y como dije antes, pienso en la plantilla archive-posttype.php específicamente como su sustituto porque lo uso como base para la paginación en todas las demás plantillas. Muchos desarrolladores primero forzarán una plantilla de página para crear una página de índice, pero 1.) Obviamente no estoy de acuerdo y 2.) llegaremos a ellos más adelante. Hasta la superestrella de WordPress, Justin Tadlock, acepta que los tipos de entradas personalizadas deberían tener al menos opción a sus propias páginas de índice.


Afortunadamente, mi función paginate() funciona directamente en la plantilla archive-posttype.php. Ufff. Pero el problema es que su paginación está vinculada a la configuración de las entradas por página en Ajustes > Lectura. Y debido a que los tipos de entradas personalizadas son solo eso, personalizadas, un desarrollador querrá que sus entradas por página sean también personalizadas nueve de cada diez veces. Para conseguir esto, la forma más sencilla que he descubierto consiste en escribir un filtro como este en functions.php:
1 |
function portfolio_posts_per_page( $query ) { |
2 |
if ( $query->query_vars['post_type'] == 'portfolio' ) $query->query_vars['posts_per_page'] = 1; |
3 |
return $query; |
4 |
}
|
5 |
if ( !is_admin() ) add_filter( 'pre_get_posts', 'portfolio_posts_per_page' ); |
Este método me fue inspirado a través del artículo de Jonathan Christopher llamado Entradas WordPress por página por tipo de entrada personalizada. ¡Gracias, Jonathan!
¿Qué sucede si no quiero que mi estructura de permalinks tenga el mismo nombre que mi tipo de entrada personalizada (por ejemplo, http://company.com/portfolio/)? Me alegra que lo preguntes. Esta es una de las razones por las que un desarrollador preferiría una plantilla de página para mostrar sus tipos de entradas personalizadas. Proporciona control total al usuario sobre la estructura de permalinks ya que puedes cambiar simplemente el nombre de la página que usa esa plantilla de página. Eso es comprensible y lo haremos pronto, pero para aquellos de nosotros que no necesitamos hacer eso o queremos otra futura manera, existe una pequeña edición que podemos realizar bajo el capó para adaptar esa estructura a nuestra voluntad.
La función para crear un tipo de entrada personalizada, register_post_type(), acepta un argumento llamado rewrite. El valor de ese argumento se pasa como una matriz y si se cambia el valor del slug cambiará la estructura del permalink. Este es un ejemplo:
1 |
'rewrite' => array( 'slug' => 'insertyourpermalinknamehere', 'with_front' => true ), |
Después de cambiar esto, dirígete a Ajustes > Permalinks y pulsa el botón "Guardar cambios" para purgar la caché de reescritura. Visita tu sitio y actualiza la página para ver el cambio. Hecho. Sin embargo, una vez más, la única desventaja de este método es que los usuarios no expertos en tecnología no podrán cambiar el nombre de su estructura de permalinks desde la interfaz gráfica de administración a menos que, por supuesto, se dirijan al Editor de temas para cambiar ese slug de reescritura.
Paso 3 Plantillas de página


No es raro que los desarrolladores muestren y paginen sus tipos de entradas personalizadas en una página principal estática a través de una plantilla de página. La razón de esto es doble; le da al usuario esa capacidad de cambio de nombre de estructura de permalink de la que acabamos de hablar y les permite mostrar tipos de entradas personalizadas en la página principal de su sitio. Pero aquí las cosas pueden ponerse feas. Me avergüenza decir que una vez codifiqué la paginación del tipo de entrada personalizada de tres maneras distintas en un tema. Esto se debe en parte al uso de WP PageNavi, pero soy el responsable de este vergonzoso hecho y con ello quiero enfatizar que todo este proceso puede resultar abrumador para los desarrolladores de temas que no sean "conocedores".
Llamemos a nuestra plantilla de página page-portfolio.php para que coincida con la convención de nomenclatura de las plantillas de tipo de entradas personalizadas, aunque no sea una. Aquí está el código:
1 |
/* Template Name: Portfolio */
|
2 |
|
3 |
$paged = 1; |
4 |
if ( get_query_var('paged') ) $paged = get_query_var('paged'); |
5 |
if ( get_query_var('page') ) $paged = get_query_var('page'); |
6 |
|
7 |
query_posts( '&post_type=portfolio&paged=' . $paged ); |
8 |
|
9 |
require_once( 'archive-portfolio.php' ); |
Esta es la primera vez que ves la plantilla archive-posttype.php encadenada a otra plantilla. ¡Y funciona! Pero, ¿qué diablos está pasando? Esta extraño negocio de la variable $paged destaca precisamente el problema que los desarrolladores parecen tener con la paginación de los tipos de entradas personalizadas. Básicamente, si esta solución (tos) no está en su sitio y un usuario hace clic para ver la página 2, como a alguien que le hayan echado un cubo de agua sobre la cabeza, WordPress se confunde y no sabe localizarla. Y para añadir más dolor a la lesión, aparentemente WordPress lo sabe y lo acepta como procedimiento de desarrollo normal publicando esta nota en la sección Parámetros de paginación de la página del Codex para WP_Query():
Nota sobre la paginación: Debes establecer get_query_var( 'page' ); si deseas que tu consulta funcione con la paginación. Desde WordPress 3.0.2, se usa get_query_var( 'página' ) en lugar de get_query_var( 'paged' ). El parámetro de paginación 'paged' para WP_Query() sigue siendo el mismo.
Para mí, tiene sentido que los desarrolladores deban ser capaces de establecer esa variable y apuntar a una página específica. Lo que no tiene sentido es que la paginación funcione intrínsecamente con los tipos de entradas predeterminadas (es decir, post, page, attachment), pero no con las entradas personalizadas.


Más allá de tener que parchear el código, aquí hay otra sorpresa, no se puede llamar al slug de tu página de la misma manera que llamas al slug del tipo de entrada personalizada. Piensa en tu slug de tipo de entrada personalizada como una palabra clave reservada; sin embargo, puedes hacer que el título de tu página sea igual al nombre que tu slug de tipo de entrada personalizada, siempre y cuando el slug de tu página sea algo diferente.
Paso 4 Plantilla de página de portada
El uso de la plantilla front-page.php bloquea a los usuarios en una página principal personalizada sin la capacidad de cambiarlo (a menos que eliminen el archivo o cambien temporalmente su nombre). Es por eso que la mayoría de los desarrolladores optan por el método de crear páginas de portada estáticas, pero por el bien de mi método supongamos que estamos usando la primera. Para lograr la paginación de tipo de entrada personalizada para esta plantilla todo lo que tenemos que hacer es simplemente incluir lo que hemos hecho para archive-posttype.php de la siguiente manera:
1 |
require_once( 'page-portfolio.php' ); |
Paso 5 Taxonomías de tipo de entradas personalizadas
La plantilla taxonomy-posttype-taxonomy.php funciona de la misma manera que la plantilla front-page.php, pero en lugar de incluir la plantilla page-portfolio.php, incluirás nuestro índice, archive-posttype.php, de la siguiente manera:
1 |
require_once( 'archive-posttype.php' ); |
Esto completa el alcance de mi método. Donde antes me golpeaba la cabeza contra el escritorio a las dos de la mañana, ahora estoy avanzando tranquilamente en proyectos a las dos de la tarde. ¡Victoria! Bueno, al menos por ahora. No soy tan ingenuo como para pensar que puede que me encuentre en una situación en la que este método no funcione para la paginación del tipo de entradas personalizadas, aunque aún no me ha pasado.
Conclusión
A diferencia de mis otros tutoriales espero que este quede obsoleto en el futuro. Mi esperanza es que WordPress actúe en base a la reciente encuesta que muestra que el 92% de todos los desarrolladores usan WordPress como UN CMS y echan un segundo vistazo a cómo funciona la paginación en toda su plataforma. El equipo de WordPress es como mínimo profesional. Me imagino un futuro en el que existan herramientas de paginación integradas y posiblemente una página de administración para los tipo de entradas personalizadas en los Ajustes para gestionar las entradas por página para los tipos de entradas personalizadas. Pero por ahora, espero que este método de encadenamiento ayude a los muchos desarrolladores que he visto sufrir en los foros de WordPress. Por favor, siéntete libre de descargar, utilizar y abusar de los siguientes archivos comprimidos como framework para lograr paginar con éxito un tipo de entrada personalizada. ¡Disfruta!
Marco de método de encadenamiento de paginación de tipo de entrada personalizada (ZIP)



