Symfony snippet: partial для постраничной навигации (pagination)

Предлагаю вашему вниманию небольшой сниппет для повседневного применения в symfony 1.3 – 1.4.

Сниппет предназначен для отображения постраничной навигации по записям.

Задача:

выводить список страниц для типового набора записей (новости, каталог и т.п.)

Решение:

Поскольку пейджер в большинстве типовых проектов требуется однотипный, то и решение для него должно быть простым и универсальным. Для бОльшей наглядости предположим что у нас есть модель NewsItem – новости сайта.

Подготовительные операции:

Схема:

NewsItem:
  options:
    type: INNODB
    collate: utf8_general_ci
    charset: utf8
  actAs:
    Timestampable:
  connection: doctrine
  tableName: news_item
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    title:
      type: string(255)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    abstract:
      type: string()
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    description:
      type: string()
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    is_published:
      type: boolean
      fixed: false
      unsigned: false
      primary: false
      default: '0'
      notnull: true
      autoincrement: false

Метод получения пейджера в NewsItemTable.class.php:

// Где-то в lib/model/doctrine/NewsItemTable.class.php
/**
 * Что-то с постраничным выводом
 * @param <int> $page
 * @return <Doctrine_Pager>
 */
public static function getNewsPager( $page )
{
  $query = Doctrine_Query::create()
    ->select    ( "*" )
    ->from      ( "NewsItem n" )
    ->where     ( "n.is_published = 1" )
    ->orderBy   ( "n.created_at DESC" );
  return new Doctrine_Pager( $query, $page, sfConfig::get( "app_pager_perpage", 10 ));
}

Настройку app_pager_perpage добавляем в app.yml:

# apps/frontend/config/app.yml
all:
  pager:
    perpage: 10

В действии:

// apps/frontend/modules/news/actions/actions.class.php
/**
 * Архив новостей
 * @param  $request
 */
public function executeArchive(sfWebRequest $request)
{
  $this->news_pager = NewsItemTable::getNewsPager( $request->getParameter( "page", 1 ) );
  $this->news       = $this->news_pager->execute();
}

Теперь создаем партиал пейджера (в каком-нибудь общем модуле, shared или commons):

// apps/frontend/modules/commons/templates/_pager.php
<?php
 
/**
 * Типовой пейджер
 *
 * @param <Doctrine_Pager> $pager - объект пейджера
 * @param <string> $route - маршрут для построения ссылок пейджера
 *
 * @package     commons
 * @subpackage  templates
 * @author      Dmitry.Bykadorov@gmail.com
 * @version     SVN: $Id: _pager.php dmitry.bykadorov $
 *
 */
 
?>
 
<?php if( $pager->haveToPaginate() ): ?>
<div class="pager">
 
  <ul>
    <?php if( $pager->getFirstPage() != $pager->getPage()): ?>
    <li><a href="<?php echo url_for( "$route?page=" . $pager->getFirstPage() ) ?>" title="<?php echo 'Первая страница'?>"><<</a></li>
    <li><a href="<?php echo url_for( "$route?page=" . $pager->getPreviousPage() ) ?>" title="<?php echo 'Назад'?>"><</a></li>
    <?php endif; ?>
 
    <?php for( $i = -2; $i < 3; $i++ ): ?>
      <?php if( ( $p = $pager->getPage() + $i ) > 0 && ( $p <= $pager->getLastPage() ) ): ?>
        <?php $active = ( $i == 0 ) ? "active" : ""; ?>
        <li><a class="<?php echo $active ?>" href="<?php echo url_for( "$route?page=" . $p ) ?>" title="<?php echo 'Страница ' . $p ?>"><?php echo $p ?></a></li>
      <?php endif; ?>
    <?php endfor; ?>
 
    <?php if( $pager->getLastPage() != $pager->getPage()): ?>
    <li><a href="<?php echo url_for( "$route?page=" . $pager->getNextPage() ) ?>" title="<?php echo 'Вперед'?>">></a></li>
    <li><a href="<?php echo url_for( "$route?page=" . $pager->getLastPage() ) ?>" title="<?php echo 'Последняя страница'?>">>></a></li>
    <?php endif; ?>
  </ul>
 
</div>
<?php endif; ?>

Ну и все что нам осталось, разместить в шаблоне архива постраничную навигацию:

// apps/frontend/modules/news/templates/archiveSuccess.php
<?php
include_partial(
  "commons/pager",
  array(
    "pager" => $news_pager,
    "route" => "@news_archive"
));
?>

Вот и все. Можно пользоваться.

Пожелания, предложения и багрепорты оставляйте в комментариях )

This entry was posted in Профессиональное and tagged , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

13 Comments

  1. develop7
    Posted 2010/03/29 at 9:20 am | Permalink

    На самом деле я тут ни при чём, этот сниппет был опубликован вроде как Nicolas Perriault у него в блоге.

    • develop7
      Posted 2010/03/29 at 9:25 am | Permalink

      Ох, ё.
      Дима, этот коммент — к предыдущему посту. Если не сможешь перенести — сноси нафиг :)

      • hudson
        Posted 2010/03/30 at 8:31 pm | Permalink

        Ничего страшного ) Кому станет интересно, заглянет в предыдущий пост: http://hudson.su/?p=1243

  2. cug
    Posted 2010/04/23 at 8:23 pm | Permalink


    <a href="getNextPage() ) ?>" title="">>

    о господи, какой ужас, разве же так можно?

    должно быть так

    getNextPage()) ?>

    • hudson
      Posted 2010/04/23 at 8:37 pm | Permalink

      Честно говоря не понял :) Поясните пожалуйста.

  3. Bridun
    Posted 2010/07/12 at 11:17 pm | Permalink

    Помогите пожалуйста с этой постраничной навигацией

    уже голова трищит

  4. Bridun
    Posted 2010/07/12 at 11:22 pm | Permalink

    как делать инклюдом на страницу
    обшем у миня сраница на которую инклюдом подвязываю контент и тепер появилось уже 4 статьи и хочу на ту же страницу зделать постраничной навигацией не делая других помогите решить пожалуйста

    • hudson
      Posted 2010/07/12 at 11:24 pm | Permalink

      Ну так если symfony – берите этот сниппет и делайте ) Или переформулируйте вопрос.

  5. Bridun
    Posted 2010/07/12 at 11:30 pm | Permalink

    сраница на которую инклюдом подвязываю контент и тепер появилось уже 4 статьи для этой станицы и хочу на ту же страницу зделать постраничной навигацией инклюдом как 1.2.3.4. по одной

    • hudson
      Posted 2010/07/12 at 11:51 pm | Permalink

      Если вы считаете что я напишу код за вас, то это не так ) Но могу помочь наводящими вопросами. Пишите в скайп. Тут не чат все-таки.

  6. pivasyk
    Posted 2011/02/12 at 4:49 pm | Permalink

    Спасибо за пост. Разобрался с pager, а то их jobeet что то тяжелее в понимании :)

    • hudson
      Posted 2011/02/12 at 5:22 pm | Permalink

      Пожалуйста ) Рад был помочь

  7. pivasyk
    Posted 2011/03/19 at 8:20 pm | Permalink

    Подскажите пожалуйста как использовать методы с sfPager, а то я что то никак не пойму
    http://www.symfony-project.org/api/1_4/sfPager

    Или же как вывести общее количество страниц, или найденных объектов. Пример что в jobeet почему то не работает.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">