Añadiendo paginación al blog

Pese a lo que me está gustando eggBlog, tiene algunas decisiones que me parecen incomprensibles. La principal es que solo se muestren 3 artículos en la página principal y no exista ningún tipo de paginación.

Así que me puse a realizar las modificaciones necesarias para añadir paginación y que el número de artículos a mostrar en las páginas fuese configurable.

Lo primero es añadir el parámetro de configuración en config.php. En mi caso, por defecto quiero mostrar 5 artículos por página:

$config['posts_per_page'] = "5";

Para hacerlo configurable debemos modificar admin.php. El método eb_admin_config se encarga de mostrar los parámetros de configuración. En el “if” se muestran por pantalla los parámetros almacenados, mientras que el “else” se encarga de construir el formulario para modificarlos. En el if introducimos:

$output.=" <tr><th>" . ucwords( 'Artículos por página' ) . "</th><td>"
.str_replace( "&Acirc;", "", htmlentities( $config['posts_per_page'], ENT_QUOTES ) )
."</td></tr>";

Mientras que en el else introducimos:

$output.=" <tr><th><label for="">" . ucwords( 'Artículos por página' )
."</label></th><td><input class="inputtext" id="" type="text""
."name="posts_per_page" value=""
.htmlentities( $config['posts_per_page'], ENT_QUOTES )."" /></td></tr>";

De la paginación en sí, se encarga una nueva página llamada page.php. Su contenido es el siguiente:

<?php
require_once "_lib/global.php";
if( !empty( $_GET['id'] ) ) {
    settype( $_GET['id'], "integer" );
}
eb_pre();
eb_head('');
$articles = getArticlesIdsForPage( $_GET['id'], $config['posts_per_page'] );
if( count( $articles ) > 0 ) {
    echo eb_article( 0, $articles );
}

showPagination( $_GET['id'], $config['posts_per_page'] );
eb_foot();
?>

Los nuevos métodos que se encargan de la paginación se encuentran en news.php y son los siguientes:

/**
 * Obtiene un vector con los IDs de los N artículos que se deben mostrar en la
 * página indicada.
 *
 * @param integer $page El número de la página a mostrar
 * @param integer $n El número de artículos a mostrar en la página
 */
function getArticlesIdsForPage( $page, $n ) {
    settype( $page, "integer" );
    settype( $n, "integer" );
    $articleIds = array();
    $sql = "SELECT article_id FROM eb_articles WHERE article_flag = 1"
          ."ORDER BY article_date DESC";
    $query = mysql_query( $sql );
    while( $row = mysql_fetch_array( $query ) ) {
        $articleIds[] = $row['article_id'];
    }

    $startIndex = ( $page - 1 ) * $n;
    $endIndex = $startIndex + $n - 1;

    if( $startIndex > ( count( $articleIds ) - 1 ) ) {
        return array();
    }

    if($endIndex > ( count( $articleIds ) - 1 ) ){
        $endIndex = count( $articleIds ) - 1;
    }

    $output = array();

    for( $i = $startIndex; $i <= $endIndex; $i++ ){
        $output[] = $articleIds[$i];
    }

    return $output;
}

/**
 * Se encarga de mostrar los enlaces a artículos anteriores y posteriores
 * dependiendo de la página en la que se encuentra el usuario.
 *
 * @param integer $currentPage La página actual
 * @param integer $articlesPerPage El número de artículos por página
 */
function showPagination( $currentPage, $articlesPerPage ){
    settype( $currentPage, "integer" );
    if( $currentPage > 1 ){
        showPrevPageLink( $currentPage );
    }

    if( count( getArticlesIdsForPage( $currentPage + 1, $articlesPerPage ) ) > 0 ){
        showNextPageLink( $currentPage );
    }
}

/**
 * Muestra el enlace a la página anterior.
 *
 * @param integer $currentPage La página actual
 */
function showPrevPageLink( $currentPage ){
    echo '<div class="paginacionPrev"><a href="page-' . ( $currentPage - 1 )
    .'.html"><- Artículos recientes</a></div>';
}

/**
 * Muestra el enlace a la página siguiente.
 *
 * @param integer $currentPage La página actual.
 */
function showNextPageLink( $currentPage ){
    echo '<div class="paginacionNext"><a href="page-' . ( $currentPage + 1 )
    .'.html">Artículos anteriores -></a></div>';
}

Por último modificamos el index.php para utilizar el nuevo parámetro y mostrar la paginación:

<?php
require_once '_lib/global.php';

global $config;
eb_pre();
eb_head('');

$articles = eb_articles( $config['posts_per_page'] );

if( count( $articles ) > 0 ) {
    echo eb_article( 0, $articles );
}

showPagination( 1, $config['posts_per_page'] );

eb_foot();
?>

Para que la paginación también utilice URL semánticas, debemos modificar el .htaccess, añadiendo esta como la primera regla:

RewriteRule page-([0-9]+).html$ page.php?id=$1 [L]