如何有条件地删除商店页面上的用视频替换产品图像

时间:2020-04-23 作者:m_khan

我正在努力WordPress (woocommerce) 插件。

我想替换(的)产品图像shop 页码)由video 如果video 链接设置自dashboard(admin-panel) 对于特定产品,如果video 链接未设置,我想显示相关产品image, 我怎么能那样做?

Code I\'m using

add_action( \'init\', array($this, \'show_video_if_set_else_image\') );
public function show_video_if_set_else_image(){

    add_action(\'woocommerce_before_shop_loop_item_title\', \'show_video\');
    function show_video(){
        $linkk = get_post_meta(get_the_ID(), \'YT_video_link\', true);
        $linkk = substr($linkk, -11);
        if($linkk != \'\'){
            echo \'show video\';
            remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 );

            ?>
            <div class="woocommerce-product-gallery">

                <iframe width="420" height="315"
                src="http://www.youtube.com/embed/<?php echo $linkk; ?>" allowfullscreen>
                </iframe>
            </div>
            <?php

        }else{    # in this part I don\'t know what to do
            echo \'show image\';
            ?>
            <img src="<?php echo get_the_post_thumbnail_url( get_the_ID() ); ?>" />
            <?php
        }
    }
}
我问了这个问题here 还有,请看一下。我对php中的OOP有点陌生,在其他部分我应该做些什么load 相关图像,如果$linkk== empty, 因为目前某些产品的图像已加载twice (检查给出的链接)对我来说有点意外。

请帮忙,非常感谢。谢谢

当我这样做的时候remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 ); 在里面else 部分仍加载第二个产品image 虽然video 是为该产品设置的,为什么会这样?

this

1 个回复
最合适的回答,由SO网友:simongcc 整理而成

它装载了两次,我相信这是由于另一个钩子也存在。您可能需要移除另一个不需要的挂钩。实际上,你不必运行该操作woocommerce_before_shop_loop_item_title 在另一个钩子里。

类删除操作示例如果要在类中放置remove\\u操作,有不同的方法。以下示例说明了两种方法。下面的类被证明可以用于放置默认店面主题的函数。php或插件,前提是站点运行时不受其他插件的干扰。

class example {
    public function __construct() {
        // option1: place here will work
        remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 );

        // wrong demonstration: will not work because original call is not a class, it is not necessary to use class method to remove
        // remove_action( \'woocommerce_before_shop_loop_item_title\', array( $this \'woocommerce_template_loop_product_thumbnail\' ), 10 );

        add_action( \'init\', array( $this, \'init\' ) );
    }

    // option2: if you want to ***group different actions*** together, it also works.
    public function init() {
        // place here also work
        // remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 );

        // other remove actions or actions
    } 
}

new example();
如果将动作移出init 钩住并重试,然后移除不需要的钩子。如果您想将其添加到插件中,而不需要init 胡克,就这样换吧。

// your \' show_video\' is already doing the job `show_video_if_set_else_image`
// so you might want to change this function name too
remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 );
add_action(\'woocommerce_before_shop_loop_item_title\', array($this, \'show_video\' ) );

    function show_video(){
        $linkk = get_post_meta(get_the_ID(), \'YT_video_link\', true);
        $linkk = substr($linkk, -11);
        if($linkk != \'\'){
            echo \'show video\';
            // if you put remove_action, it will not work as expected because the remove_action is run after add_action, so before it removes, it run already.

            ?>
            <div class="woocommerce-product-gallery">

                <iframe width="420" height="315"
                src="http://www.youtube.com/embed/<?php echo $linkk; ?>" allowfullscreen>
                </iframe>
            </div>
            <?php

        }else{    # in this part I don\'t know what to do
            echo \'show image\';
            ?>
            <img src="<?php echo get_the_post_thumbnail_url( get_the_ID() ); ?>" />
            <?php
        }
    }
关于优先级如果你想更改标题挂钩的优先级,你只需要早晚调整优先级,例如add_action( \'woocommerce_before_shop_loop_item_title\', \'some_function\', 50 );

WordPress挂钩系统是一个基于事件的系统。它遵循一系列称为过滤器或操作的事件。通常,过滤器允许您重写值,而操作允许您执行其他作业。所以它按照优先级和顺序运行。对于操作,它在特定的时间执行任务。所以,一次一份工作。除非有特殊原因,否则大多数情况下不需要添加使用其他作业的作业。因为action 自身独立存在于do_action().

即使你加入init 钩子,队列woocommerce_before_shop_loop_item_title 仍在运行do_action( \'woocommerce_before_shop_loop_item_title\'), 它不会提前运行。更改钩子的优先级是针对同一钩子,因为可能有一些其他正在运行的操作需要覆盖。然后,您可以调整挂钩以稍后运行,以确保覆盖工作。

关于double running

可能存在woocommerce_before_shop_loop_item_title 做类似事情的行动。所以如果它输出两次,因为您只输出一次,而原始动作输出一次。

如果要删除现有操作。您只需运行:(以下是Woocommerce默认操作)

remove_action( \'woocommerce_before_shop_loop_item_title\', \'woocommerce_template_loop_product_thumbnail\', 10 );
您可以参考remove_action()

钩子名称、函数名称和优先级必须与原始名称相同,才能将其删除,以便您可以参考该源代码或在文件夹中查找代码以获取准确信息。