按类别内的标签过滤文章 - Joomla 和 K2

Posted

技术标签:

【中文标题】按类别内的标签过滤文章 - Joomla 和 K2【英文标题】:Filter articles by tag inside a category - Joomla and K2 【发布时间】:2015-06-08 13:00:29 【问题描述】:

我想制作一个带有标签列表的自定义模块。当点击一个标签时,访问者将被导航到一个类别页面,该页面将显示带有该标签的文章。

我不是 joomla 专家,我正在考虑像这样的超链接这样的解决方案,我会添加到模块内的标签中:

href="http://mywebsite.com/index.php/itemlist/tag/tokio%20city?category=places"

这可能吗?或者我怎么能达到这个结果? 谢谢!

【问题讨论】:

【参考方案1】:

这比 URL 中的查询字符串要复杂一些,因为您还需要调整模板。

如果您想让它尽可能简单,我建议使用模板覆盖创建一个新的 K2 模板并编辑类别模板,以便它可以读取查询字符串参数并仅显示已按类别过滤的文章以及通过查询字符串的标签。

这只是一个简短的操作方法,现在有更多细节:

1) 使用模板覆盖创建新的 K2 模板。

在您的模板中,如果它不存在,请创建一个文件夹结构/templates/your_template/html/com_k2/templates/default。如果您想拥有更多 K2 模板,可以将“默认”替换为任何名称,但您必须手动将新模板设置为您拥有的每个类别。

现在从“/components/com_k2/templates/default”中获取内容并将其复制到模板中的新文件夹中。现在,K2 正在使用您的 /templates/your_template/html/com_k2/ 文件夹中的模板。如果您不了解模板覆盖,请随时 google 更多详细信息,这在自定义模板时非常重要。

2) 编辑您的类别视图文件以使列表适应您的查询字符串

您现在感兴趣的文件位于/templates/your_template/html/com_k2/templates/default/category.php。打开此文件并尝试了解其中的重要内容:

Line 141
<?php foreach($this->leading as $key=>$item): ?>
Line 169
<?php foreach($this->primary as $key=>$item): ?>
Line 197
<?php foreach($this->secondary as $key=>$item): ?>
Line 226
<?php foreach($this->links as $key=>$item): ?>

这很重要。在这四个 foreach 循环中,有所有项目。然后,您可以将每个循环的内容包装到一个 if 条件中,以检查它是否具有 URL 中指定的所需标记。

举个例子,这是&lt;div id="itemListPrimary"&gt; 的代码。您可以将 category.php 文件中的整个 div 替换为以下代码,它将完美运行。我刚刚编写并测试了它。

<div id="itemListPrimary">

    <?php foreach ($this->primary as $key=>$item): ?>

        <?php
        # Get the value of the "tag" query string
        $jInput = JFactory::getApplication()->input;
        $myTag = $jInput->get('tag', null, 'STRING'); // Joomla 1.6+
        //$myTag = JRequest::getVar('tag'); // for Joomla 1.5

        # If the tag is empty, the query string is not specified and we'll go standard way without any tag filter
        if (empty($myTag)) 

            // Define a CSS class for the last container on each row
            if ((($key+1)%($this->params->get('num_secondary_columns'))==0) || count($this->secondary)<$this->params->get('num_secondary_columns'))
                $lastContainer= ' itemContainerLast';
            else
                $lastContainer='';
            ?>
            <div class="itemContainer<?php echo $lastContainer; ?>"<?php echo (count($this->secondary)==1) ? '' : ' style="width:'.number_format(100/$this->params->get('num_secondary_columns'), 1).'%;"'; ?>>
                <?php
                    // Load category_item.php by default
                    $this->item=$item;
                    echo $this->loadTemplate('item');
                ?>
            </div>
            <?php if(($key+1)%($this->params->get('num_secondary_columns'))==0): ?>
            <div class="clr"></div>
            <?php endif;

        # Otherwise the tag is set so we'll filter the articles by the tag
         else 

          # Get an array of all the tags that the current article in the loop has
          $articleTags = array();
          foreach ($item->tags as $tag) 
              $articleTags[] = $tag->name;
          

          # Check if the article has the tag specified in the URL as a query string
          if (in_array($myTag, $articleTags)) 

              # Now the default content of the foreach loop comes as written in the default K2 category.php template

              // Define a CSS class for the last container on each row
              if ((($key+1)%($this->params->get('num_secondary_columns'))==0) || count($this->secondary)<$this->params->get('num_secondary_columns'))
                  $lastContainer= ' itemContainerLast';
              else
                  $lastContainer='';
              ?>
              <div class="itemContainer<?php echo $lastContainer; ?>"<?php echo (count($this->secondary)==1) ? '' : ' style="width:'.number_format(100/$this->params->get('num_secondary_columns'), 1).'%;"'; ?>>
                  <?php
                      // Load category_item.php by default
                      $this->item=$item;
                      echo $this->loadTemplate('item');
                  ?>
              </div>
              <?php if(($key+1)%($this->params->get('num_secondary_columns'))==0): ?>
              <div class="clr"></div>
              <?php endif;
          
         ?>

    <?php endforeach; ?>
