вторник, 18 марта 2008 г.

"Гибридный" вывод новостей (дочерние документы+категории)

Мы привыкли делать вывод новостей, статей, каталога продукции и тд., находящихся в определенной папке. То есть, имеем мы категории новостей (например: Новости шоу-бизнеса, Интервью, Мнения ...), они же у нас родительские документы к самим этим новостям. Есть и другие способы вывода, может быть из других родительских документов, из множества родительских документов, но суть одна - мы всегда выводим статьи из каких-либо папок. А что если какие-то документы, находясь в одной папке, должны выводиться и в других категориях (папках)? Не дублировать же их всюду?

Недавно столкнувшись с такой вот задачей "кросспостинга", я придумал следующее решение. Сразу замечу, можно легко решить проблему "свалив" все документы в одну папку и настроить категории только с помощью TV. Ditto при этом настроить элементарно. Однако в мою задачу входит сохранение уже существующей структуры папок и документов в них.

Для начала нужно определиться - документ в БД должен существовать в единственном экземпляре, никаких дублей! Задать категории, в которых он должен отобразиться помимо своей родительской мы можем с помощью TV (например типа список checkbox). Единственной проблемой теперь встает настройка вывода Ditto, который должен вывести все документы из родительского документа а также проверить принадлежность к заданной категории документов из других папок. На ум сразу же пришло использование параметра &filter, который может "отсеять" документы не принадлежащие к заданной папке И (именно логическое AND) не содержащие в определенном TV "упоминаний" о текущей категории. Однако есть досадная деталь: множество фильтров Ditto (например &filter=`test1,34,2|test2,78,1` поддерживают лишь логическое ИЛИ). Единственным выходом оказалось изучение и написание собственного (custom) фильтра. Сделать это можно на основе примерного фильтра в файле example.extender.inc.php. И подключить его параметром &extenders. не буду вдаваться в подробности кода, там достаточно все элементрано:
<?php
// ---------------------------------------------------
// Group: Filters
// Define custom or basic filters within the extender to expand Ditto's filtering capabilities
// ---------------------------------------------------

$filters["custom"]["exampleFilter"] = array("parent,artist_category","exampleFilter");
// Variable: $filters["custom"]["exampleFilter"]
// Add the filter exampleFilter to the custom filters
// list with the source pagetitle and the callback
// exampleFilter
if (!function_exists("exampleFilter")) {
// wrap functions in !function_exists statements to ensure that they are not defined twice

// ---------------------------------------------------
// Function: exampleFilter
//
// Takes the resource array for an individual document
// and asks for the return of a 0 or 1 with 0 removing
// the document and 1 leaving it in the result set.
// In this case, if the lower case value of the pagetitle
// is foo, it is removed while all other documents are shown
// ---------------------------------------------------
function exampleFilter($resource) {
global $modx;
$id = $modx->documentObject['id'];
if (!stristr($resource['artist_category'], $id) && $resource['parent'] != $id) {
return 0;
} else {
return 1;
}
}
}

?>

(если не менять название этого файла, то в вызове Ditto теперь достаточно прописать &extenders=`example`)

Напомню, этот фильтр проверяет отсутствие упоминания id категории в дополнительном параметре artist_category и неравенство родителя этому же id категории, если оба условия верны - документ отфильтровывается. В противном случае документ выводится на страницу. Таким образом, расставив галочки в нашем TV artist_category, мы можем "подцепить" документы из других папок к выводу документов заданной папки :)

4 комментария:

Анонимный комментирует...

У меня к вам вопрос ;-)
Вы кода нибудь сталкивались с проблемой вывода аннотации статьи с картинкой к ней ( сама картинка находится в статье ) ?
Можно ли эту проблему решить с помощью Дитто ?

yentsun комментирует...

хмм.. а в чем состоит проблема? Можно выводить часть статьи как аннотацию

Unknown комментирует...

Я сейчас переношу сайт на MODx и не пойму, как правильно сделать...

Есть странички с новостями, которые я хочу разместить в папке новостей и выводить их на общую страницу "Новости". Но для самих новостей мне надо сделать 5 категорий (кино, театр, шоу, альбомы, афиша). Чтобы новости одновременно выводились и на странице "Новости", и на страницах "кино", "театр", "шоу", "альбомы", "афиша".

Посоветуйте, пожалуйста, каким образом реализовать такой одновременный вывод новостей?

Unknown комментирует...

Почему может не работать элементарная фильтрация?
Пытаюсь отделить только записи помечанные как "Новые" с помощью TV "isnew":

example.extender.inc.php
http://pastie.org/379576

Вызов дитто:
[!Ditto? &startID=3&tpl=NewCars&depth=3&summarize=9&extenders=example&hideFolders=1&sortBy='createdon DESC'&truncText=''&paginate=0&dateSource=createdon&dateFormat=%d.%m.%y!]