Skip to content
Advertisement

Woocommerce: How to show Product Attribute name and Category name on title

Using the answer provided in this thread (Woocommerce: How to show Product Attribute name on title when in a category page and “filtering” products via ‘?pa_attribute=’ on address bar) I would like to display the category as well as the attribute name. I have a separate JS function that is currently updating the page_title when a filter is applied but that is only loading after ajax has finished. So in this event it would not load till after the filter is applied.

In the event that a user uses the nav to get to the category, currently only the attribute is displaying in the page_title. Looking to also display the category. I believe this would work out of the box if I organized my products in to subcategories but due to how the filtering is being set up I elected not to go this route. I can explain in further detail why I had to take this approach if anyone is interested.

I have left the commented out code in so that you can see the approach I was attempting to take. If this is confusing can edit it out.

add_filter( 'woocommerce_page_title', 'custom_woocommerce_page_title', 15, 2 );

function custom_woocommerce_page_title( $page_title ) {
    if ( is_archive() ) {
        $exists_attr = false;

        foreach ( $_GET as $index => $value ) {
            if ( substr( $index, 0, 3 ) === 'pa_' ) {
                //$cat_id = wc_category_taxonomy_id_by_name( $index );
                $attr_id = wc_attribute_taxonomy_id_by_name( $index );

                if ( $attr_id === 0 && $cat_id ) {
                    continue;
                }

                if ( ! $exists_attr /* && ! $exists_cat */) {
                    $exists_attr = true;
                    //$exists_cat = true;

                    $page_title .= ' ';
                } else {
                    $page_title .= ' ';
                }

                //$terms = get_the_terms( $post->ID, 'product_cat' );
                $term = get_term_by( 'slug', esc_html( $value ), $index );
                $page_title =  /*$terms->name . ': ' .  */ $term->name;                     
                        
            }
        }

    }

    // Need to add category name after attribute term name.

    return $page_title;

}

Also, I have included the JS I am using to apply page_title in the event a filter selection occurs. Ideally it would be great if I could handle it all via a JS file as I am much more familiar with JS and just starting to dive in to php. I am using the WOOF – WooCommerce Products Filter and modifying some of the code to accomplish what I need.

(function() {
  var machineEl = document.getElementsByClassName('woof_select woof_select_pa_machine')[0];
  var processEl = document.getElementsByClassName('woof_select woof_select_pa_processing')[0];
  var optionMachine = machineEl.querySelector("option[selected='selected']");
  var optionProcess = processEl.querySelector("option[selected='selected']");
  var machineValue = optionMachine.innerHTML;
  var processValue = optionProcess.innerHTML;
  var result = document.getElementsByClassName('woocommerce-products-header__title page-title')[0];
  if (machineValue != 'Product Machine' && processValue != 'Product Processing') {
            result.innerHTML = machineValue + " " + processValue;            
  }
  else if (machineValue != 'Product Machine') {
            result.innerHTML = machineValue;            
  }
  else if (processValue != 'Product Processing') {
            result.innerHTML = processValue;            
  }       
})()

Advertisement

Answer

So was able to get this to work by taking my JS and adding it in as a script within my functions.php. So essentially I was able to eliminate the custom_woocommerce_page_title filter.

Function.php

<?php

add_action('wp_footer', 'onLoadPageTitle');
function onLoadPageTitle() {
    ?>
        <script>
                    
  machineEl = document.getElementsByClassName('woof_select woof_select_pa_machine')[0];
  processEl = document.getElementsByClassName('woof_select woof_select_pa_processing')[0];
  optionMachine = machineEl.querySelector("option[selected='selected']");
  optionProcess = processEl.querySelector("option[selected='selected']");  
  if (optionMachine != null) {
    machineValue = optionMachine.innerHTML;
  }
  else {
    machineValue = "";
  }
  if (optionProcess != null) {
    processValue = optionProcess.innerHTML;
  }
  else {
    processValue = "";
  }
  result = document.getElementsByClassName('woocommerce-products-header__title page-title')[0];
  result.innerHTML = machineValue + " " + processValue;   

        </script>
    <?php
}

?>

Then the woof woocommerce filter js that updates the title when a new select occurs after the AJAX.

(function() {
  machineEl = document.getElementsByClassName('woof_select woof_select_pa_machine')[0];
  processEl = document.getElementsByClassName('woof_select woof_select_pa_processing')[0];
  optionMachine = machineEl.querySelector("option[selected='selected']");
  optionProcess = processEl.querySelector("option[selected='selected']");  
  if (optionMachine != null) {
    machineValue = optionMachine.innerHTML;
  }
  else {
    machineValue = "";
  }
  if (optionProcess != null) {
    processValue = optionProcess.innerHTML;
  }
  else {
    processValue = "";
  }
  result = document.getElementsByClassName('woocommerce-products-header__title page-title')[0];
  result.innerHTML = machineValue + " " + processValue; 
})()

will probably pare it down by just calling the script function from within the woof js after ajax.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement