Search code examples
phpwordpresstemplateswoocommercehook-woocommerce

Replace WooCommerce Single product short description with custom code


In the code below, I inserted a php block "shop_content" within a WordPress hook. In the output, as it should, the inserted php block shows up before the woocommerce_single_product_summary hook. So, "shop_content" shows up before the h1 title. My goal is to get the title above the shop_content, essentially adding custom html into a WordPress hook. I'm wondering if there is a way I can rearrange this hook without resorting to jQuery to reorder the divs? I'm viewing this hook guide as reference.

        <div class="<?php echo esc_attr($ozark_product_summary_class) ?>">
            <div class="summary entry-summary gs-product-summary">
                <?php
                /**
                 * Product Title
                 */
                if (ozark_inherit_option('general_title', 'general_title_product', '1') == '2') {
                    remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_title', 5);
                }?>

                <?php if ( is_active_sidebar( 'shop_content' ) ) : ?>
                    <div id="shop_description" class="shop-description widget-area" role="complementary">
                        <?php dynamic_sidebar( 'shop_content' ); ?>
                    </div>
                <?php endif; ?>

                <?php
                /**
                 * Hook: woocommerce_single_product_summary.
                 *
                 * @hooked woocommerce_template_single_title - 5
                 * @hooked woocommerce_template_single_rating - 10
                 * @hooked woocommerce_template_single_price - 10
                 * @hooked woocommerce_template_single_excerpt - 20
                 * @hooked woocommerce_template_single_add_to_cart - 30
                 * @hooked woocommerce_template_single_meta - 40
                 * @hooked woocommerce_template_single_sharing - 50
                 * @hooked WC_Structured_Data::generate_product_data() - 60
                 */

                // remove product short description 
                remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
                remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_rating', 10);
                add_action('woocommerce_single_product_summary', 'woocommerce_template_single_rating', 6);

                do_action('woocommerce_single_product_summary');
                ?>
                <?php if (get_theme_mod('product_share', '2') == '1') : ?>
                    <?php get_template_part('templates/extra/share') ?>
                <?php endif; ?>
            </div>
        </div>

Solution

  • You are making confusions… When making customizations:

    1. First, try to use available hooks (what you are not doing).
    2. Then, if you have no other choice, you can override WooCommerce templates.

    Important: You can not use add_action() or remove_action() on the template itself.

    With remove_action() and add_action() you can rearrange the output and also insert custom code, via your child theme functions.php file.

    So try the following instead:

    add_action( 'woocommerce_single_product_summary', 'custom_single_product_summary_start', 3 );
    function custom_single_product_summary_start(){
        if ( ozark_inherit_option('general_title', 'general_title_product', '1') == '2' ) {
            remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
        }
        remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_rating', 10);
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
    
        add_action('woocommerce_single_product_summary', 'woocommerce_template_single_rating', 6);
        add_action( 'woocommerce_single_product_summary', 'custom_short_description', 20 );
        add_action( 'woocommerce_single_product_summary', 'custom_single_product_summary_end', 100 );
    }
    function custom_short_description(){
        if ( is_active_sidebar( 'shop_content' ) ) { ?>
            <div id="shop_description" class="shop-description widget-area" role="complementary">
                <?php dynamic_sidebar( 'shop_content' ); ?>
            </div>
        <?php  }
    }
    
    function custom_single_product_summary_end(){
        if (get_theme_mod('product_share', '2') == '1') {
            get_template_part('templates/extra/share');
        }
    }
    

    Code goes in function.php file of your child theme (or in a plugin).

    Then your template code will be instead:

            <div class="<?php echo esc_attr($ozark_product_summary_class) ?>">
                <div class="summary entry-summary gs-product-summary">
                    <?php
                    /**
                     * Hook: woocommerce_single_product_summary.
                     *
                     * @hooked woocommerce_template_single_title - 5
                     * @hooked woocommerce_template_single_rating - 10
                     * @hooked woocommerce_template_single_price - 10
                     * @hooked woocommerce_template_single_excerpt - 20
                     * @hooked woocommerce_template_single_add_to_cart - 30
                     * @hooked woocommerce_template_single_meta - 40
                     * @hooked woocommerce_template_single_sharing - 50
                     * @hooked WC_Structured_Data::generate_product_data() - 60
                     */
                    do_action('woocommerce_single_product_summary');
                    ?>
                </div>
            </div>
    

    Related: WooCommerce action hooks and overriding templates