Разделы

Сниппет MiniNEWS v0.3.2

Обновлён 01.03.2010 в 10.24

Описание:
Давно хотел написать легкий сниппет выводящий несколько новостей.
Тем паче что Ditto большой, толстый и два на страницу глючат очень сильно.

MiniNews делает 3 запроса к базе.
На стандартном шаблоне MiniNEWS и blank для основной + 1 TV
на VDS:
оперативка 192 Мб
процессор 500 МГц
генерит три документа:
0.0394 s — время на запросы к базе данных
5 — запросов к базе данных (2 приходятся на MODx)
0.1133 s — время на работу PHP скриптов
0.1527 s — общее время на генерацию страницы

Прошу использовать при желании.

И конечно же прошу совета:
Как использовать плейсхолдеры типа [+body+] в сниппете — такое ощущение что MODx их вырезает с корнем?

Фиксы:
— Ошибка даты в версии 0.3.0
— Ошибка « `` is not numeric and may not be passed to makeUrl() » когда total больше суммы документов.

Нововведения:
Поддержка TV:
Реализованная без API поддержка TV
&tv_name — необходимые TV параметры через запятую.
По умолчанию все TV
Зависит от: &tv_enable

&tv_enable — Определяет, включен ли механизм подстановки TV параметров: значения TRUE / FALSE
В шаблон нужно добавить плейсхолдер [~+tv_name+~] в который выведется содержание TV.
Например есть TV-картинка и TV текстовое поле с системными именами image и text соответственно.
Что бы вывести их в шаблон вставляем плейсхолдеры [~+image+~] и [~+text+~].
А вызов добавляем &tv_name=`image,system`
По умолчанию FALSE

Добавление полей при вызове:
&fields — поля, необходимые к получению. Желательно указывать, для уменьшения нагрузки к БД.
По умолчанию «id,pagetitle,description,alias,menutitle,longtitle,content,introtext,pub_date»



<?php
/*
Сниппет вывода новостей MiniNEWS  v0.3.2
Пример вызова:
[!MiniNEWS? &id=`1` &tpl=`MiniNEWS_tpl`!]
Переменные в вызове сниппета:

&id - ID родительского документа
По умолчанию "ID текущей страницы"

&dir - направление сортировки DESC ASC
По умолчанию "DESC"

&sort -поле для сортировки
По умолчанию "createdon"

&total - общее количество возвращаемых документов
По умолчанию "нет"

&fields - поля, необходимые к получению. Желательно указывать, для уменьшения нагрузки к БД.
По умолчанию "id,pagetitle,description,alias,menutitle,longtitle,content,introtext,createdon"

&data - формат даты
По умолчанию "%d.%m.%Y - %A"

&tv_name - TV параметры через запятую.
В шаблон нужно добавить плейсхолдер [~+tv_name+~] в который выведется содержание TV .
Например есть TV-картинка и TV текстовое поле с системными именами image и text соответственно.
Что бы вывести их в шаблон вставляем плейсхолдеры [~+image+~] и [~+text+~]. 
А вызов добавляем &tv_name=`image,system`
По умолчанию все TV
Зависит от: &tv_enable

&tv_enable - Определяет, включен ли механизм подстановки TV параметров: значения TRUE / FALSE
По умолчанию FALSE

&tpl - шаблон документа - чанк, что содержит плейсхолдеры, соответствующие названиям заданных полей
По умолчанию: "<dl class="mininews"><dt><a href="[~+id+~]">[~+pagetitle+~]</a>  - [~+createdon+~]</dt><dd>[~+introtext+~]</dd></dl>"

Поля (плейсхолдеры) по умолчанию:
[~[~+id+~]~] - ссылка 
[~+id+~] - ID
[~+pagetitle+~] - заголовок
[~+description+~] - описание
[~+alias+~] - псевдоним
[~+menutitle+~] - название ссылки
[~+longtitle+~] - расширенный заголовок
[~+content+~] - содержание документа
[~+introtext+~] - сокращенное содержание
[~+createdon+~] - дата
*/
            
