Autonomía digital y tecnológica

Código e ideas para una internet distribuida

Cómo filtrar las funciones previous_post_link y next_post_link de WordPress usando un custom field

Imago voragine.net

En WordPress previous_post_link() y next_post_link() permiten enlazar, en la plantilla de una entrada, la anterior y la siguiente entrada respectivamente. Estas entradas vienen definidas por unos parámetros por omisión que definen una petición a la base de datos que hace la función get_adjacent_post(). Estos parámetros definen que el criterio para seleccionar la entrada anterior y posterior sea la fecha de publicación.

Afortunadamente get_adjacent_post() dispone de tres hooks donde añadir filtros para modificar los parámetros de la petición a la base de datos para modificar las entradas previa y siguiente: get_{$adjacent}_post_join, get_{$adjacent}_post_sort y get_{$adjacent}_post_where. $adjacent puede tomar los valores previous y next.

Escribo a continuación el código necesario para cambiar el criterio para obtener la entrada previa y siguiente en base a un campo (custom field) numérico que haya servido para ordenar ascendentemente las entradas en la plantilla de archivo.

/**
 * Join postmeta to the sql query, so we can filter for custom fields
 *
 * @param $join
 *
 * @return string
 */
function pfx_get_adjacent_post_join($join) {
	if(is_singular('post')) {
		global $wpdb;
		$join = $join."INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id";
	}
	return $join;
}
add_filter('get_previous_post_join', 'esfo_get_adjacent_cs_join');
add_filter('get_next_post_join', 'esfo_get_adjacent_cs_join');

/**
 * Change where clause of post for prev / next navigation
 *
 * @param $where
 *
 * @return string|void
 */
function pfx_get_adjacent_cs_where($where, $operator) {
	if(is_singular(ESFO_PT_CS)) {
		global $wpdb, $post;
		$pt = 'post';
		$k = '_number';
		$v = get_post_meta($post->ID,'_number',true);
		$where = " WHERE p.post_type = '".$pt."' AND p.post_status = 'publish' AND ( m.meta_key = '".$k."' AND (m.meta_key = '".$k."' AND CAST(m.meta_value AS CHAR) $operator $v) )";
	}
	return $where;
}
add_filter( 'get_previous_post_where',
	function( $where ) {
		return pfx_get_adjacent_cs_where( $where, '<' );
	}
);
add_filter('get_next_post_where', 
	function( $where ) {
		return pfx_get_adjacent_cs_where( $where, '>' );
	}
);

/**
 * Change sort clause of post for prev navigation
 *
 * @param $sort
 *
 * @return string|void
 */
function pfx_get_prev_cs_sort($sort) {
	if(is_singular('post')) {
		global $wpdb;
		$sort = " GROUP BY p.ID ORDER BY m.meta_value DESC LIMIT 1";
	}
	return $sort;
}
add_filter('get_previous_post_sort', 'pfx_get_prev_cs_sort');

/**
 * Change sort clause of post for next navigation
 *
 * @param $sort
 *
 * @return string|void
 */
function pfx_get_next_cs_sort($sort) {
	if(is_singular('post')) {
		global $wpdb;
		$sort = " GROUP BY p.ID ORDER BY m.meta_value ASC LIMIT 1";
	}
	return $sort;
}
add_filter('get_next_post_sort', 'pfx_get_next_cs_sort');

Si se quisiera usar otro criterio habría que cambiar la petición a base de datos.

Encontré la pista para escribir este código en este hilo de stackexchange.

Dejar un comentario

No hay comentarios en esta entrada.
*
*

 

No hay trackbacks