Блог на MODx Revolution: как сделать архив

Дорабатывая свой сайт, обнаружил, что на просторах отечественных интернетов тема MODx освещена весьма скудно, а там где освещена - в основном статьи по MODx Evolution, в то время как MODx Revolution широкой поступью набирает силу и мощь. Поэтому я решил написать несколько статей по MODx Revolution в ключе практических задач. Первая задача - организовать архив записей (фильтрацию по месяцам), как это сделано в небезызвестном Wordpress.

Начнем с начала: определимся с задачей и составим небольшую спецификацию, а-ля ТЗ.

Пользователь приходит на блог и просматривает записи. В специальном месте расположены ссылки на архивные записи по месяцам вида Декабрь 2010 (4), при нажатии на которую пользователю показываются только те блого-записи, которые были написаны в декабре 2010 года. В скобочках рядом с месяцем приведено количество записей за этот месяц (в данном примере - 4). Из описанного выше видно, что для наших целей необходимо каким-то образом передать выбранный месяц, пусть это будет параметр GET запроса с названием bymonth со значениями вида 201012, т.е. четыре цифры года и две цифры месяца. Также нам потребуется две функции, одна будет считать количество записей за месяц, проходя по всем блого-записям, чтобы сформировать ссыки архива, а другая - для выбора их базы данных только тех записей, которые были опубликованы в заданном месяце.

Сниппет getArchiveMonths для формирования ссылок архива:

$collection = $modx->getCollection('modResource', array(
    'published' => 1,
    'parent' => '2')
);

setlocale(LC_TIME, 'ru_RU.UTF8');
$output = "";
$months = array();

foreach ($collection as $resourceId => $resource) {
    $strmonth = date("Ym", $resource->publishedon);
    if(array_key_exists($strmonth, $months))
        $months[$strmonth]['count']++;
    else
    {
        $months[$strmonth]['count'] = 1;
        $months[$strmonth]['text'] = strftime("%B %Y", $resource->publishedon);
    }
}

krsort($months);

foreach ($months as $month => $count) {       
    $output .= $modx->getChunk($tpl, array( 
        'month' => $month,
        'text' => $count['text'] . ' (' . $count['count'] . ')'
    )); 
}

return $output;

В первом запросе мы получаем все документы, имеющие определенного родителя и опубликованные (при желании условия можно изменить, например на номер шаблона, который имеют блого-записи). Далее идет формирование словаря, ключом которого является месяц, а значением - пара значений: колчество записей в этот месяц и отформатированное название месяца. Потом этот словарь сортируется так, чтобы самые последние месяца шли раньше, и на его основе, а так же переданного чанка, генерируется кусок html-кода.

Вызов сниппета в моем случае (пробел между [ и [ сделан, чтобы MODx не обрабатывал его как вызов сниппета):

<ul>
    [ [getArchiveMonths? &tpl=`archiveMonthRow`]]
</ul>

Пример чанка:

<li><a href="/blog/?bymonth="></a></li>

Прекрасно. Теперь у нас есть набор ссылок, по которым пользователь может нажать, осталось обработать эти запросы.

Т.к. для отображения документов в большинстве своем используется сниппет getResources, то для того, чтобы он показал лишь определенные записи достаточно задать ему параметр resources:

if (!empty($_GET['bymonth'])) {
    $month = (int)$_GET['bymonth']; // для защиты от всякой дряни
    $ids = $modx->runSnippet('getResourcesIds',array(
         'month' => $month
    ));
    $scriptProperties['resources'] = $ids;
}

Сниппет getResourcesIds возвращает список id ресурсов, опубликованных в заданном месяце:

$collection = $modx->getCollection('modResource', array(
    "EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(`publishedon`)) = '$month'",
    'published' => 1,
    'parent' => '2'));
$output = "";
foreach ($collection as $resourceId => $resource) {
    $output.=$resourceId.',';
    }
if(strlen($output)>0)
    $output = substr($output, 0, -1);
return $output;

Вот таким образом я решил вопрос с организацией архива на своем блоге. Самое забавное то, что в процессе работы над статьей, я наткнулся на уже готовое решение данной проблемы от комманды MODx, называется Archivist. Как я его не заметил несколько месяцев назад, когда делал сайт - уму непостижимо. Ну ничего. Изобрел свой велосипед - стал умнее и опытнее =)

Thu, 20.01.2011

Теги: MODx