You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce开发:使用esc_html时如何正常渲染带CSS的HTML标签

问题根源

esc_html()的设计逻辑就是把所有HTML特殊字符(<、>、引号等)转义为字符实体,浏览器会把转义后的内容识别为纯文本,不会解析为HTML标签,自然也不会加载绑定的CSS样式。你遇到的标签直接输出、样式失效是这个函数的正常表现,不是代码bug。
WordPress安全规范从来不是要求所有输出变量统一套esc_html(),必须根据变量的输出场景选择对应的转义函数,错用函数就会导致渲染异常。

对应场景的正确转义规则
  • 输出无HTML标签的纯文本(比如日期、订单号、状态名、商品名称这类普通字符串):用esc_html(),你代码里的$date_created本身是d/m/Y格式的纯日期,正确使用esc_html()不会影响样式。
  • 输出HTML属性内的URL值(比如href、src属性里的链接):用esc_url(),你代码里的订单详情链接$view_order、商品下载链接都属于这类。
  • 输出系统生成的可信HTML内容(比如WooCommerce返回的带格式的订单金额、商品图片、分页HTML这类包含合法标签和样式的内容):用wp_kses_post(),这个函数会过滤掉恶意脚本等危险内容,同时保留合法的HTML标签、属性和样式。
  • 输出普通HTML属性值(比如title、class里的动态内容):用esc_attr()。
代码修正示例

你之前测试的a标签案例属于典型的函数错用,不能把整个HTML标签字符串丢进esc_html(),要拆分动态部分分别转义:

// 错误写法:整个a标签被转义为纯文本
// echo esc_html( '<a href="http://www.example.com/">A link</a>' );

// 正确写法:静态标签保留,动态内容按位置转义
printf(
    '<a href="%s" target="_blank">%s</a>',
    esc_url( 'http://www.example.com/' ), // 链接用esc_url
    esc_html( 'A link' ) // 链接文本用esc_html
);

针对你提供的orders.php模板,核心需要修改的点:

  1. 把原来整块字符串拼接输出的写法改成PHP与HTML混写,只对动态变量做转义,静态写死的HTML标签不需要处理
  2. 修正你代码里target=”_blank”的全角引号问题,换成英文半角引号否则属性不生效
  3. 每个动态变量按输出场景匹配对应转义函数

修正后的完整模板代码如下:

<?php
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_account_orders', $has_orders );
?>
<div class="orders-container">
<table class="table_orders heading">
<tr>
 <td class="product_number"><?php esc_html_e( 'Ordine', 'your-theme' ); ?></td>
 <td class="product_name"><?php esc_html_e( 'Prodotto', 'your-theme' ); ?></td>
 <td class="product_data"><?php esc_html_e( 'Data', 'your-theme' ); ?></td>
 <td class="product_price"><?php esc_html_e( 'Totale', 'your-theme' ); ?></td>
 <td class="product_status"><?php esc_html_e( 'Stato', 'your-theme' ); ?></td>
 <td class="product_action"><?php esc_html_e( 'File', 'your-theme' ); ?></td>
</tr>
</table>
<?php
if ( $has_orders ) {
    foreach ( $customer_orders->orders as $customer_order ) {
        $order = wc_get_order( $customer_order );
        $items = $order->get_items();
        
        $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();

        foreach ( $items as $item ) {
            $product_name = $item->get_name();
            $product = $item->get_product();
            $order_img = '';
            if( $product instanceof WC_Product ){
                $order_img = $product->get_image();
            }

            $download_button = '';
            $downloads = $order->get_downloadable_items();
            if(is_array($downloads)) {
                foreach($downloads as $download_item){
                    $download_button .= sprintf(
                        '<a href="%s" target="_blank">%s</a>',
                        esc_url( $download_item['download_url'] ),
                        esc_html__( 'Download', 'woocommerce' )
                    );
                } 
            } 
            
            $view_order = $order->get_view_order_url();
            ?>
            <table class="table_orders">
            <tr class="table_row_items">
                <td class="product_number">
                    <span class="mobile title"><?php esc_html_e( 'Ordine', 'your-theme' ); ?></span>
                    <span>#<?php echo esc_html( $orders_id ); ?></span>
                </td>

                <td class="product_name">
                    <span class="mobile title"><?php esc_html_e( 'Prodotto', 'your-theme' ); ?></span>
                    <a href="<?php echo esc_url( $view_order ); ?>"><?php echo esc_html( $product_name ); ?></a>
                </td>

                <td class="product_data">
                    <span class="mobile title"><?php esc_html_e( 'Data', 'your-theme' ); ?></span>
                    <span><?php echo esc_html( $date_created ); ?></span>
                </td>

                <td class="product_price">
                    <span class="mobile title"><?php esc_html_e( 'Prezzo', 'your-theme' ); ?></span>
                    <span><?php echo wp_kses_post( $order_total ); ?></span>
                </td>

                <td class="product_status">
                    <span class="mobile title"><?php esc_html_e( 'Stato', 'your-theme' ); ?></span>
                    <span><?php echo esc_html( $status ); ?></span>
                </td>

                <td class="product_action">
                    <span class="mobile title"><?php esc_html_e( 'File', 'your-theme' ); ?></span>
                    <a target="_blank" href="<?php echo esc_url( $view_order ); ?>">
                        <?php esc_html_e( 'Visualizza', 'your-theme' ); ?>
                        <i class="fa-duotone fa-eye"></i>
                    </a>
                </td>
            </tr>    
            </table>
            <?php
            if( $download_button ) {
                printf( '<div class="container_orders_download">%s</div>', wp_kses_post( $download_button ) );
            }
        }
    }
    ?>
    <div class="container-pagination">
    <?php 
    $args = array(
        'base'          => esc_url( wc_get_endpoint_url( 'orders') ) . '%_%',
        'format'        => '%#%',
        'total'         => $customer_orders->max_num_pages,
        'current'       => $current_page,
        'show_all'      => false,
        'end_size'      => 3,
        'mid_size'      => 3,
        'prev_next'     => true,
        'prev_text' => '<i class="fa-solid fa-angle-left"></i>', 
        'next_text' => '<i class="fa-solid fa-angle-right"></i>',
        'type'          => 'plain',
        'add_args'      => false,
        'add_fragment'  => ''
    ); 
    echo wp_kses_post( paginate_links($args) );
    ?>
    </div>
<?php
} else {
    ?>
    <div class="msg_orders"><?php esc_html_e( 'La tua cronologia ordini è vuota!', 'your-theme' ); ?></div>
    <?php
} 
do_action( 'woocommerce_after_account_orders', $has_orders ); 
?>
</div>

内容的提问来源于stack exchange,提问作者Snorlax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:27:17