Random_news - случайная новость
Попробовал написать сниппет выводящий случайную новость, использовать Ditto не хотелось будучи наслышанным о большой нагрузке, которую он создает. Решил использовать API MODx, для выборки документов с последующей заменой плейсхолдеров и вывода случайной новости. Замечу, что таким способом можно выводить любые случайные данные, будь то товар в интернет-магазине или картинка для слайдера.
Вот что получилось:
Сниппет "random_news" для получения случайной новости
<?php $parent= isset($parent)? $parent:0; $tpl= isset($tpl)? $tpl:''; $display= isset($display)? $display:1; include_once(MODX_BASE_PATH.'assets/snippets/random_news/random_news.php'); ?>
Содержимое файла "random_news.php"
<?php
if ($display==1)
{
// если новость для вывода только одна,
// то используем упрощенный вариант
one_random_new($modx,$parent,$tpl);
}
else
{
// иначе используем более полный вариант
random_news($modx,$parent,$tpl,$display);
}
function random_news($modx,$parent,$tpl,$display){
// получаем список дочерних документов
$childIds = $modx-> getActiveChildren ($parent);
// если количество документов в категории меньше
// заданного кол-ва для вывода, то выводим сколько есть
if (count($childIds)<$display){$display=count($childIds);}
// формируем массив различных случайных идентификаторов новостей
do {
// тестовое случайное число
$test_rand = rand(0,count($childIds) - 1);
// если 0 значит такое число ещё не встречалось
$bil=0;
// перебираем уже имеющиеся числа
for ($x=0; $x<>count($array_index); $x++)
{
//если такое число уже было, то bil=1
if ($array_index[$x]==$test_rand){$bil=1;}
}
// а если не было, то добавляем к списку
if ($bil==0){$array_index[] = $test_rand;}
} while (count($array_index)<$display);
// повторять пока не наберется документов больше display
// перебираем выбранные случайные индикаторы документов,
// чтобы вывести сами документы
for ($x=0; $x<count($array_index); $x++)
{
// получим содержимое документа по ID
$random_doc = $modx->getDocument($childIds[$array_index[$x]]["id"]);
// обрабатываем чанк $tpl заменяем в нем плейсхолдеры
// на значения из массива $random_doc
$tplChunk = $modx->parseChunk($tpl, $random_doc,'');
echo $tplChunk;
}
}
function one_random_new($modx,$parent,$tpl) {
// получаем список дочерних документов
$childIds = $modx-> getActiveChildren ($parent);
// вычисляем случайный документ
$index = rand(0,count($childIds) - 1);
// получим содержимое документа по ID
$random_doc = $modx->getDocument($childIds[$index]["id"]);
// обрабатываем чанк $tpl заменяем в нем плейсхолдеры
// на значения из массива $random_doc
$tplChunk = $modx->parseChunk($tpl, $random_doc,'');
echo $tplChunk;
}
?>
Чанк для шаблона вывода "shablon_random_news"
<h2>[+pagetitle+]</h2> <p>[+introtext+]</p>
Вызов сниппета
[!random_news? &parent=`4` &display=`2` &tpl=`shablon_random_news` !]
| Параметры | Описание | Значение по умолчанию |
|---|---|---|
| &parent | Id начальной папки для вывода ресурсов. Корневая папка имеет id =0. | 0 |
| &display | Количество элементов для вывода | 1 |
| &tpl | Шаблон вывода. | [+pagetitle+] |
А потом я решил проверить насколько дольше будет делать ту же операцию Ditto и был несколько удивлен.
В качестве вызова Ditto использовалась такая строка с параметрами (только необходимое).
[!Ditto? &parents=`4` &display=`2` &tpl=`shablon_random_news` &randomize=`1`!]
За основной показатель качества было взято количество запросов в базу данных.
Начальные условия:
4/17 — количество запросов к базе данных (кэш/база)
| Количество выводимых ресурсов | Random_news | Ditto |
|---|---|---|
| 1 | 6/19 | 7/20 |
| 2 | 7/20 | 7/20 |
| 3 | 8/21 | 7/20 |
Вывод
Ditto не так плох, как про него ходят слухи. Если у вас Ditto притормаживает, то или используются специфические настройки (фильтры и прочее), или стоит задуматься над более хорошим хостингом.
Так что пользоваться моим примером стоит если предполагается выводить только один-два случайных ресурса или модернизировав для более сложных случаем, когда Ditto начинает плохо справляться.
Пример почти полностью построен на API MODx - надеюсь пояснения в коде позволят разобраться в их работе.
02.02.2012

