dede loop支持分页吗?如何实现?

99ANYc3cd6
预计阅读时长 16 分钟
位置: 首页 DEDE建站 正文

织梦(DedeCMS)的 {dede:loop} 标签本身不支持直接分页。

织梦 dede loop 可以分页吗
(图片来源网络,侵删)

下面我将详细解释原因,并提供几种常用的解决方案,以及推荐的最佳实践。


为什么 {dede:loop} 不支持分页?

要理解这个问题,我们需要知道 {dede:loop} 和另一个常用标签 {dede:arclist} 的核心区别:

  • {dede:arclist} (文章列表标签):

    • 数据来源: 直接从织梦的数据库 dede_archives (文章主表) 和 dede_addonarticle (文章附加表) 等核心内容表中查询。
    • 分页机制: 织梦系统为这个标签内置了强大的分页功能,系统会自动计算总文章数,根据你设置的 pagesize (每页显示数量) 来生成总页数,并处理 pageno (当前页码) 参数,从而实现分页查询和显示。
    • 适用场景: 主要用于调用系统里已经发布的文章、图集等常规内容。
  • {dede:loop} (循环标签):

    织梦 dede loop 可以分页吗
    (图片来源网络,侵删)
    • 数据来源: 它是一个通用的“万能”循环标签,其数据源完全由你自定义的 SQL 查询语句决定,它本身不关心数据是什么,只是忠实地执行你的 SQL 并循环输出结果。
    • 分页机制: 因为它的数据是任意的,系统无法预知你的 SQL 会查出多少条数据。{dede:loop} 标签本身没有内置分页逻辑,它只负责执行一次查询并输出所有结果。

{dede:loop} 是一个“执行器”,它只执行你给它的命令(SQL),而分页是一个“业务逻辑”,需要系统在执行命令前就知道总数据量并进行处理。


如何为 {dede:loop} 实现分页?

既然 {dede:loop} 不自带分页,我们就需要手动“赋能”,核心思路是:先进行分页查询,再将分页后的结果交给 {dede:loop} 显示。

以下是几种主流的实现方法,从最推荐到次推荐排序:

使用 {dede:pagelist} 标签(最推荐、最规范)

这是最标准、最符合织梦架构的解决方案,它利用了织梦内置的分页函数,只需要在循环标签之前加入一个 {dede:pagelist} 标签即可。

织梦 dede loop 可以分页吗
(图片来源网络,侵删)

步骤:

  1. 编写你的自定义 SQL,确保它包含一个 id 字段(作为唯一标识)。
  2. 在模板中,先使用 {dede:pagelist},它会自动处理分页逻辑。
  3. 然后使用 {dede:loop},在它的 sql 属性中,使用一个特殊变量 **tbname**,织梦在分页时,会自动将分页后的查询语句(通过 LIMIT 子句)赋值给这个 **tbname** 变量。

示例代码:

假设你想调用一个自定义的 my_product 表,并实现分页。

<!-- 1. 先调用分页标签 -->
{dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'}
<!-- 2. 再使用 loop 标签,关键在于 sql 属性中使用 'tbname' -->
{dede:loop table='my_product' sort='id' if='ischeck=1' row='10' sql='SELECT * FROM **tbname**'}
    <li>
        <a href="[field:link/]" title="[field:title/]">
            <img src="[field:pic/]" alt="[field:title/]">
            <h3>[field:title/]</h3>
            <p>价格:¥[field:price/]</p>
        </a>
    </li>
{/dede:loop}

代码解析:

  • {dede:pagelist ...}: 这个标签会根据当前页码和总记录数,生成分页链接(如 “首页 上一页 1 2 3 下一页 末页”)。
  • sql='SELECT * FROM **tbname**': 这里的 **tbname** 是一个“占位符”,当织梦处理 {dede:loop} 时,系统会自动将分页后的 SQL(SELECT * FROM my_product WHERE ischeck=1 ORDER BY id LIMIT 0, 10)替换掉 **tbname**,从而实现只查询当前页的数据。

优点:

  • 代码简洁:只需要两个标签配合。
  • 性能好:数据库只在每次请求时查询当前页的数据,而不是一次性查出所有数据。
  • 规范:完全遵循织梦的设计模式,兼容性好。

手动处理 PageNo 变量(灵活但复杂)

如果你不想使用 {dede:pagelist},或者需要更复杂的分页逻辑,可以手动获取并处理 PageNo 变量。

步骤:

  1. 在模板中通过 GetQuery('PageNo') 获取当前页码。
  2. 在自定义 SQL 中,使用 LIMIT 子句进行分页计算。
  3. 手动编写分页链接。

示例代码:

{php $listsize = 10;} <!-- 每页显示10条 -->
{php $pageno = isset($PageNo) ? intval($PageNo) : 1;}
{php $offset = ($pageno - 1) * $listsize;}
<!-- 自定义SQL,加入LIMIT分页 -->
{dede:loop table='my_product' sort='id' if='ischeck=1' row='10' sql="SELECT * FROM `my_product` WHERE ischeck=1 ORDER BY id LIMIT $offset, $listsize"}
    <li>
        [field:title/]
    </li>
{/dede:loop}
<!-- 手动生成分页链接 -->
<div class="page_links">
    {php $total_sql = "SELECT COUNT(*) as total FROM `my_product` WHERE ischeck=1";}
    {php $total_arr = $dsql->GetOne($total_sql);}
    {php $total_count = $total_arr['total'];}
    {php $total_page = ceil($total_count / $listsize);}
    <!-- 上一页 -->
    {if $pageno > 1}
        <a href="?PageNo={$pageno-1}">上一页</a>
    {/if}
    <!-- 页码 -->
    {php for($i=1; $i<=$total_page; $i++): }
        {if $i == $pageno}
            <span class='current'>{$i}</span>
        {else}
            <a href="?PageNo={$i}">{$i}</a>
        {/if}
    {php endfor; }
    <!-- 下一页 -->
    {if $pageno < $total_page}
        <a href="?PageNo={$pageno+1}">下一页</a>
    {/if}
</div>

优点:

  • 灵活性极高:可以完全自定义分页的样式和逻辑。
  • 不依赖特定标签:适用于各种复杂场景。

缺点:

  • 代码量大:需要手动编写大量 PHP 代码和 HTML。
  • 容易出错:需要自己处理页码计算、边界条件等。
  • 模板混乱:PHP 代码和 HTML 混合在一起,可读性较差。

总结与建议

方法 优点 缺点 推荐度
{dede:pagelist} 代码简洁、性能好、规范 灵活性相对较低 ★★★★★ (强烈推荐)
手动处理 PageNo 灵活性极高 代码量大、易出错、模板混乱 ★★☆☆☆ (不推荐,除非有特殊需求)

最终建议:

请优先使用方法一,即 {dede:pagelist}{dede:loop} 配合使用的方式,这是织梦社区公认的最佳实践,既能实现功能,又能保持代码的整洁和高效。

只有在分页需求非常特殊(比如需要动态改变每页显示数量、自定义分页算法等)时,才考虑使用方法二。

-- 展开阅读全文 --
头像
织梦搜索页如何支持dede type?
« 上一篇 昨天
dede审核后更新,栏目页首页如何同步?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]