【问题标题】:Filter resources by template variable value with MODx Wayfinder使用 MODx Wayfinder 按模板变量值过滤资源
【发布时间】:2014-08-08 14:51:54
【问题描述】:

我有一个网站,它使用 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 提示符上给了我正确的 ID,但是像这样将它添加到 Wayfinder 调用中再次给出了一个空结果:

&where=`["id IN (SELECT contentid FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=17 AND value LIKE '%Highlights%')"]`

关于如何实现这一目标的任何想法?为了保持一致性,我想继续使用 Wayfinder,但也欢迎使用其他解决方案。

【问题讨论】:

    标签: modx modx-revolution wayfinder


    【解决方案1】:

    您可以只使用pdomenupdoTools 的一部分)代替 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%"}]`
    
    ]]
    

    【讨论】:

    • 感谢您的建议!我现在不喜欢安装额外的插件,但它看起来相当通用。不过,额外的页面显示“9 个喜欢,56 个不喜欢”。你知道为什么会这样吗?
    • 这不是插件,它只是一些有用的sn-ps。大多数俄语文档是为什么这么多不喜欢的原因,但是如果您查看源代码 (github.com/bezumkin/pdoTools) 并了解它是如何工作的,它们很难帮助您开发
    • 啊,术语失误!我的意思是插件,就像我看到的“通过包管理器安装的东西”一样,语言障碍肯定是一个问题。我会记住 pdoTools,如果我以后再遇到查询问题!
    【解决方案2】:

    看看一些配置文件 [core/components/wayfinder/configs] - 我没有尝试过,但看起来你可以直接在配置中运行你的选择查询并将 tmplvarid 数组传递给$where 变量。

    【讨论】:

    • 如果我猜对了,你的建议类似于&where='["id IN [[!runMyQuery]]"]'(反引号被替换),只是查询是在 config.php 而不是 sn-p.php 中运行的,并且在配置而不是在寻路器调用中也设置了哪里?
    • 非常精确,但没有额外的 sn-ps 等。事实上,您可能只能使用 TV 值作为标准来获取 modResource 数组,但我不确定您是否会在标准中加入 TV vars 表[我不确定它们是否是 modResource 对象的一部分 ~ 你需要检查]
    【解决方案3】:

    玩了一会儿,我找到了一个解决方案:在引用 ID 时,我需要包含类名(而不是表名):

    &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,%'
        )
    )"]`
    

    我并没有声称这个查询特别有效(我似乎记得 OR 条件很糟糕)。此外,如果没有删除换行符,MODx 将无法与此一起使用。不过,我更喜欢以格式良好的形式发布查询。

    【讨论】:

      【解决方案4】:

      我使用 sn-p 作为 wayfinder 的 includeDocs 的参数,在我的情况下它很有用,因为我需要菜单中的不同资源取决于用户浏览器(移动或桌面)

      [[!Wayfinder? 
          &startId=`4`
          &level=`1`
          &includeDocs=`[[!menu_docs?&startId=`4`]]`
          &outerTpl=`home_menu_outer`
          &rowTpl=`menu_row`
      ]] 
      

      然后是 menu_docs sn-p

      <?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);
      

      【讨论】:

        猜你喜欢
        • 2017-07-25
        • 2015-06-18
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多