【问题标题】:Drupal: "previous and next" links in each node?Drupal:每个节点中的“上一个和下一个”链接?
【发布时间】:2010-09-12 12:18:17
【问题描述】:

我想为我的 Drupal 网站的每个节点添加上一个和下一个按钮。

这些链接应该指向网站内容中的下一个节点。

我该怎么做? 谢谢

【问题讨论】:

  • 这里提到的确切问题(节点 455 有一个到节点 454 的链接和一个到节点 456 的链接)可能会与其他模块一起做一些奇怪的事情。我建议尝试改写你想要发生的事情,不要使用没有内容类型的“上一个节点”和“下一个节点”。
  • 是的,我想按内容类型过滤

标签: drupal drupal-6


【解决方案1】:

这是 Aterchin 代码的 D7 版本。

<?php
/**
* Previous / Next function for nodes, ordered by node creation date
*
* @param $current_node: node object or node id
* @param $node_types:  array of node types to query
*
* @return array
* 
*/
function MODULE_prev_next_node($current_node = NULL, $node_types = array()) {
    // make node object if only node id given
    if (!is_object($current_node)) { $current_node = node_load($current_node->nid); }

    // make an array if string value was given
    if (!is_array($node_types)) { $node_types = array($node_types); }

    // previous
    $prev = db_select('node', 'n')
    ->fields('n',array('nid','title','created'))
    ->condition('n.status', 1,'=')
    ->condition('n.type', $node_types,'IN')
    ->condition('n.created', $current_node->created,'<')
    ->orderBy('created','DESC')
    ->range(0,1)
    ->execute()
    ->fetchAssoc();

    // next or false if none
    $next = db_select('node', 'n')
    ->fields('n',array('nid','title','created'))
    ->condition('n.status', 1,'=')
    ->condition('n.type', $node_types,'IN')
    ->condition('n.created', $current_node->created,'>')
    ->orderBy('created','ASC')
    ->range(0,1)
    ->execute()
    ->fetchAssoc();

    return array('prev' => $prev, 'next' => $next);
}
?>

【讨论】:

  • 这是一个很好的解决方案,因为其他答案中提到的一些第 3 方模块有点搞砸了。但我认为你的函数的第一行有一个小错误,但很容易修复:如果!is_object(…) 检查是true,那么你不应该访问$current_node-&gt;nid 字段,而是直接使用$current_node 值。此外,您还可以将检查更改为 is_numeric(…) 甚至 is_int(…)
【解决方案2】:

使用 Drupal 8,我最终创建了一个位于 modules/MY_MODULE/src/TwigExtension 中的 twig 扩展(其中 MODULE_NAME 是您的模块机器名称,如果您不知道如何创建自定义 D8 模块,you can refer to this official post )

namespace Drupal\MODULE_NAME\TwigExtension;

use Drupal\node\Entity\Node;

class PrevNextNode extends \Twig_Extension {
    /**
     * Generates a list of all Twig filters that this extension defines.
     */
    public function getFunctions() {
        return [
            new \Twig_SimpleFunction('customPrevious', array($this, 'customPrevious')),
            new \Twig_SimpleFunction('customNext', array($this, 'customNext'))
        ];
    }

    /**
     * Gets a unique identifier for this Twig extension.
     */
    public function getName() {
        return 'custom.prevnextnode_extension';
    }

    /**
     * Previous node
     * @param $prevNextInfo
     * @return array|bool
     */
    public function customPrevious($prevNextInfo)
    {
        $node = Node::load($prevNextInfo['nid']);
        return $this->getNodeInformation($prevNextInfo['node_type'], $node->getCreatedTime(), '<', 'DESC');
    }

    /**
     * Next node
     * @param $prevNextInfo
     * @return array|bool
     */
    public function customNext($prevNextInfo)
    {
        $node = Node::load($prevNextInfo['nid']);
        return $this->getNodeInformation($prevNextInfo['node_type'], $node->getCreatedTime(), '>', 'ASC');
    }

    /**
     * Get current langcode
     * @return string
     */
    public function getCurrentLangcode()
    {
        return \Drupal::languageManager()->getCurrentLanguage()->getId();
    }

