dede loop如何实现分页功能?

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

这是一个非常常见的需求,因为 {dede:loop} 是一个自由循环标签,不像 {dede:arclist}{dede:list} 那样自带分页功能,所以我们需要手动实现。

dede loop 如何分页
(图片来源网络,侵删)

实现分页的核心思路是:

  1. 获取总记录数:首先要知道总共有多少条数据,才能计算出总页数。
  2. 获取当前页码:通过 URL 参数(如 ?page=2)来判断用户当前在看第几页。
  3. 计算分页数据:根据当前页码和每页显示的数量,使用 LIMIT 子句从数据库中只查询当前页需要的数据。
  4. 生成分页导航条:根据总页数和当前页码,生成上一页、下一页、页码等链接。

下面我们提供两种主流的实现方法:


使用原生 PHP 代码(推荐,灵活高效)

这种方法的核心是利用 DedeCMS 提供的 GetOne()Execute() 方法来直接操作数据库,完全由自己控制分页逻辑。

完整代码示例

{dede:config.pagesize value='10'/}  <!-- 1. 设置每页显示条数,这里设为10条 -->
<?php
// 2. 获取当前页码,如果没有则默认为第1页
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? intval($_GET['page']) : 1;
// 3. 获取每页显示条数
$pagesize = (isset($cfg_pagesize) && is_numeric($cfg_pagesize)) ? $cfg_pagesize : 10;
// 4. 计算总记录数 (非常重要!)
//    这里假设你的 loop 查询是 "SELECT * FROM dede_archives WHERE typeid=1"
$sql_count = "SELECT COUNT(*) AS total FROM dede_archives WHERE typeid=1";
$row_count = $dsql->GetOne($sql_count);
$totalcount = $row_count['total'];
// 5. 计算总页数
$totalpage = ceil($totalcount / $pagesize);
// 6. 确保当前页码不超过总页数
if ($page > $totalpage) $page = $totalpage;
if ($page < 1) $page = 1;
// 7. 计算数据库查询的偏移量 (LIMIT offset, rows)
$offset = ($page - 1) * $pagesize;
// 8. 执行带分页的查询
//    注意:这里使用了 {$offset} 和 {$pagesize} 变量,DedeCMS 模板引擎会自动替换
$sql_query = "SELECT * FROM dede_archives WHERE typeid=1 ORDER BY id DESC LIMIT {$offset}, {$pagesize}";
$dsql->Execute('me',$sql_query);
// 9. 使用 {dede:loop} 循环输出当前页的数据
//    注意这里的源数据名称 'me' 必须和上面 Execute 的第二个参数一致
{dede:loop table='dede_archives' sort='id' if='typeid=1' row='{$pagesize}'}
    <li>
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:loop}
// 10. 生成分页导航条
<div class="dede_pages">
    <ul class="pagelist">
        // 上一页
        <li><a href="{dede:global name='phpurl'/}/your_list.php?page=<?php echo ($page-1 > 0 ? $page-1 : 1); ?>">上一页</a></li>
        // 页码列表
        <?php
        for ($i = 1; $i <= $totalpage; $i++) {
            if ($i == $page) {
                // 当前页,高亮显示,不添加链接
                echo "<li class='thisclass'><span>{$i}</span></li>";
            } else {
                // 其他页,生成链接
                echo "<li><a href='{dede:global name='phpurl'/}/your_list.php?page={$i}'>{$i}</a></li>";
            }
        }
        ?>
        // 下一页
        <li><a href="{dede:global name='phpurl'/}/your_list.php?page=<?php echo ($page+1 <= $totalpage ? $page+1 : $totalpage); ?>">下一页</a></li>
        // 跳转到指定页
        <li><span class="pageinfo">共 <strong><?php echo $totalcount; ?></strong> 条记录</span></li>
        <li><span class="pageinfo">/<?php echo $totalpage; ?> 页</span></li>
        <li>
            <form name="formsearch" action="{dede:global name='phpurl'/}/your_list.php">
                <select name="page" onchange="document.formsearch.submit()">
                    <?php
                    for ($j = 1; $j <= $totalpage; $j++) {
                        $selected = ($j == $page) ? "selected='selected'" : "";
                        echo "<option value='{$j}' {$selected}>第 {$j} 页</option>";
                    }
                    ?>
                </select>
            </form>
        </li>
    </ul>
</div>