// Поехали! Кот, одмин, шредер!
// Проверка поля для сортировки
        if(!isset($sort))$sort = 'createdon';
// Проверяем поля:         
		if(!isset($fields))
		{
		$fields = array('id','pagetitle','description','alias','menutitle','longtitle','content','introtext','createdon');
		}ELSE{
		$fields = explode(",",$fields);
		}
// Проверка направления сортировки
        if(!isset($dir))$dir = 'DESC';
        
// Проверка переменной формата даты
        if(!isset($data))$data = '%d.%m.%Y - %A';
        
// Проверка ID родительского документа
        if(!isset($id))$id = $modx->documentIdentifier;
		
// Проверка TV?

		if(!isset($tv_enable))$tv_enable=false;

// Проверка шаблона
        if(isset($tpl)){
        $chunk = $modx->getChunk($tpl);
        }ELSE{
        $chunk = '<dl class="mininews"><dt><a href="[~[~+id+~]~]">[~+pagetitle+~]</a>  - [~+createdon+~]</dt><dd>[~+introtext+~]</dd></dl>';
        }
// Готовим к использованию поля - переводим массив в тест и создаем массив плейсхолдеров       
		for ($i = 0; $i < sizeof($fields); $i++) {
                        if(isset($fields_txt)){
                                        $fields_txt = $fields_txt.','.$fields[$i];
                                }ELSE{
                                        $fields_txt =$fields[$i];
                                }
                $place_arr[$i] = '[~+'.$fields[$i].'+~]';
        } 
        
// Запрос в API        
        $child = $modx->getActiveChildren($id,$sort,$dir,$fields_txt);
        
// Обработка даты

				setlocale(LC_TIME, '');				
				foreach($child as $key => $value){
				$data_i = strftime($data,$value["createdon"]);
				$child[$key]["createdon"]= $data_i;
				}    
// print_r($child);
		
// Устанавливаем количество интераций
		if(!isset($total))$total = sizeof($child);
		if($total > sizeof($child))$total = sizeof($child);

		
// Выдергиваем TV
	if($tv_enable==true){

	// Формируем список всех ID
		for ($i = 0; $i < $total; $i++){
		$doc = $child[$i];
		if(isset($id_arr))
			{
			$in = $id_arr.','.$doc['id'];
			$id_arr = $in;
			}ELSE{
			$id_arr= $doc['id'];
			}
		
		}
		// Вытаскиваем префикс
		$dbprefix = $modx->db->config['table_prefix'];

		// Формируем запрос к получению TV
		
		
		if(isset($tv_name)){
			$tv_que=str_replace(',','\',\'',$tv_name);
			$q_i=' AND '.$dbprefix.'site_tmplvars.name IN (\''.$tv_que.'\')';
		}ELSE{

		}
		$q='SELECT '.$dbprefix.'site_tmplvar_contentvalues.value, '.$dbprefix.'site_tmplvars.name, '.$dbprefix.'site_tmplvar_contentvalues.contentid  FROM '.$dbprefix.'site_tmplvar_contentvalues INNER JOIN '.$dbprefix.'site_tmplvars ON '.$dbprefix.'site_tmplvar_contentvalues.tmplvarid = '.$dbprefix.'site_tmplvars.id WHERE '.$dbprefix.'site_tmplvar_contentvalues.contentid IN ('.$id_arr.')'.$q_i.'';
		
		// Получаем TV
		$result = $modx->db->query($q);
		for ($tv_ar=array(); $row=mysql_fetch_assoc($result);$tv_ar[]=$row);

	}
		
