PEAR::PAGER, Paginations d'article, ou comment naviguer dans les paragraphes d'un article avec le paginateur
À 10:13 dans la rubrique PHP / PEAR
←
/ #836
/ rss
/ →
Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton
Vous avez probablement vu beaucoup de sites Web comporter des articles longs et détaillés, qui sont coupés en paragraphes, chacun présenté dans une page séparée.
Les utilisateurs préfèrent souvent lire les morceaux courts du texte au lieu de faire défiler une très(trop) longue page (à moins qu'ils ne veulent l'imprimer).
Dans ce tuto, nous allons voir comment nous pouvons établir un système de paginations d'article, a l'aide de PEAR::Pager.
La structure de base de données
Nous aurons besoin de deux tables pour stocker nos articles :
- une avec l'information de base des article (auteur, titre, résumé, date de publication)
- et une contenant les paragraphes (un par enregistrement, avec le titre et le contenu).
Techniquement, nous pourrions employer juste une table, utilisant quelques délimiteurs spéciaux incorporés dans le texte (tel que le « ====FIN DE PAGE====") pour découper les paragraphes, mais croyez moi qu'à la longue cette une solution bien meilleure
[SQL] CREATE TABLE articles ( id INTEGER NOT NULL, title VARCHAR(250) NOT NULL, abstract TEXT, submission_date TIMESTAMP NOT NULL, author_id INTEGER NOT NULL, CONSTRAINT articles_pkey PRIMARY KEY(id) ); CREATE TABLE paragraphs ( article_id INTEGER NOT NULL, paragraph_id INTEGER NOT NULL, title VARCHAR(250), content TEXT, CONSTRAINT paragraphs_pkey PRIMARY KEY(article_id, paragraph_id), CONSTRAINT paragraphs_fk FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE );
Données d'exemple
Voici quelques données d'exemple si vous voulez tester tout en lisant ce tuto :
[SQL] -- Premier Article INSERT INTO articles (id, title, abstract, submission_date, author_id) VALUES ( 1, 'How to navigate through the paragraphs of an article with Pager', 'You\'ve probably seen a lot of websites featuring long, detailed articles, which are split into paragraphs, each of them in a separate page. Users often prefer reading short chunks of text instead of scrolling a very long page (unless they want to print the page, then the opposite applies). In this tutorial, we\'re going to see how we can build an article pagination system, with a little help from PEAR::Pager.', CURRENT_TIMESTAMP, 1 ); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 1, 'The database structure', 'First paragraph here'); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 2, 'Sample data', 'Second paragraph here'); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 3, 'Showtime', 'Third paragraph here'); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 4, 'Alternate navigation', 'Fourth paragraph here'); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 5, 'Article summary', 'Fifth paragraph here'); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 6, 'Printer friendly version', 'Sixth paragraph here'); -- Second Article INSERT INTO articles (id, title, abstract, submission_date, author_id) VALUES ( 2, 'PEAR::Pager tutorials', 'New series of tutorials about PEAR::Pager', CURRENT_TIMESTAMP, 1 ); INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (2, 1, 'Articles index', '1. How to efficiently paginate database results. 2. Create pretty links with Pager and mod_rewrite. 3. Navigation with Pager and AJAX (or simple Javascript). 4. Article pagination.');
Showtime!
Maintenant que nous sommes ok avec la structure de base de données, nous pouvons afficher les articles sur notre site, un paragraphe par la page.
Pour cette tâche, nous allons employer PEAR::MDB2 DBAL et le bien pratique Pager_Wrapper que nous avons déjà vu dans un tuto précédent :
[php]
<?php
//Copier le fichier Pager_Wrapper file là où il peut-être inclu
require_once 'Pager_Wrapper.php';
require_once 'MDB2.php';
$article_id = 1; //if you fetch this parameter via GET/POST, remember to validate it!
//on passe le code de connexion DB
//on suppose qu'on a une connexion valide dans $db
$pager_options = array(
'mode' => 'Sliding',
'perPage' => 1, //On ne veut qu'un paragraphe par page
'delta' => 3,
);
$query = 'SELECT articles.title AS article_title,
articles.submission_date,
articles.abstract,
paragraphs.title AS paragraph_title,
paragraphs.content
FROM paragraphs
LEFT JOIN articles ON articles.id = paragraphs.article_id
WHERE articles.id = '. (int)$article_id .'
ORDER BY paragraphs.paragraph_id;
$paged_data = Pager_Wrapper_MDB2($db, $query, $pager_options);
//Afficher les résultats
echo '<h1>'.$paged_data['data'][0]['article_title'].'</h1>';
echo '<p><i>'.$paged_data['data'][0]['submission_date'].'</i></p>';
if ($paged_data['page_numbers']['current'] == 1) {
// afficher aussi le résumé.
echo '<p>'.$paged_data['data'][0]['abstract'].'</p>';
}
echo '<h2>'.$paged_data['data'][0]['paragraph_title'].'</h2>';
echo '<p>'.$paged_data['data'][0]['content'].'</p>';
//afficher les liens
echo $paged_data['links'];
?>
Puisque nous avons demandé au paginateur de couper les articles (les paragraphes, dans notre cas) en groupes de "un", il renverra seulement un paragraphe, et nous pouvons naviguer vers les autres paragraphes avec les liens générés par paginateur.
Voici le rendu du script :