代码详解

  1. {dede:config.pagesize value='10'/}:

    dede loop 如何分页
    (图片来源网络,侵删)
    • 这是一个 DedeCMS 的配置标签,用于在模板中定义一个变量 $cfg_pagesize,这是一种良好的实践,方便在后台统一修改每页显示数,你也可以直接在 PHP 代码里 $pagesize = 10;
  2. 获取当前页码 $page:

    • isset($_GET['page']) 检查 URL 中是否存在 page 参数。
    • is_numeric()intval() 确保传入的是数字,防止 SQL 注入等安全问题。
  3. 计算总记录数:

    • SELECT COUNT(*) AS total FROM ... 是获取数据表中记录总数的标准 SQL 语句。
    • $dsql->GetOne() 执行查询并返回第一行结果,我们从中取出 total 字段的值。
  4. 计算 LIMIT 偏移量:

    • LIMIT {$offset}, {$pagesize} 的意思是:从第 {$offset} 条记录开始,查询 {$pagesize} 条。
    • 第2页($page=2),每页10条($pagesize=10),则 offset = (2-1) * 10 = 10,查询语句就是 LIMIT 10, 10,即第11到第20条记录。
  5. {dede:loop} 的使用:

    dede loop 如何分页
    (图片来源网络,侵删)
    • 这里我们使用了 loop 标签的另一种写法:{dede:loop table='...' sort='...' if='...' row='...'}
    • table: 指定要查询的数据表。
    • sort: 排序字段。
    • if: 查询条件。
    • row: 每页显示的行数,我们这里用 {$pagesize} 变量动态传入。
    • 注意:虽然 row 属性可以限制输出条数,但它不能实现真正的分页(即 LIMIT),所以我们还是需要在 PHP 中执行 LIMIT 查询,loop 标签在这里只是一个循环输出工具,数据已经在 $dsql->Execute() 中准备好。
  6. 生成分页导航:

    • 这部分是纯 PHP 代码,在模板中直接输出 HTML。
    • 循环生成页码链接,并对当前页进行特殊样式处理(class='thisclass')。
    • 上一页/下一页链接需要判断边界,防止页码超出范围。
    • 跳转下拉框也是通过 PHP 动态生成 option 选项。

使用 list 标签的 pagesize 属性(简单但有限制)

如果你只是需要一个简单的分页,并且不关心复杂的排序或查询条件,可以借用 {dede:list} 的分页功能。

完整代码示例

{dede:list pagesize='10' titlelen='40' orderby='pubdate'}
    <li>
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:list}
<!-- 调用 {dede:list} 自带的分页标签 -->
<div class="dede_pages">
    <ul class="pagelist">
        {dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'}
        </ul>
</div>

代码详解

  1. {dede:list}:

    • 这个标签本身就是为分页列表设计的。
    • pagesize='10': 直接设置每页显示10条记录。
    • orderby='pubdate': 按发布时间排序。
    • 限制{dede:list} 的数据源是固定的,它只能列出某个栏目(typeid)下的文章,你无法像方法一那样自由地写 WHERE 条件(typeid=1 AND flag='c')。
  2. {dede:pagelist}:

    • 这是 {dede:list} 的配套分页标签,它会自动生成上一页、下一页、页码等。
    • listsize='4': 显示当前页码前后各4个页码。
    • listitem='...': 定义要显示的分页项,包括 info(记录总数/页数)、index(首页)、end(尾页)、pre(上一页)、next(下一页)、pageno(页码)。

何时选择方法二?

  • 优点:代码极其简单,无需写任何 PHP 逻辑。
  • 缺点:不够灵活,分页逻辑被 {dede:list} 标签绑定,无法进行自定义查询。

总结与对比

特性 方法一 (原生 PHP) 方法二 ({dede:list})
灵活性 极高,可写任意 SQL 查询条件 ,只能按栏目列表
性能 ,只查询当前页数据 ,底层也是 LIMIT
代码复杂度 较高,需要编写 PHP 逻辑 极低,纯模板标签
适用场景 自定义列表、特殊条件查询、API数据展示 普通的文章列表、产品列表等标准栏目内容
  • 如果你的需求是简单的文章列表分页,直接使用方法二 {dede:list},最快最方便。
  • 如果你的需求比较复杂,比如需要跨栏目查询、按特定字段排序、或者数据来源不是 dede_archives 表,那么必须使用方法一,虽然代码多一些,但能完全掌控分页逻辑。
-- 展开阅读全文 --
头像
如何用织梦搜索指定ID的文档?
« 上一篇 01-30
dede中arclist分页
下一篇 » 01-30
取消
微信二维码
支付宝二维码

目录[+]