0

0

解决WooCommerce自定义模板分页内容重复加载问题

DDD

DDD

发布时间:2025-09-28 15:58:24

|

808人浏览过

|

来源于php中文网

原创

解决woocommerce自定义模板分页内容重复加载问题

在WooCommerce自定义订单或下载模板中,分页链接点击后内容始终显示第一页的问题困扰着许多开发者。本文将详细介绍如何通过调整页码获取方式和paginate_links函数参数,确保自定义查询的分页功能正常运作,从而实现正确的页面内容加载。

问题剖析:WooCommerce自定义模板分页挑战

当开发者在WordPress和WooCommerce环境中构建自定义模板(例如,用于展示用户订单历史或可下载产品)时,经常会遇到分页功能失效的问题。具体表现为:用户点击分页链接(如“第2页”)后,URL虽然正确地更新了(例如从mywebsite.com/account/downloads变为mywebsite.com/account/downloads/2),但页面显示的内容却依然是第一页的数据。

这通常发生在自定义循环(Custom Loop)中,特别是当使用wc_get_orders等WooCommerce特有的查询函数时。默认的WordPress分页机制(依赖get_query_var('paged'))可能无法在所有自定义URL结构或Endpoint下正确识别页码。问题的核心在于:

  1. 页码获取不准确:模板未能正确地从URL中解析出当前页码。
  2. 分页链接格式不匹配:paginate_links函数生成的链接格式与查询页码的机制不一致。

解决方案核心:调整分页参数与URL处理

解决此问题的关键在于两步:首先,采用更可靠的方法从URL中获取当前页码;其次,确保paginate_links函数生成的链接格式与新的页码获取机制相匹配。

步骤一:获取当前页码的正确姿势

在许多情况下,get_query_var('paged')可能无法在自定义的WooCommerce Endpoint或重写规则下正确工作。一个更健壮的方法是直接从$_GET请求中获取自定义的页码参数,并进行适当的过滤。

我们将$current_page(或$paged)变量的定义从:

$current_page = ( get_query_var('paged') ) ? get_query_var('paged') : 1;

修改为:

$paged = max( 1, (int) filter_input( INPUT_GET, 'pagina' ) );

解释:

课游记AI
课游记AI

AI原生学习产品

下载
  • filter_input( INPUT_GET, 'pagina' ):这是一个更安全、更明确地从$_GET数组中获取名为pagina的参数的方法。它有助于防止潜在的XSS攻击,并确保我们获取的是一个经过过滤的输入。
  • (int):将获取到的值强制转换为整数类型,确保其作为页码的有效性。
  • max( 1, ... ):确保页码至少为1,避免出现负数或零页码的情况。
  • 注意:这里的'pagina'是自定义的查询参数名,你可以根据需要更改,但必须与后续paginate_links的format参数保持一致。

步骤二:配置paginate_links以匹配新的URL结构

为了让paginate_links函数生成与我们新的页码获取方式兼容的URL,我们需要调整其format参数。

在paginate_links的参数数组中,将format值从:

'format' => '%#%', // 或者其他不带查询参数的格式

修改为:

'format' => '?pagina=%#%',

解释:

  • ?pagina=%#%:这告诉paginate_links函数,在生成分页链接时,应该将页码(由%#%占位符表示)作为pagina查询参数添加到URL中。例如,对于第二页,链接将变为mywebsite.com/account/downloads/?pagina=2。
  • 注意:base参数也需要正确设置,通常使用wc_get_endpoint_url()来获取当前Endpoint的URL。例如,'base' =youjiankuohaophpcn esc_url( wc_get_endpoint_url( 'libreria') ) . '%_%'。确保libreria与你的自定义Endpoint名称相符。

完整代码示例

以下是经过修正后的WooCommerce自定义订单(或下载)模板代码,其中包含了上述两项关键改动:

<?php

?><div class="orders-container"><?php

defined( 'ABSPATH' ) || exit;

// 确保下载产品存在,此处为示例,可根据实际需求调整
$downloads     = WC()->customer->get_downloadable_products();
$has_downloads = (bool) $downloads;

do_action( 'woocommerce_before_account_downloads', $has_downloads );