     /**
      * Previous or next node
      * @param $node_type
      * @param $date
      * @param $date_comparator
      * @param $sort_order
      * @return array|bool
      */
    public function getNodeInformation($node_type, $date, $date_comparator, $sort_order)
    {
        $prev_or_next = \Drupal::entityQuery('node')
            ->condition('type', $node_type)
            ->condition('status', 1)
            ->condition('created', $date, $date_comparator)
            ->sort('created', $sort_order)
            ->range(0, 1)
            ->execute()
        ;

        if(!$prev_or_next) return false;

        // Get the node itself
        $prev_or_next = Node::load(array_values($prev_or_next)[0]);
        // Get the available languages for the given node
        $available_languages = $prev_or_next->getTranslationLanguages();
        // If the current language is defined in the available languages array
        if(array_key_exists($this->getCurrentLangcode(), $available_languages)){
            // Get the translated node
            $translation = $prev_or_next->getTranslation($this->getCurrentLangcode());

            // Return the information you need, can be w/e you want.
            return [
                'title' => $translation->getTitle(),
                'id' => $translation->id(),
                'path' => $translation->toUrl()->toString()
            ];
        }

        return false;
    }
}

然后您必须将您的 twig 扩展注册为服务(位于 modules/MY_MODULE 中的 MY_MODULE.services.yml)。

services:
  # Next / Previous links on selected node pages. class: namespace of your extension
  custom.prevnextnode_extension:
    class: Drupal\MODULE_NAME\TwigExtension\PrevNextNode
    tags:
      - { name: twig.extension }

清除 Drupal 8 的缓存,您就可以在 HTML 中的任意位置使用新的 twig 扩展。

{# make sure you get 'content_type' and 'nid' parameters (a preprocess file would be a good start) #}
{%
    set prevNextInfo = { 'node_type': 'content_type', 'nid' : 10 }
%}

{% if prevNextInfo.node_type and prevNextInfo.nid and (customPrevious(prevNextInfo) or customNext(prevNextInfo)) %}
    <div id="node-pagination">
        {% if customPrevious(prevNextInfo) %}
            <a href="{{ customPrevious(prevNextInfo).path }}" class="pagination-btn pagination-prev">{{ 'Previous node' }} : {{ customPrevious(prevNextInfo).title }}</a>
        {% endif %}
        {% if customNext(prevNextInfo) %}
            <a href="{{ customNext(prevNextInfo).path }}" class="pagination-btn pagination-prev">{{ 'Next node' }} : {{ customNext(prevNextInfo).title }}</a>
        {% endif %}
    </div>
{% endif %}

【讨论】:

  • 感谢这是一个非常有帮助的开始。
【解决方案3】:

Custom Pager module 完全符合您的要求。您可以使用视图来定义哪些节点是下一个/上一个节点。

如果您使用的是图像模块,则图像自定义寻呼机的设置在文档中。

【讨论】:

    【解决方案4】:

    我认为Previous/Next API 模块可能是您正在寻找的。​​p>

    来自模块页面:

    一种用于浏览下一个/上一个节点而不会使数据库服务器过载的 API。

    此模块允许您了解任何给定节点的前一个或下一个节点。这对于向用户提供导航链接非常有用,而无需动态地动态推断此类信息所需的昂贵查询。

    【讨论】:

      【解决方案5】:

      其他方式:drupal 包中的“book”模块。

      【讨论】:

        【解决方案6】:

        提姆托迪,伙计。我使用的选项不需要额外的模块,而是需要一些关于如何构建 Drupal 数据库的知识(加上一些基本的 SQL):

        • 为您的节点类型创建自定义模板,
        • 在模板中,根据您的需要添加一个数据库查询以获取下一个和上一个节点(根据您的需要进行过滤),
        • 提取这两个节点的 URL,
        • 将链接放在您需要的地方。

        它有点复杂,但最终很灵活;)

        【讨论】:

          【解决方案7】:

          这会在同一个函数调用中同时执行 prev/next 查询,并将 prev/next 信息作为数组返回。我首选的方法是重用代码。参数也更灵活。

          <?php
          /**
          * Previous / Next function for nodes, ordered by node creation date
          *
          * @param $current_node: node object or node id
          * @param $node_types:  array of node types to query
          *
          * @return array
          */
          function mymodule_prev_next_created($current_node = NULL, $node_types = array()) {
            // make node object if only node id given
            if (!is_object($current_node)) { $current_node = node_load($current_node->nid); }
          
            // make an array if string value was given
            if (!is_array($node_types)) { $node_types = array($node_types); }
          
            // previous
            $sql = "SELECT n.nid, n.title, n.created FROM {node} n
              WHERE n.created < %d AND n.type IN ('%s')
              AND n.status = 1 ORDER BY n.created DESC LIMIT 1";
            $result = db_query($sql, $current_node->created, implode("','", $node_types));
            $prev = db_fetch_object($result);
          
            // next
            $sql = "SELECT n.nid, n.title, n.created FROM {node} n
              WHERE n.created > %d AND n.type IN ('%s')
              AND n.status = 1 ORDER BY n.created ASC LIMIT 1";
            $result = db_query($sql, $current_node->created, implode("','", $node_types));
            $next = db_fetch_object($result);
          
            return array('prev' => $prev, 'next' => $next);
          }
          ?>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多