Supongamos que deseamos mostrar 5 posts en la sección principal del sitio y 16 para todo el resto de secciones (archivos por fecha, autores, etiquetas, categorías, búsquedas, etc). En la configuración de WordPress indicamos que muestre los 16 posts por página, y luego con un sencillo plugin lo modificamos solo para la sección principal :


function home_pagination(&$query) {
	if ( $query->is_home  ) {
		$query->set('posts_per_page', 5);
	}
}

add_filter('pre_get_posts','home_pagination');

Pueden ver esto funcionando en un fotolog que tengo con WordPress: 5 en la sección principal y 16 en los archivos y demás.

Yo uso el hook pre_get_posts para modificar esto poco antes de que se haga el query principal, también se puede usar parse_request o cualquier otro hook donde WordPress ya ha procesado los rewrite rules y sabe en que sección estamos. Noten que $query se pasa por referencia, así que no hay que retornarla, sino aplicar los cambios directamente en esta.

Si necesitamos que exclusivamente la portada tenga una paginación diferente (así como hacemos en la de Maestros del Web), entonces tenemos que modificar el hook a:


function home_pagination(&$query) {
	if ($query->is_home) {
		if ( intval($query->query_vars['paged']) < 2 ) {
			$query->set('posts_per_page',5);
		} else if ( intval($query->query_vars['paged']) > 1) {
			$offset = 5 + (absint($query->query_vars['paged'])-2) * 16;
			$query->set('offset',$offset);
		}
	}

}

add_filter('pre_get_posts','home_pagination');

La idea acá es recalcular las siguientes páginas tomando en cuenta que ya se mostraron 5 posts en la primera. Por ejemplo, en la segunda página se mostrarían los posts 6 al 21, en la tercera del 22 al 36. Recordar que los offsets en MySQL empiezan desde cero: el offset cero (0) se refiere a la primera fila, el offset cinco se refiere a la sexta fila, etc.

Si tenemos algún plugin que muestra la cantidad de páginas de cada sección, entonces deberíamos modificar los datos que usa el plugin (según como funcione este); en nuestro caso lo que hacemos es ejecutar esto antes de invocar a la función del plugin (y solo en la portada):

global $wp_query; 
$wp_query->max_num_pages = ceil( ($wp_query->max_num_pages * 5)/16 );