Autre navigation
Si vous n'aimez pas des liens normaux pour la navigation, et préférez un menu de <select> à la place, vous devez ajouter un appel à la la fonction getPageSelectBox () dans Pager_Wrapper_MDB2, avant de renvoyer le tableau de données paginée, puisqu'elle n'est pas incluse dans la version par défaut :
[php]
function Pager_Wrapper_MDB2(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB2_FETCHMODE_ASSOC)
{
// Pager_Wrapper_MDB2() body omitted. Add the following lines before the return call:
// ===== Début du CODE ajouté ======
$selectbox_options = array(
'optionText' => 'page %d',
'autoSubmit' => true,
);
$page['select_menu'] = $pager->getPageSelectBox($selectbox_options);
// ===== Fin du CODE ajouté =====
return $page;
}
Maintenant on affiche le menu de navigation :
[php] <?php // [snip: même code que dans le paragraphe précédent] //Affichage du menu echo 'Choisissez une page: '. $paged_data['select_menu']; ?>
Et voilà ce que ca devrait donner:

Sommaire de l'article
Parfois, vous pouvez vouloir montrer un sommaire de l'article, avec une liste des titres de paragraphe, chacun indiquant le paragraphe complet.
Aucun problème, vous pouvez faire cela.
[php]
<?php
$query = 'SELECT title
FROM paragraphs
WHERE article_id = '. (int)$article_id
.' ORDER BY paragraph_id';
$paragraph_titles = $db->queryCol($query);
//on oublide le code de vérification
echo '<h2>Sommaire</h2>';
echo '<ul>';
foreach ($paragraph_titles as $k => $title) {
if ($k == ($paged_data['page_numbers']['current'] -1)) {
// Page courrante, ne pas afficher le lien
echo '<li>' . $title . '</li>';
} else {
echo '<li><a href="article.php?id='. (int)$article_id .'&pageID='. ($k+1) .'">'. $title . '</a></li>';
}
}
echo '</ul>';
?>
Le résultat est un résumé des titres de paragraphe, avec leurs liens

Version imprimable
Si vous voulez proposer une version pour l'impression avec l'article complet, vous pouvez chercher tous les paragraphes et simplement les afficher l'un après l'autre :
[php]
<?php
$query = 'SELECT title,
submission_date,
abstract
FROM articles
WHERE id = '. (int)$article_id;
$article = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
$query = 'SELECT title,
content
FROM paragraphs
WHERE article_id = '. (int)$article_id
.' ORDER BY paragraph_id';
$paragraphs = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
//Afficher les données principales de l'article:
echo '<h1>'.$article['title'].'</h1>';
echo '<p><i>'.$article['submission_date'].'</i></p>';
echo '<p>'.$article['abstract'].'</p>';
// Afficher les paragraphes de l'article:
foreach ($paragraphs as $paragraph) {
echo '<h2>'.$paragraph['title'].'</h2>';
echo '<p>'.$paragraph['content'].'</p>';
}
?>
J'espère que ce tuto était utile (la traduc aussi :).
Si vous avez besoin de quelques clarifications, ou avez quelques suggestions , envoyez-nous un mail :








Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire