Фильтруйте ресурсы по значению переменной шаблона с 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);
Другие вопросы по тегам