【问题标题】:Output certain product page on homepage / WooCommerce shortcode not working properly在主页上输出某些产品页面/WooCommerce 短代码无法正常工作
【发布时间】:2021-10-11 13:48:56
【问题描述】:

我需要在首页输出某个产品页面。 add_rewrite_rule 出于任何原因不适用于主页( 数据库中的首页实际上并没有重写规则,WordPress似乎使用了一些其他功能 查询首页):

//works fine
add_rewrite_rule( 'certainproductpage/?$',
    'index.php?post_type=product&name=certainproduct',
    'top'
);
//does not work 
add_rewrite_rule( '', //tried everything like "/", "/?$" etc
    'index.php?post_type=product&name=certainproduct',
    'top'
);

在花太多时间查看 wp / wc 核心代码和 stackoverflow 之后,我遇到了另一种选择。我可以 只需在页面内容中添加一个简码我需要同时成为主页和产品页面 时间:[product_page id=815]。确实它很好用,但只有在管理编辑器中添加短代码或 存储在数据库中(post_content)。如果我尝试在页面模板上手动调用简码( page-certainproductpage.php) 然后它输出产品页面而不需要一些必要的东西(PayPal、PhotoSwipe 和 画廊 js)。奇怪的是,如果我将简码保留在内容中(通过 Gutenberg / 代码编辑器)但不要 致电the_content 并仅回显短代码,然后一切正常:

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

get_header( 'shop' );

//works fine only if the same shortcode is within the certainproductpage's content
echo do_shortcode("[product_page id='815']");
//the_content();

get_footer( 'shop' );

另外,当我尝试通过the_content 过滤钩子添加短代码时,在核心的 do_shortcode 函数应用之前 default-filters.php ($priority

NOTICE: PHP message: PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /var/www/html/wp-includes/functions.php on line 5106

很遗憾,没有记录堆栈跟踪。第 5107 行周围的函数是 wp_ob_end_flush_all,它在 shutdown 上从 default-filters.php 调用

echo do_shortcode(apply_filters('the_content', "[product_page id=815]")); 也没有帮助(与不完整的输出相同 echo do_shortcode("[product_page id=815]");)

也很奇怪: 当我比较编辑器中的内容字符串和以编程方式添加的短代码字符串时,它是 相等!:

add_filter( "the_content", function ( $content ){
            $wtf = "<!-- wp:paragraph -->
<p>[product_page id=815]</p>
<!-- /wp:paragraph -->";
            $result = $wtf === $content;
            ?><pre><?php var_dump($result)?></pre><?php
            return $content;
}, 1 );

但是,如果我将 return $content 替换为 return $wtf - 我会得到超出最大执行时间的错误。

那么我如何才能在主页(“/”)上正确输出产品页面,或者如何使用简码获得相同的结果 当在 the_content 过滤器中应用时,就像在 (Gutenberg) 编辑器中添加短代码时一样?

更新

使用仅输出标题标签的简单自定义短代码对其进行了测试,并且可以与the_content 过滤器一起正常工作。还在一个仅安装了 WooCommerce 和 PayPal 的绝对干净的网站上进行了尝试——结果相同。似乎是 WooCommerce 方面的一个错误。本周某天将通过 xDebug 运行它。

【问题讨论】:

    标签: wordpress woocommerce


    【解决方案1】:

    好的,找到了一个 hacky 解决方案。我只是检查每个页面加载是否当前正在查询主页。然后我获取页面内容并检查它是否已经包含短代码。如果没有,那么页面内容会在数据库中更新,并附加短代码。

    //it has to be a hook which loads everything needed for the wp_update_post function 
    //but at the same time has not global $post set yet
    //if global $post is already set, the "certainproductpage"  will load content not modified by the following code
    add_action( "wp_loaded", function () {
        //check if homepage
        //there seems to be no other simple method to check which page is currently queried at this point
        if ( $_SERVER["REQUEST_URI"] === "/" ) {
            $page    = get_post(get_option('page_on_front'));
            $product = get_page_by_path( "certainproduct", OBJECT, "product" );
    
            if ( $page && $product ) {
                $page_content       = $page->post_content;
                $product_id         = $product->ID;
                $shortcode          = "[product_page id=$product_id]";
                        
                //add shortcode to the database's post_content if not already done
                $contains_shortcode = strpos( $page_content, $shortcode ) > - 1;
                if ( ! $contains_shortcode ) {
                    $shortcode_block = <<<EOT
    <!-- wp:shortcode -->
    {$shortcode}
    <!-- /wp:shortcode -->
    EOT;
                    $new_content     = $page_content . $shortcode_block;
    
                    wp_update_post( array(
                        'ID'           => $page->ID,
                        'post_content' => $new_content,
                        'post_status'  => "publish"
                    ) );
                }
            }
        }
    } );
    
    

    【讨论】:

      【解决方案2】:

      我建议一次一步。首先,这行得通吗?

      add_filter( "the_content", function ( $content ) {
         $content .= do_shortcode( '[product_page id=815]' );
         return $content;
      }, 1 );
      

      这应该将产品页面附加到每个 WordPress 页面/帖子。

      如果它有效,那么你需要将它限制在主页上,如果它是一个静态页面,则使用 is_front_page() 条件:

      add_filter( "the_content", function ( $content ) {
         if ( is_front_page() ) {
            $content .= do_shortcode( '[product_page id=815]' );
         }
         return $content;
      }, 1 );
      

      如果这也有效,那么我们将了解如何返回 Gutenberg 段落块,但不确定您为什么需要它,所以也许给我们更多上下文

      【讨论】:

      • 嘿,伙计,感谢您对此进行调查-我有时会看到您的帖子 :) 但是第一个建议会导致与问题中描述的相同的最大时间超出错误。第二个建议输出不完整的标记(缺少 PayPal 按钮、Gallery 和 LigthBox)。
      • 它必须是 Gutenberg 块,这样我才能比较字符串(数据库中的字符串是我作为 Gutenberg 编辑器中的块添加的)
      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      相关资源
      最近更新 更多