How to Remove Shop Text from Bread Crumb in woo commerce?[Home-->Shop-->Pink Himalayan Salt]
I want to Set Bread crumb as per my Navigation menu in m WordPress site.[Home-->Products-->Salt-->Pink Himalayan Salt]
I have used some Pages, Custom Links, Categories & Products to My main Menu.
See screenshot.
Bredcrumb -
Menu -
You can override WooCommerce templates via the theme (read the following official documentation):
Template Structure + Overriding Templates via a Theme
Once you have copied the file from plugins/woocommerce/templates/global/breadcrumb.php
to: themes/yourtheme/woocommerce/global/breadcrumb.php, you will be able to change the code by replacing it with the following:
<?php
/**
* Shop breadcrumb
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/breadcrumb.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.3.0
* #see woocommerce_breadcrumb()
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! empty( $breadcrumb ) ) {
$breadcrumb0 = $breadcrumb[0];
$shop_txt = __( 'Shop', 'woocommerce' );
$products_txt = __( 'Products', 'woocommerce' );
$products_url = home_url( '/products/' );
$breadcrumb10 = array( $products_txt );
$breadcrumb11 = array( $products_txt, $products_url );
if(is_product() || is_shop() || is_product_category() || is_product_tag() ){
if( $breadcrumb[1][0] == $shop_txt ){
if( ! empty( $breadcrumb[1][1] ) )
$breadcrumb[1] = $breadcrumb11;
else
$breadcrumb[1] = $breadcrumb10;
} else {
unset($breadcrumb[0]);
array_unshift($breadcrumb, $breadcrumb0, $breadcrumb11);
}
}
echo $wrap_before;
foreach ( $breadcrumb as $key => $crumb ) {
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
echo esc_html( $crumb[0] );
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
echo $delimiter;
}
}
echo $wrap_after;
}
This will:
Replace "Shop" by "Products"
Add "Products" just after "Home" when "Shop" doesn't exits.
So your breadcrumps will always start with: Home > Products on shop, archives and single product pages…
This might be solved with CSS, but cannot help unless you post a link to your shop.
Try like this:
Add this line to your custom CSS
ul.breadcrumbs li:nth-of-type(2) {display:none}
If it does not work, might also need !important
ul.breadcrumbs li:nth-of-type(2) {display:none!important}
I cannot comment that is why I had to answer. please provide the link of your site. I'll update my answer with exact CSS.
Inspired by LoicTheAztec, here is a solution for a similar but slightly different requirement. Let's say you just wanted to remove the Shop link completely:
Copy the file: plugins/woocommerce/templates/global/breadcrumb.php
to: themes/yourtheme/woocommerce/global/breadcrumb.php
In the new file, look for the line
foreach ( $breadcrumb as $key => $crumb ) {
and after that line, add this line:
if (trim(strip_tags($crumb[0])) == 'Shop') { continue; }
So the final code will look like this:
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! empty( $breadcrumb ) ) {
echo $wrap_before;
foreach ( $breadcrumb as $key => $crumb ) {
if (trim(strip_tags($crumb[0])) == 'Shop') { continue; }
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
echo esc_html( $crumb[0] );
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
echo $delimiter;
}
}
echo $wrap_after;
}
I have Got the answer by doing changes on functions.php
https://www.screencast.com/t/U42lqPduY707
if (get_post_type() == 'product')
{
echo sprintf($link, '#', esc_html__('Products', 'thegem'));
//echo sprintf($link, get_permalink(get_option ('woocommerce_shop_page_id' , 0 )), esc_html__('Product', 'thegem'));
$taxonomy = 'product_cat';
$terms = get_the_terms( $post->ID, $taxonomy );
foreach ( $terms as $c ) {
$c->term_id;
// echo '' . ($c->name ) . '';
if($c->term_id=='36') {
echo $delimiter;
echo sprintf($link, get_permalink( 106 ), esc_html__($c->name, 'thegem'));
}
}
}
else {
$slug = $post_type->rewrite;
printf($link, $home_link . '/' . $slug['slug'] . '/', $post_type->labels->singular_name);
}
Related
I've been trying for about three days now to get 4 of my woocommerce product attribute slugs instead of names to display underneath the products.
So far I've been using this code that does seem to do exactly what I want except for taking the attribute name instead of the value.
/**
* Display available attributes.
*
* #return array|void
*/
function iconic_available_attributes() {
global $product;
if ( ! $product->is_type( 'variable' ) ) {
return;
}
$attributes = iconic_get_available_attributes( $product );
if ( empty( $attributes ) ) {
return;
}
foreach ( $attributes as $attribute ) {
?>
<div class="iconic-available-attributes">
<p class="iconic-available-attributes__title"><?php _e( 'Available', 'iconic' ); ?> <strong><?php echo $attribute['name']; ?></strong></p>
<ul class="iconic-available-attributes__values">
<?php foreach ( $attribute['values'] as $value ) { ?>
<li class="iconic-available-attributes__value <?php echo $value['available'] ? '' : 'iconic-available-attributes__value--unavailable'; ?>"><?php echo $value['name']; ?></li>
<?php } ?>
</ul>
</div>
<?php
}
}
/**
* Get available attributes.
*
* #param WC_Product_Variable $product
*
* #return array
*/
/**
* #snippet Display Custom Products Attributes on the Products Page
*/
function cw_woo_attribute(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$display_result = '';
foreach ( $attributes as $attribute ) {
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
$cwtax = $terms[0]->taxonomy;
$cw_object_taxonomy = get_taxonomy($cwtax);
if ( isset ($cw_object_taxonomy->labels->singular_name) ) {
$tax_label = $cw_object_taxonomy->labels->singular_name;
} elseif ( isset( $cw_object_taxonomy->label ) ) {
$tax_label = $cw_object_taxonomy->label;
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$display_result .="<span class='attribute'>" . $tax_label . "</span>";
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
array_push( $tax_terms);
}
$display_result .= implode(', ', $tax_terms);
} else {
$display_result .= $name;
$display_result .= esc_html( implode( ', ', $attribute->get_options() ) );
}
}
echo "<span class='attributeline'>" . "| " . "</span>" . $display_result;
}
add_action('woocommerce_shop_loop_item_title', 'cw_woo_attribute', 25);
I'm not a PHP coder in any way so I've been struggling to get it to work.
Here is a sample of the current situation showing the name: "plant type" instead of the value: "annual".
Looking forward to your replies so I can move on with the rest of the shop!
Can you check this existing answer?
Wordpress Woocommerce Show attributes on shop page
I just tested it on a recent Woocommerce install, and the accepted answer seems to still work fine.
See if you can get it to work by predefining which attributes you want to show like they do in that question: pa_country, pa_class etc. You can see it in the following part.
// Define you product attribute taxonomies in the array
$product_attribute_taxonomies = array( 'pa_country', 'pa_class','pa_faction', 'pa_gender' );
If you don't want to predefine the attributes, you can still get them like below (also tested). But for testing, it might be helpful to just use the predefined strings so you are sure it's working.
$attributes = $product->get_attributes();
$attrs = [];
foreach($attributes as $key => $attribute) :
$attrs[] = $key;
endforeach;
// just replace the array with attribute names with $attrs
$product_attribute_taxonomies = $attrs;
Add the following code snippet to functions.php to display a coma separated string of term names under product on shop archive.
add_filter( 'woocommerce_after_shop_loop_item_title', 'loop_display_attr', 15 );
function loop_display_attr() {
global $product;
// The attribute slug
$attribute = 'attr';
// Get attribute term names in a coma separated string
$term_names = $product->get_attribute( $attribute );
// Display a coma separted string of term names
echo '<p>' . $term_names . '</p>';
}
I want to display the SKU field of each product in its signle product page. The woocommerce plugin's settings does not have that option in wordpress.
I already followed the instructions here:
https://wordpress.stackexchange.com/questions/219410/how-to-show-product-sku-on-product-page/219427#219427
I tried adding to my functions.php file this code:
add_action( 'woocommerce_single_product_summary', 'dev_designs_show_sku', 5 );
function dev_designs_show_sku(){
global $product;
echo 'SKU: ' . $product->get_sku();
}
And also tried to add this code to the theme's single product content file:
if ( 'sku' === $element ) {
woocommerce_template_single_sku();
}
file name is owp-single-product.php:
<?php
/**
* Single product template.
*
* #package OceanWP WordPress theme
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// Get price conditional display state.
$ocean_woo_single_cond = get_theme_mod( 'ocean_woo_single_conditional', false );
// Conditional vars.
$show_woo_single = '';
$show_woo_single = ( is_user_logged_in() && $ocean_woo_single_cond === true );
/**
* Display Single Product template
*
*/
// Get elements.
$elements = oceanwp_woo_summary_elements_positioning();
// Loop through elements.
foreach ( $elements as $element ) {
do_action( 'ocean_before_single_product_' . $element );
// Title.
if ( 'title' === $element ) {
woocommerce_template_single_title();
}
// Sku.
if ( 'sku' === $element ) {
woocommerce_template_single_sku();
}
// Rating.
if ( 'rating' === $element ) {
woocommerce_template_single_rating();
}
// Price.
if ( 'price' === $element ) {
if ( false === $ocean_woo_single_cond || $show_woo_single ) {
woocommerce_template_single_price();
}
}
// Excerpt.
if ( 'excerpt' === $element ) {
woocommerce_template_single_excerpt();
}
// Quantity & Add to cart button.
if ( 'quantity-button' === $element ) {
if ( false === $ocean_woo_single_cond || $show_woo_single ) {
woocommerce_template_single_add_to_cart();
} else {
// Get Add to Cart button message display state.
$ocean_woo_single_msg = get_theme_mod( 'ocean_woo_single_cond_msg', 'yes' );
if ( 'yes' === $ocean_woo_single_msg ) {
// Get Add to Cart button replacement message.
$ocean_woo_single_msg_txt = get_theme_mod( 'ocean_woo_single_cond_msg_text' );
$ocean_woo_single_msg_txt = $ocean_woo_single_msg_txt ? $ocean_woo_single_msg_txt : esc_html__( 'Log in to view price and purchase', 'oceanwp' );
$woo_single_myaccunt_link = get_theme_mod( 'ocean_single_add_myaccount_link', false );
echo '<div class="owp-woo-single-cond-notice">';
if ( false === $woo_single_myaccunt_link ) {
echo '<span>'. $ocean_woo_single_msg_txt .'</span>';
} else {
echo '' . $ocean_woo_single_msg_txt . '';
}
echo '</div>';
}
}
}
// Meta.
if ( 'meta' === $element ) {
woocommerce_template_single_meta();
}
do_action( 'ocean_after_single_product_' . $element );
}
Did not work! What do I do?
You can try this to show the sku after product title
add_action( 'ocean_after_single_product_title', 'show_product_sku', 5 );
function show_product_sku(){
global $product;
echo 'SKU: ' . $product->get_sku();
}
I'm using WooCommerce, I have Storefront theme applied and I have then created a childtheme of that which I can use to alter my site.
What I am trying to do is alter the final result in the breadcrumb shown on all pages to display the result in an <h2> tag, rather than the standard <p> tag it is currently in. So for example:
<p>Homepage > Page1 > Page2</p>
would end up becoming:
<p>Homepage > Page1 > </p><h2>Page2</h2>
I am a novice when it comes to altering childthemes on WordPress and have not been able to find any helpful answers online which is why I am asking for help here. I understand that the breadcrumbs.php file will need to be altered however I am unsure exactly what sections would need to be altered to allow for the changes I have proposed above. These changes are all essential for SEO purposes.
You can try rewrite breadcrumb.php in your theme, for example:
yourtheme/woocommerce/global/breadcrumb.php
And the code will be something like this:
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! empty( $breadcrumb ) ) {
echo $wrap_before;
foreach ( $breadcrumb as $key => $crumb ) {
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
echo '<h2 class="some-class">' . esc_html( $crumb[0] ) . '</h2>'; // edited here
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
echo $delimiter;
}
}
echo $wrap_after;
}
I'm using the following function to remove the product title from the breadcrumbs displayed on the product page:
add_filter( 'woocommerce_get_breadcrumb', 'ed_change_breadcrumb' );
function ed_change_breadcrumb( $breadcrumb ) {
if(is_singular()){
array_pop($breadcrumb);
}
return $breadcrumb;
}
It works in that it does remove the title, but it also stops the last category/sub-category from being a hyperlink. How can I fix that?
For example:
Original breadcrumb
<a>Home</a> / <a>Category</a> / <a>Sub Category</a> / Product Title
Result of the above function
<a>Home</a> / <a>Category</a> / Sub Category
I need the Sub Category to still be clickable after removing the product title from the breadcrumbs.
Thanks
Your code works but the last element in the breadcrumbs never contains a link through the code used in global/breadcrumb.php template file on line 34
This template can be overridden by copying it to yourtheme/woocommerce/global/breadcrumb.php.
So you can remove your filter hook and apply the following code in the template file so that it provides a link to the last element when is_product() is true
Note: is_product() - Returns true on a single product page. Wrapper for is_singular()
Replace
if ( ! empty( $breadcrumb ) ) {
echo $wrap_before;
foreach ( $breadcrumb as $key => $crumb ) {
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
echo esc_html( $crumb[0] );
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
echo $delimiter;
}
}
echo $wrap_after;
}
With
if ( ! empty( $breadcrumb ) ) {
echo $wrap_before;
foreach ( $breadcrumb as $key => $crumb ) {
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
if ( is_product() ) {
unset($crumb);
} else {
echo esc_html( $crumb[0] );
}
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
if ( is_product() && sizeof( $breadcrumb ) == $key + 2 ) {
echo '';
} else {
echo $delimiter;
}
}
}
echo $wrap_after;
}
I have e commerce website in wordpress. There are lot of product in it & many product comes under multiple categories like 600 mah Power bank is comes under automobile, IT, media etc. My problem is when i go to the detail of a product there it by default pick up only one category no matter if go through IT category at the end it shows me automobile like this Home / Shop / industry / Automobile / 600 mah Power Bank. But i went to this product via IT so it should show me like this Home / Shop / industry / IT / 600 mah Power Bank.
How can iget path where i come from previous page?
if you are using Woocommerce you can use the following directly, if not it will need adapting but you get the idea:
if (get_post_type() == 'product' && is_single() && ! is_attachment()) {
echo $prepend;
if ($terms = get_the_terms($post->ID, 'product_cat')) {
$referer = wp_get_referer();
foreach ($terms as $term) {
$referer_slug = (strpos($referer, $term->slug));
if ($referer_slug == true) {
$category_name = $term->name;
$ancestors = get_ancestors($term->term_id, 'product_cat');
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $ancestor) {
$ancestor = get_term($ancestor, 'product_cat');
if (! is_wp_error($ancestor) && $ancestor) {
echo $before . '' . $ancestor->name . '' . $after . $delimiter;
}
}
echo $before . '' . $category_name . '' . $after . $delimiter;
}
}
}
echo $before . get_the_title() . $after;
}
The main bulk of the work here is done by wp_get_referer which gets the referring URL of the product your visitor has navigated to. The rest of the code checks if a valid category is contained within the URL and uses it in the breadcrumb.
See Jonathon Js post here for more information http://www.cryoutcreations.eu/forums/t/wrong-breadcrumbs-displayed
Updated answer for anyone still encountering this issue on a newer version of WooCommerce, this solution worked for me on WooCommerce 3.5.4.
This code should be placed inside the following file path (i.e. a child theme)
/wp-content/themes/your-child-theme/woocommerce/global/breadcrumb.php
It will override the default WooCommerce breadcrumb code.
http://pastebin.com/raw/bemM8ZNF
/**
* Shop breadcrumb
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/breadcrumb.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 2.3.0
* #see woocommerce_breadcrumb()
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( $breadcrumb ) {
echo $wrap_before;
if ( is_single() && get_post_type() == 'product' ) {
echo $prepend;
if ( $terms = get_the_terms( $post->ID, 'product_cat' ) ) {
$referer = wp_get_referer();
$printed = array();
foreach( $terms as $term){
if(in_array($term->id, $printed)) continue;
$referer_slug = (strpos($referer, '/'.$term->slug.'/'));
if(!$referer_slug==false){
$printed[] = $term->id;
$category_name = $term->name;
$ancestors = get_ancestors( $term->term_id, 'product_cat' );
$ancestors = array_reverse( $ancestors );
foreach ( $ancestors as $ancestor ) {
$ancestor = get_term( $ancestor, 'product_cat' );
if ( ! is_wp_error( $ancestor ) && $ancestor )
echo $before . '' . $ancestor->name . '' . $after . $delimiter;
}
echo $before . '' . $category_name . '' . $after . $delimiter;
}
}
}
echo $before . get_the_title() . $after;
} else {
foreach ( $breadcrumb as $key => $crumb ) {
echo $before;
if ( ! empty( $crumb[1] ) && sizeof( $breadcrumb ) !== $key + 1 ) {
echo '' . esc_html( $crumb[0] ) . '';
} else {
echo esc_html( $crumb[0] );
}
echo $after;
if ( sizeof( $breadcrumb ) !== $key + 1 ) {
echo $delimiter;
}
}
}
echo $wrap_after;
}
C/O: Joris Witteman
I reworked the code a little bit to account for a primary category and a referred one, having infinite parents.
I used the breadcrumb filter as it is quite clean, directly in the single product template, but in case you need it elsewhere you can use the single conditional.
function breadcumbs_referred_or_primary ($main, $terms)
{
// Our primary term is 520 (hardcoded)
$referer = wp_get_referer();
$referredTerm = -1;
$referredTermIndex = -1;
$primaryTermId = 520; // hardcoded
$primaryTermIndex = -1;
foreach($terms as $key => $term) {
if ($referredTerm != -1) break; // we found it in a previous iteration!
$ancestors = get_ancestors( $term->term_id, 'product_cat');
array_unshift($ancestors, $term->term_id);
if ($primaryTermIndex == -1 && in_array($primaryTermId, $ancestors)) $primaryTermIndex = $key;
foreach ($ancestors as $ancestor) {
if($referredTerm != -1) break 2; // we found it in a previous iteration!
$ancestor = get_term( $ancestor, 'product_cat' );
$referer_slug = (strpos($referer, '/'.$ancestor->slug.'/'));
if (!$referer_slug==false) { // it's found in the current level
$referredTerm = $term->term_id;
$referredTermIndex = $key;
}
}
}
// we return either the browsed terms or the primary term
if ($referredTermIndex != -1) {
return $terms[$referredTermIndex];
} else {
return $terms[$primaryTermIndex];
}
}
add_filter('woocommerce_breadcrumb_main_term', 'breadcumbs_referred_or_primary', 10, 2);
My solution is:
if (!empty($breadcrumb)) {
echo $wrap_before;
if (is_single() && get_post_type() == 'product') {
$breadcrumb_diff = [];
$breadcrumb_diff[] = $breadcrumb[0];
if ($terms = get_the_terms($post->ID, 'product_cat')) {
$referer = wp_get_referer();
$site_url = site_url();
$referer = str_replace($site_url . '/zoomagazin/', '', $referer);
$referer_array = explode('/', $referer);
foreach ($referer_array as $term_slug) {
$get_term_by_slug = get_term_by('slug', $term_slug, 'product_cat');
$breadcrumb_diff[] = [$get_term_by_slug->name, get_term_link($term_slug, 'product_cat')];
}
$breadcrumb_diff[]= $breadcrumb[count($breadcrumb) - 1];
foreach ($breadcrumb_diff as $key => $crumb) {
echo $before;
if (!empty($crumb[1]) && sizeof($breadcrumb_diff) !== $key + 1) {
echo '' . esc_html($crumb[0]) . '';
} else {
echo esc_html($crumb[0]);
}
echo $after;
if (sizeof($breadcrumb) !== $key + 1) {
echo $delimiter;
}
}
}
} else {
foreach ($breadcrumb as $key => $crumb) {
echo $before;
if (!empty($crumb[1]) && sizeof($breadcrumb) !== $key + 1) {
echo '' . esc_html($crumb[0]) . '';
} else {
echo esc_html($crumb[0]);
}
echo $after;
if (sizeof($breadcrumb) !== $key + 1) {
echo $delimiter;
}
}
}
echo $wrap_after;
}