Random_news - случайная новость

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_newsDitto
1 6/19 7/20
2 7/20 7/20
3 8/21 7/20

Вывод

Ditto не так плох, как про него ходят слухи. Если у вас Ditto притормаживает, то или используются специфические настройки (фильтры и прочее), или стоит задуматься над более хорошим хостингом.
Так что пользоваться моим примером стоит если предполагается выводить только один-два случайных ресурса или модернизировав для более сложных случаем, когда Ditto начинает плохо справляться. Пример почти полностью построен на API MODx - надеюсь пояснения в коде позволят разобраться в их работе.


02.02.2012
blog comments powered by Disqus