</div>

3) 了解网址的工作原理

我的典型类别 URL 是:

http://mywebsite.com/category-name

要仅显示带有指定标签的文章,请使用:

http://mywebsite.com/category-name?tag=your-tag

例如,如果您只想显示带有“Tokio City”标签的文章,请使用:

http://mywebsite.com/category-name?tag=Tokio City

完成。

这就是您所需要的基础知识。如果您只使用主要文章(没有前导和次要或链接),这就是您所需要的。当然,您可能还需要处理更多的事情:

没有指定标签的文章时的通知 没有多余的代码,我这样写是为了简单易读 SEO - URL 中的空格和特殊字符 确保不会打印空 div

但这将是更多的代码,我想让它简单易读。我想我给了你足够的开始,所以继续完成它,祝你好运:)

【讨论】:

您对这两个平台非常非常熟悉!感谢这个惊人的答案,我想在我提供反馈之前使用它。你写的sn-p效果很好,我只有两个问题:1.现在我的查询在一列中显示文章,我想这必须用“主要文章”来完成,但没关系,我想我以后可以在 CSS 中调整它,还是我应该使用辅助文章来显示结果? 2. 这些标准功能有没有文档,可以多学一些? :) 再次感谢,你太棒了。 这就是我这两年一直在做的:) 你可以在K2分类设置中设置每个分类和每种文章(最新、主要、次要、链接)的列数或者使用您的自定义 CSS,两者都很好用 :) 就个人而言,我建议您只使用一种类型的文章,比如说主要的,因为使用更多类型可能会给您带来一些意想不到的麻烦。我不认为有这方面的文档,它或多或少只是一点点 PHP 和 K2 知识。 我在上面的代码中遇到了一个小问题。不,它显示所有类别(餐厅、汽车租赁、俱乐部等,甚至查询:mywebsite.com/restaurants?tag=Tokio City)中带有标签=Tokio City 的帖子。有没有办法在餐厅类别帖子中仅显示有关餐厅的信息,而无需使用相同标签的汽车租赁和俱乐部?谢谢! 这是正确的行为。如果您只想显示带有查询字符串中指定标签的文章而不显示其他标签,请尝试将 if 部分从 if (in_array($myTag, $articleTags)) 更改为 if (in_array($myTag, $articleTags) &amp;&amp; count($articleTags) == 1) ,它应该可以工作。我没有测试过代码,你自己试试,告诉我。 谢谢!但这不是我所需要的。有许多来自不同类别的帖子具有相同的标签(即东京市)。但是当我导航到餐厅菜单(链接到餐厅类别)并查询标签:“东京市”时,我会收到来自所有其他类别的带有此标签的帖子,而不仅仅是来自餐厅类别。我想要实现的是这样的:“SELECT * FROM posts WHERE category='restaurants' AND tag='Tokio City'”

以上是关于按类别内的标签过滤文章 - Joomla 和 K2的主要内容,如果未能解决你的问题,请参考以下文章

php 为每个按类别排序的 joomla k2

如何为 k2 类别创建自定义模板并将此模板分配给 Joomla 支持?

在joomla k2 php中列出没有重复的类别

Joomla! K2 - K2 类别的额外字段

从 Joomla K2 中移除 RSS Feed 图标(链接)

Joomla 2.5 仅在 K2 类别上显示模块而不在 K2 项目上