覆盖WC_ShortCodes类中的静态方法(ShortCode)

时间:2018-06-02 作者:dingo_d

我正在尝试覆盖product_categories 来自WooCommerce的短代码,以便我可以向包装器添加其他类

[product_categories number="0" parent="0" class="container"]
所以我看了一下WooCommerce code, 并创建了一个扩展WC_Shortcodes 我只是复制了静态方法product_categories

  /**
   * Updated product categories shortcode
   *
   * List all (or limited) product categories.
   *
   * @param array $atts Attributes.
   * @return string
   */
  public static function product_categories( $atts ) {
    if ( isset( $atts[\'number\'] ) ) {
      $atts[\'limit\'] = $atts[\'number\'];
    }

    $atts = shortcode_atts( array(
        \'limit\'      => \'-1\',
        \'orderby\'    => \'name\',
        \'order\'      => \'ASC\',
        \'columns\'    => \'4\',
        \'hide_empty\' => 1,
        \'parent\'     => \'\',
        \'ids\'        => \'\',
        \'class\'      => \'\',
    ), $atts, \'product_categories\' );
    $ids        = array_filter( array_map( \'trim\', explode( \',\', $atts[\'ids\'] ) ) );
    $hide_empty = ( true === $atts[\'hide_empty\'] || \'true\' === $atts[\'hide_empty\'] || 1 === $atts[\'hide_empty\'] || \'1\' === $atts[\'hide_empty\'] ) ? 1 : 0;
    // Get terms and workaround WP bug with parents/pad counts.
    $args = array(
        \'orderby\'    => $atts[\'orderby\'],
        \'order\'      => $atts[\'order\'],
        \'hide_empty\' => $hide_empty,
        \'include\'    => $ids,
        \'pad_counts\' => true,
        \'child_of\'   => $atts[\'parent\'],
    );
    $product_categories = get_terms( \'product_cat\', $args );
    if ( \'\' !== $atts[\'parent\'] ) {
      $product_categories = wp_list_filter( $product_categories, array(
          \'parent\' => $atts[\'parent\'],
      ) );
    }
    if ( $hide_empty ) {
      foreach ( $product_categories as $key => $category ) {
        if ( 0 === $category->count ) {
          unset( $product_categories[ $key ] );
        }
      }
    }
    $atts[\'limit\'] = \'-1\' === $atts[\'limit\'] ? null : intval( $atts[\'limit\'] );
    if ( $atts[\'limit\'] ) {
      $product_categories = array_slice( $product_categories, 0, $atts[\'limit\'] );
    }
    $columns = absint( $atts[\'columns\'] );
    wc_set_loop_prop( \'columns\', $columns );
    wc_set_loop_prop( \'is_shortcode\', true );
    ob_start();
    if ( $product_categories ) {
      woocommerce_product_loop_start();
      foreach ( $product_categories as $category ) {
        wc_get_template( \'content-product_cat.php\', array(
            \'category\' => $category,
        ) );
      }
      woocommerce_product_loop_end();
    }
    woocommerce_reset_loop();
    return \'<div class="woocommerce columns-\' . $columns . \' \' . $atts[\'class\'] . \'">\' . ob_get_clean() . \'</div>\';
  }
并在初始化主题时初始化它(我使用this boilerplate).

很明显,这不起作用。我甚至尝试删除它,只需使用this code, 但那没用。

我唯一的选择是创建一个新的短代码并使用它吗?

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

以下是您可以(或应该)删除默认短代码的方式:

// Hook after `WC_Shortcodes::init()` is executed.
add_action( \'init\', function(){
    // Remove the shortcode.
    remove_shortcode( \'product_categories\' );

    // Add it back, but using our callback.
    add_shortcode( \'product_categories\', \'my_product_categories_shortcode\' );
}, 11 );
下面是如何修改默认快捷码的输出:

function my_product_categories_shortcode( $atts ) {
    $out = WC_Shortcodes::product_categories( $atts );

    // Modify the wrapper\'s opening tag.
    if ( ! empty( $atts[\'class\'] ) ) {
        $columns = isset( $atts[\'columns\'] ) ?
            absint( $atts[\'columns\'] ) : 4;

        $out = str_replace(
            \'<div class="woocommerce columns-\' . $columns . \'">\',
            \'<div class="woocommerce columns-\' . $columns . \' \' . esc_attr( $atts[\'class\'] ) . \'">\',
            $out
        );
    }

    return $out;
}
或者如果你愿意,你可以复制the whole code (即克隆)然后随心所欲:

function my_product_categories_shortcode( $atts ) {
    if ( isset( $atts[\'number\'] ) ) {
        $atts[\'limit\'] = $atts[\'number\'];
    }

    $atts = shortcode_atts( array(
        \'limit\'      => \'-1\',
        \'orderby\'    => \'name\',
        \'order\'      => \'ASC\',
        \'columns\'    => \'4\',
        \'hide_empty\' => 1,
        \'parent\'     => \'\',
        \'ids\'        => \'\',
        \'class\'      => \'\', // the extra arg
    ), $atts, \'product_categories\' );

    // ... refer to the link I provided

    return \'<div class="woocommerce columns-\' . $columns . \' \' . esc_attr( $atts[\'class\'] ) . \'">\' .
        ob_get_clean() . \'</div>\';
}

结束

相关推荐

Namespaced shortcode?

我正在改造一个旧的WP站点,该站点有许多自定义的短代码,显然由于代码当前的组织方式,这些短代码在性能方面付出了代价。当然,我可以修复优化不好的代码,使用十几个短代码,并且一天就可以完成,但我想知道如何更好地组织它们。根据WordPress\'documentation, 建议将它们放在插件中并在上初始化init. 我们可以通过这样“命名”它们来减少这个钩子中的负载吗?[com.company shortcode attr=\"attr\" prop=\"prop\"] 有人尝试过这样的解决方案吗