// Основной цикл
        for ($i = 0; $i < $total; $i++) {
                $doc = $child[$i];
				
				// Поиск и замена плейсхолдеров
                $parce = str_replace($place_arr,$doc,$chunk);
				
				            
				
				// Создание и добавление ссылки
                $url = $modx->makeUrl($doc['id']);
                $parse_with_links = str_replace('[~[~+id+~]~]',$url,$parce);
				
				// Формируем TV
				foreach ($tv_ar as $value){if($value['contentid']==$doc['id']){$tv_on=true;break;}ELSE{$tv_on=false;}}

				if($tv_enable==true && $tv_on=true){
					foreach ($tv_ar as $value)
					{
						if($value['contentid']==$doc['id']){
							$tv_place='[~+'.$value[name].'+~]';
							
							if(isset($parse_with_tv))
							{
								$str_i = str_replace($tv_place,$value[value],$parse_with_tv);
								$parse_with_tv = $str_i;
							}ELSE{
								$parse_with_tv = str_replace($tv_place,$value[value],$parse_with_links);
							}
						}
					}
				
				echo $parse_with_tv;
				}ELSE{
				echo $parse_with_links;
				}
				
                
				// УСЁ!!!
                
         unset($parse_with_tv);               
        }
// удаляем переменные для возможности многократного вызова     
unset($id, $sort, $dir, $fields_txt, $data, $tpl, $tv_name, $total, $i, $int, $tv_name,$tv_enable);
?>
  • +6
  • 5 февраля 2010, 10:01
  • abadello

Комментарии (23)

RSS свернуть / развернуть
+2
2. makeUrl вам в помощь.
avatar

pitbull

  • 5 февраля 2010, 10:12
0
от спасибо! ужо поправил!
avatar

abadello

  • 5 февраля 2010, 10:17
+1
эх, TV бы ещё сюда добавить для вывода изображений.
avatar

NevroZ

  • 8 февраля 2010, 20:54
0
пожалуйста
avatar

abadello

  • 9 февраля 2010, 12:15
+1
Да, отсутствие обработки ТВ параметров — это основной минус. Но собсно, если они не используются (что тоже нередко встречается), то действительно Дитто абы-зря гонять не стоит.
avatar

iJack

  • 8 февраля 2010, 23:36
0
Добавил поддержку TV.
Следуя принципам — вывести новости как можно менее затратным способом эта поддержка скорее полуавтоматическая. Подробности в коде, там все описано.
avatar

abadello

  • 9 февраля 2010, 12:12
0
А кстати не замеряли по времени теперь? С функцией $modx->getTemplateVars в цикле ко всем выводимым новостям. Ибо это может потянуть посильнее, чем Дитто :) — отдельный запрос на каждую новость. В идеале, как я думаю, нужно вытягивать все для всех новостей все ТВ сразу.
avatar

iJack

  • 10 февраля 2010, 01:18
0
Вы предлагаете сделать выборку напрямую из базы, без API, в массив, а потом его печатать? Это просто единственное что мне приходит в голову.
avatar

abadello

  • 10 февраля 2010, 13:13
+1
Ну вобщем то да, почти напрямую, но с API… MODx DBAPI :)
$modx->db->query();
Это позволит не делать лишнее подключение к БД + системный счетчик кол-ва запросов к БД.
avatar

iJack

  • 10 февраля 2010, 14:11
0
))))))))
avatar

abadello

  • 10 февраля 2010, 14:12