if ( $has_downloads ) {
    ?>
    <table class="table_orders heading">
        <tr>
            <td class="product_number">Ordine</td>
            <td class="product_name">Prodotto</td>
            <td class="product_data">Data</td>
            <td class="product_price">Totale</td>
            <td class="product_status">Stato</td>
            <td class="product_action">File</td>
        </tr>
    </table>
    <?php

    $order_statuses = array('wc-completed');
    // 步骤一:使用 filter_input 获取当前页码
    $paged = max( 1, (int) filter_input( INPUT_GET, 'pagina' ) );

    $args = apply_filters('woocommerce_my_account_my_orders_query',array(
        'customer_id'     => get_current_user_id(),
        'post_status'     => $order_statuses,
        'paged'           => $paged,
        'posts_per_page'  => 3, // 每页显示订单数量
        'paginate'        => true,
    ));
    $customer_orders = wc_get_orders( $args );

    // 遍历订单并显示内容
    foreach($customer_orders->orders as $order) {
        $orders_id = $order->get_id();
        $status =  wc_get_order_status_name( $order->get_status() );
        $date_created = $order->get_date_created()->date('d/m/Y');
        $order_total = $order->get_formatted_order_total();
        $view_order = $order->get_view_order_url();

        foreach($order->get_items() as $item_id => $item) {
            $product_name = $item->get_name();

            echo '
                <table class="table_orders">
                <tr class="table_row_items">
                    <td class="product_number">
                     <span class="mobile title">Ordine</span>
                     <span>#'. esc_attr($orders_id) .'</span>
                    </td>

                    <td class="product_name">
                     <span class="mobile title">Prodotto</span>
                     <a href="'. wp_kses_post($view_order) .'">'. wp_kses_post($product_name) .'</a>
                    </td>

                    <td class="product_data">
                     <span class="mobile title">Data</span>
                     <span>'. wp_kses_post($date_created) .'</span>
                    </td>

                    <td class="product_price">
                     <span class="mobile title">Prezzo</span>
                     <span>'. wp_kses_post($order_total) .'</span>
                    </td>

                    <td class="product_status">
                     <span class="mobile title">Stato</span>
                     <span class="label ' . $order->get_status() . '">'. wp_kses_post($status) .'</span>
                    </td>

                    <td class="product_action">
                     <span class="mobile title">File</span>
                     <a target=”_blank” href="'. esc_url($view_order) .'">Visualizza<i class="fa-duotone fa-eye"></i></a>
                    </td>
                </tr>    
                </table> 
            ';
        }
    }

    // 分页按钮 - 负责订单历史的分页按钮和页码
    ?><div class="container-pagination"><?php
        $args = array(
            'base'          => esc_url( wc_get_endpoint_url( 'libreria') ) . '%_%', // 替换 'libreria' 为你的自定义Endpoint
            // 步骤二:修改 format 参数以匹配新的页码获取方式
            'format'        => '?pagina=%#%',
            'total'         => $customer_orders->max_num_pages,
            'current'       => $paged,
            'show_all'      => false,
            'end_size'      => 3,
            'mid_size'      => 3,
            'prev_next'     => true,
            'prev_text'     => __('<i class="fa-regular fa-angle-left"></i><span>Indietro</span>'),
            'next_text'     => __('<span>Avanti</span><i class="fa-regular fa-angle-right"></i>'),
            'type'          => 'plain',
            'add_args'      => false,
            'add_fragment'  => ''
        );
        echo paginate_links($args);
    ?></div><?php
} else {
    ?><div class="msg_orders">La tua cronologia ordini è vuota!</div><?php
}
do_action( 'woocommerce_after_account_downloads', $has_downloads );

?></div>

关键点与注意事项

  1. get_query_var与filter_input的选择
    • get_query_var('paged')主要用于WordPress主查询或已注册的查询变量。在自定义模板和Endpoint中,尤其当URL结构不完全遵循WordPress默认的分页规则时,它可能无法按预期工作。
    • filter_input(INPUT_GET, 'param_name')直接从$_GET超全局变量中获取参数,并提供了强大的数据过滤和验证功能,更适合处理自定义的URL查询参数。
  2. paginate_links参数详解
    • base:生成链接的基础URL。wc_get_endpoint_url('your-endpoint')是获取WooCommerce自定义Endpoint URL的推荐方式。%_%是paginate_links内部用来替换页码的占位符。
    • format:定义页码如何插入到URL中。将其设置为?pagina=%#%是解决此问题的核心。
    • total:总页数,通常从自定义查询结果中获取(例如$customer_orders->max_num_pages)。
    • current:当前页码,必须与你从URL中获取的页码变量($paged)保持一致。
  3. 自定义Endpoint与URL重写
    • 如果你的分页链接是在WooCommerce的My Account页面下的自定义Endpoint中(如/account/libreria),那么wc_get_endpoint_url('libreria')会生成正确的Endpoint基础URL。
    • 确保你的WordPress永久链接设置(Permalinks)是除了“朴素”之外的任何一种,这样URL重写才能正常工作。
  4. 安全性考虑
    • 始终对从用户输入或URL中获取的数据进行过滤和转义。filter_input已经提供了初步的过滤。在输出到HTML时,使用esc_attr(), wp_kses_post(), esc_url()等WordPress函数进行转义,以防止XSS攻击。
  5. 调试技巧
    • 如果分页仍不工作,请检查浏览器开发者工具中的网络请求,确保分页链接的URL是正确的。
    • 使用var_dump($paged);和var_dump($customer_orders);来检查$paged变量是否正确获取了页码,以及wc_get_orders查询结果是否包含了正确的总页数。

总结

通过将页码的获取方式从get_query_var('paged')更改为filter_input(INPUT_GET, 'pagina'),并相应地调整paginate_links函数的format参数为?pagina=%#%,可以有效地解决WooCommerce自定义模板中分页链接点击后内容重复加载的问题。这一方法确保了自定义查询能够正确识别和响应URL中的页码参数,从而实现流畅且功能完善的分页体验。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

888

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

464

2024.06.27

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

100

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

106

2025.09.18

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1071

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

617

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

335

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

2

2026.03.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.7万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号