Фильтруйте ресурсы по значению переменной шаблона с MODx Wayfinder
У меня есть сайт, который использует Wayfinder для отображения последних 3 записей из блога статей. Теперь я хочу рассмотреть только те записи в блоге, которые помечены Highlights
,
Мой оригинальный вызов Wayfinder выглядит так, ничего особенного:
[[!Wayfinder? &startId=`296` &level=`1`
&outerTpl=`emptyTpl`
&innerTpl=``
&rowTpl=`thumbnails_formatter`
&ignoreHidden=`1`
&sortBy=`menuindex`
&sortOrder=`DESC`
&limit=`3`
&cacheResults=`0`
]]
как теги статей управляются через articlestags
Телевизор, я думал, что &where
может сделать свое дело, но без удачи:
&where=`[{"articlestags:LIKE":"%Highlights%"}]`
ничего не дает. В качестве проверки работоспособности я попробовал [{"pagetitle:LIKE":"%something%"}]
, который работал. Очевидно, проблема в том, что articlestags
это не столбец modx_site_content
, но я не уверен, как поставить подзапрос.
SELECT contentid
FROM modx_site_tmplvar_contentvalues
WHERE tmplvarid=17
AND value LIKE '%Highlights%'
Дали мне правильные идентификаторы в приглашении sql, но добавление их к вызову Wayfinder, как это, снова дало пустой результат:
&where=`["id IN (SELECT contentid FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=17 AND value LIKE '%Highlights%')"]`
Есть идеи, как этого добиться? Я хотел бы остаться с Wayfinder для согласованности, но приветствуются и другие решения.
4 ответа
Небольшая игра привела меня к решению: мне нужно было включить имя класса (не имя таблицы) при обращении к идентификатору:
&where=`["modResource.id IN (SELECT contentid FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=17 AND value LIKE '%Highlights%')"]`
небольшой тест показал, что даже простой
&where=`["id = 123"]`
не работает без modResource.
,
Взгляд на wayfinder.class.php
показывает следующую строку, которая кажется "виновником":
$c->select($this->modx->getSelectColumns('modResource','modResource'));
Этот метод псевдоним выбранных столбцов - соответствующий код в xpdoobject.class.php
, Первый параметр - это имя класса, второй - псевдоним таблицы. Эффект состоит в том, что запрос выбирает id AS modResource.id
, и так далее.
РЕДАКТИРОВАТЬ: окончательная версия моего запроса:
&where=`["modResource.id IN (
SELECT val.contentid
FROM modx_site_tmplvars AS tv
JOIN modx_site_tmplvar_contentvalues AS val
ON tv.id = val.tmplvarid
WHERE tv.name = 'articlestags' AND (
val.value = 'Highlights'
OR val.value LIKE 'Highlights,%'
OR val.value LIKE '%,Highlights'
OR val.value LIKE '%,Highlights,%'
)
)"]`
Я не утверждаю, что этот запрос особенно эффективен (кажется, я помню, что условия ИЛИ плохие). Кроме того, MODx не будет работать с этим, если новые строки не будут удалены. Тем не менее, я предпочитаю публиковать запрос в его хорошо отформатированном виде.
Вы можете просто использовать pdomenu (часть pdoTools) вместо Wayfinder
[[!PdoMenu?
&startId=`296`
&level=`1`
&outerTpl=`emptyTpl`
&innerTpl=``
&rowTpl=`thumbnails_formatter`
&ignoreHidden=`1`
&sortBy=`menuindex`
&sortOrder=`DESC`
&limit=`3`
&cacheResults=`0`
&includeTVs=`articlestags`
&where=`[{"TVarticlestags.value:LIKE":"%filter%"}]`
]]
Взгляните на некоторые файлы конфигурации [core/components/wayfinder/configs ] - я не пробовал, но похоже, что вы можете выполнить свой запрос select прямо в config и передать массив tmplvarid в переменную $where,
Я использовал сниппет в качестве параметра для includeDocs wayfinder. В моем случае это было полезно, потому что мне требовались разные ресурсы в меню, зависящие от браузера пользователя (мобильный или рабочий стол)
[[!Wayfinder?
&startId=`4`
&level=`1`
&includeDocs=`[[!menu_docs?&startId=`4`]]`
&outerTpl=`home_menu_outer`
&rowTpl=`menu_row`
]]
а затем фрагмент menu_docs
<?php
if (empty ($startId))
return;
if (!isMobileDevice())
return;
$query = $modx->newQuery('modResource');
$query->innerJoin('modTemplateVarResource','TemplateVarResources');
$query->where(array(
'TemplateVarResources.tmplvarid' => 3,
'TemplateVarResources.value:LIKE' => 'yes',
'modResource.parent' => $startId,
'modResource.deleted' => 0,
'modResource.published' => 1,
'modResource.hidemenu' => 0
));
$resources = $modx->getCollection('modResource', $query);
$ouput = array();
foreach ($resources as $resource)
$output[] = $resource->get('id');
return implode (',', $output);