0
Слушай, чет не пойму как префикс таблиц вычислить… ( Может подскажешь?
avatar

abadello

  • 10 февраля 2010, 14:53
0
ААА нашел!
avatar

abadello

  • 10 февраля 2010, 16:03
0
Фактически реализовал
avatar

abadello

  • 10 февраля 2010, 17:06
0
Поставил, на выходе получил:

аЂб�аЕб�б�б� аНаОаВаОб�б�б� — 01.01.1970
аЂб�аЕб�б�б� аНаОаВаОб�б�б�
а�аОб�б�б�аАб� аИаНб�аОб�аМаАб�аИб� аИаЗ аЖаИаЗаНаИ аНаАб�аЕаКаОаМб�б�…

а�аОаВаОб�б�б� аНаОаМаЕб� аДаВаА — 01.01.1970
а�аОаВаОб�б�б� аНаОаМаЕб� аДаВаА:
б�аАаМаАб� аПб�аЕаКб�аАб�аНаАб� аНаОаВаОб�б�б� аНаА б�аВаЕб�аЕ — аОб�аЕаНб� аИаНб�аЕб�аЕб�аНаАб� аНаОаВаОб�б�б� — б�аМаОб�б�аИб�аЕ, б�аИб�аАаЙб�аЕ, аВаНаИаМаАаЙб�аЕ…

а�аОаВаОб�б�б� аНаОаМаЕб� аОаДаИаН — 01.01.1970
а�аОаВаОб�б�б� аНаОаМаЕб� аОаДаИаН:
аНаЕаКаОб�аОб�аОаЕ аКб�аАб�аКаОаЕ аОаПаИб�аАаНаИаЕ аНаОаВаОб�б�аИ

« MODx Parse Error »
MODx encountered the following error while attempting to parse the requested resource:
« `` is not numeric and may not be passed to makeUrl() »
— EVO-1.0.2
avatar

kalina

  • 9 февраля 2010, 23:56
0
покажите вызов и шаблон
avatar

abadello

  • 10 февраля 2010, 13:10
0
Ошибку пофиксил, а с кодировками это у вас беда
avatar

abadello

  • 10 февраля 2010, 13:46
0
Реализована поддержка TV без привязки к API, что свело нагрузку к минимуму.
avatar

abadello

  • 10 февраля 2010, 17:46
+1
Отлично! Спасибо!

Есть еще ошибки.
1. В разделе три документа. Дату публикации у документов я не ставил.
Все три вывелись нормально, за исключением их дат:
01.01.1970
2. Поставил у Двух документов даты публикации:
Новость номер два 26 02-02-2010 01:54:00
Новость номер один 22 01-02-2010 01:52:00
Новости вывелись в таком виде:
Новость номер два — 02.02.2010
Самая прекрасная новость на свете — очень интересная новость — смотрите, читайте, внимайте…
Новость номер один — 02.02.2010
некоторое краткое описание новости

Третья новость — 02.02.2010
Горячая информация из жизни насекомых…
т.е.
дата вывелась везде одинаковая, при этом у Третьего документа дата публикации не выставлена.
Шаблон использую дефолтный; EVO-102; кодировка UTF-8
avatar

kalina

  • 11 февраля 2010, 02:04
0
Тут важно учесть разницу между датами [*createdon*] и [*pub_date*]. [*createdon*] — создается и записывается ВСЕГДА при создании дока. А [*pub_date*] — только если ее явно указать или юзать ММ, там плагин автоматически заполняет. Собственно тут или иную дату нужно использовать в разных случаях по необходимости. Так что стоит учесть, что плэйсхолдер даты — это не только [*pub_date*] (это замечание, так сказать, автору топика :) ).
avatar

iJack

  • 11 февраля 2010, 12:30
0
Да, эти поправки я уже внес.
Думал сначала публикацию выводить, но пото уже понял что createdon адекватнее воспримится массами ))
Просто нашел косяк, с которым никак не разберусь, как поправлю только, сразу все и выкачу.
avatar

abadello

  • 11 февраля 2010, 12:37
0
А где же пагинатор? :)
avatar

Dorimen

  • 21 февраля 2010, 10:30
0
Внес фикс с датой, были проблемы.
Есть известная ошибка с использованием TV. Когда указано что TV есть а их нет.
Катастрофически не хватает времени.
avatar

abadello

  • 1 марта 2010, 10:28
0
не туда, но все поняли ))
avatar

abadello

  • 1 марта 2010, 10:28

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.