WooCommerce is creating category pagination pages for parent categories. We don't want these indexed, but I can't work out how best to do this.
For instance I have
https://www.i-hled.co.uk/product-category/light-engines/led-count-one/page/2/
This goes up to page 31, but I only want the main category page indexed not these paginated pages. This is NOT a site wide requirement, I still want other pages pagination to index, so I can't make a global change.
I've looked at the following
<meta name="robots" content="follow, <?php echo
(get_query_var('paged')==1)?'index':'noindex'?>" /><meta name="robots"
content="follow, <?php echo (get_query_var('paged')==1)?'index':'noindex'?
>" />
But that removes all pagination indexing
Also I thought of something along these lines in the header, but I can't work out how this would work with pagination.
if ( is_product_category(led-count-one){
echo "<meta name=\"robots\" content=\"noindex\" />";
}
Is there a way to do this in htaccess file instead? Or is code in the header.php file the best option?
https://www.i-hled.co.uk/product-category/light-engines/led-count-one/page/2/
https://www.i-hled.co.uk/product-category/light-engines/led-count-one/page/3/
etc
Will not be indexed, but
https://www.i-hled.co.uk/product-category/light-engines/led-count-one/one-led/page/2/
https://www.i-hled.co.uk/product-category/light-engines/led-count-one/one-led/page/3/
etc
Will be indexed
I used All in One SEO API to fix this as follows
add_filter( 'aioseop_robots_meta', 'change_robots_meta_value' );
function change_robots_meta_value( $robots_meta_value ) {
if( is_product_category( 'PYO' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'Light Engines' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'LED Count' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'Micromoles' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'Size' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'Wavelength' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
if( is_product_category( 'Thermal' ) && is_paged() ) {
$robots_meta_value = 'noindex,nofollow';
}
return $robots_meta_value;
}
Related
I want to hide post with specific category for users not logged in and with not specific group i checked i tried to use this code but it doesnt work it hides my homepage content etc.`add_filter( 'the_content', 'filter_the_content_in_the_main_loop', -1 );
function filter_the_content_in_the_main_loop( $content ) {
// Check if we're inside the main loop in a post or page.
if ( is_single()) {
if (has_term('categoryname', 'category')){
if ( (is_user_logged_in() && $customer_group_id == $group_id) || is_admin() ) {
return $content;
}
else
{
return $content ="". esc_html__("for specific users only", "my-textdomain");
}
}
else{
return $content;
}
}
}`
ho to make the code work on archive blog page , single post and do not break homepage(page)
You have to return the "$content" parameter in that filter please try the below code.
add_filter( 'the_content', 'filter_the_content_in_the_main_loop', 5, 1 );
function filter_the_content_in_the_main_loop( $content ) {
// Check if we're inside the main loop in a post or page.
if ( is_single() ) { // check if this is single or archive of post.
if ( has_term( 'categoryname', 'category' ) ){ // check specific category is include.
if ( ( is_user_logged_in() && $customer_group_id == $group_id) || is_admin() ) { // your user logged in and group logic.
return $content;
}else{
return $content ="". esc_html__("for specific users only", "my-textdomain");
}
}else{
return $content;
}
}elseif ( is_category( 'categoryname' ) ) {
if ( ( is_user_logged_in() && $customer_group_id == $group_id) || is_admin() ) { // your user logged in and group logic.
return $content;
}else{
return $content ="". esc_html__("for specific users only", "my-textdomain");
}
}else{
return $content;
}
}
i got this code from researching and trying to modify it but no luck. I want the last item in yoast breamcrumbs not to appear on single pages only
if ( is_single() ) {
/*Remove Last item in Yoast SEO Breadcrumb */
function adjust_single_breadcrumb( $link_output) {
if(strpos( $link_output, 'breadcrumb_last' ) !== false ) {
$link_output = '';
}
return $link_output;
}
add_filter('wpseo_breadcrumb_single_link', 'adjust_single_breadcrumb' );
};
I tried adding if is single in between the function and also this
if(strpos( $link_output, 'breadcrumb_last' ) !== false && is_single) {
unfortunately, the whole breadcrumb disappears.
with this code, you can remove post title in single page.
add_filter('wpseo_breadcrumb_single_link_info', 'remove_post_title_wpseo_breadcrumb', 10, 3);
function remove_post_title_wpseo_breadcrumb($link_info, $index, $crumbs)
{
if (is_singular() && isset($link_info['id']))
return [];
return $link_info;
}
Updated: In the latest version above code does not work perfectly.
for this reason, I removed the last item with regex:
function getBreadcrumb() {
if ( function_exists( 'yoast_breadcrumb' ) ) {
ob_start();
yoast_breadcrumb( '<p id="breadcrumb" class="meta-info">', '</p>' );
$breadcrumb = trim( ob_get_clean() );
if ( is_singular() )
$breadcrumb = trim( preg_replace( '/ ' . WPSEO_Options::get( 'breadcrumbs-sep' ) . ' <span class="breadcrumb_last" aria-current="page">(.*)<\/span>/i', '',
$breadcrumb ) );
echo $breadcrumb;
}
}
And call the function anywhere you want:
<?php getBreadcrumb() ?>
I have a category called 'News'. The category ID is '20'. I am using the Divi (Divi child) theme + Wordpress and want to shorten the excerpt for the News category.
I typically would use the 'add_filter' function like this:
<pre>
add_filter('excerpt_length', 'news_excerpt_length');
function news_excerpt_length($length) {
if(in_category(20)) {
return 30;
} else {
return 60;
}
}
</pre>
But that ain't workin'. I found the excerpt control in the 'main-modules.php' and figure to add my filter here? Has anyone done this?
I added the 'main-module.php' to the root of my child theme and then added this to my child 'functions.php'
<pre>
if ( ! function_exists( 'et_builder_add_main_elements' ) ) :
function et_builder_add_main_elements() {
require ET_BUILDER_DIR . 'main-structure-elements.php';
require 'main-modules.php';
do_action( 'et_builder_ready' );
}
endif;
</pre>
It didn't break the theme, but it didn't work either. Does anyone have any experience with this particular issue?
-Thanks!
To override the post_excerpt lengh, you can find in custom_functions.php the function truncate_post()
if ( ! function_exists( 'truncate_post' ) ) {
function truncate_post( $amount, $echo = true, $post = '', $strip_shortcodes = false ) {
global $shortname;
if ( '' == $post ) global $post;
$post_excerpt = '';
$post_excerpt = apply_filters( 'the_excerpt', $post->post_excerpt );
if ( 'on' == et_get_option( $shortname . '_use_excerpt' ) && '' != $post_excerpt ) {
if ( $echo ) echo $post_excerpt;
else return $post_excerpt;
} else {
// get the post content
$truncate = $post->post_content;
// remove caption shortcode from the post content
$truncate = preg_replace( '#\[caption[^\]]*?\].*?\[\/caption]#si', '', $truncate );
// remove post nav shortcode from the post content
$truncate = preg_replace( '#\[et_pb_post_nav[^\]]*?\].*?\[\/et_pb_post_nav]#si', '', $truncate );
// Remove audio shortcode from post content to prevent unwanted audio file on the excerpt
// due to unparsed audio shortcode
$truncate = preg_replace( '#\[audio[^\]]*?\].*?\[\/audio]#si', '', $truncate );
if ( $strip_shortcodes ) {
$truncate = et_strip_shortcodes( $truncate );
} else {
// apply content filters
$truncate = apply_filters( 'the_content', $truncate );
}
// decide if we need to append dots at the end of the string
if ( strlen( $truncate ) <= $amount ) {
$echo_out = '';
} else {
$echo_out = '...';
// $amount = $amount - 3;
}
// trim text to a certain number of characters, also remove spaces from the end of a string ( space counts as a character )
$truncate = rtrim( et_wp_trim_words( $truncate, $amount, '' ) );
// remove the last word to make sure we display all words correctly
if ( '' != $echo_out ) {
$new_words_array = (array) explode( ' ', $truncate );
array_pop( $new_words_array );
$truncate = implode( ' ', $new_words_array );
// append dots to the end of the string
$truncate .= $echo_out;
}
if ( $echo ) echo $truncate;
else return $truncate;
};
}
}
You don't need to put if ( ! function_exists( 'truncate_post' ) ) { to make it work just create your function with the same name in functions.php
If you are using a child theme (I really hope so with a theme like this), copy/paste index.php and paste these lines, line 54
if(in_category(20)) {
truncate_post( 30 );
} else {
truncate_post( 60 );
}
It can be easier
Hope it helps
I ended up doing it ( although I don't know which solution is better ) by putting this in my 'main-module.php' starting on line 12319
// do not display the content if it contains Blog, Post Slider, Fullwidth Post Slider, or Portfolio modules to avoid infinite loops
if ( ! has_shortcode( $post_content, 'et_pb_blog' ) && ! has_shortcode( $post_content, 'et_pb_portfolio' ) && ! has_shortcode( $post_content, 'et_pb_post_slider' ) && ! has_shortcode( $post_content, 'et_pb_fullwidth_post_slider' ) ) {
if ( 'on' === $show_content ) {
global $more;
// page builder doesn't support more tag, so display the_content() in case of post made with page builder
if ( et_pb_is_pagebuilder_used( get_the_ID() ) ) {
$more = 1;
the_content();
} else {
$more = null;
the_content( esc_html__( 'read more...', 'et_builder' ) );
}
} else {
if ( has_excerpt() ) {
the_excerpt();
} else {
if(in_category(20)) {
echo wpautop( truncate_post( 70, false ) );
} else {
echo wpautop( truncate_post( 370, false ) );
}
}
}
} else if ( has_excerpt() ) {
the_excerpt();
}
Is there a conditional function or another solution to check if the products are currently filtered?
Something like this would be great:
if( is_filtered() ) echo 'Filters active';
Amazing would be if the function returns the number of active filters (or a array) or false.
Thanks to David Chandra Purnama who pushed me in the right direction here's a very simple function to use:
function active_woocommerce_filters() {
// for older WC versions
// global $_chosen_attributes;
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
return count( $_chosen_attributes );
}
The function returns the number of active filters so it can be used like this:
if( active_woocommerce_filters() ) {
echo str_replace( '%s', active_woocommerce_filters(), 'There are %s filters active' );
} else {
echo 'There are no filters active';
}
EDIT:
As Artur Czyżewski pointed out the $_chosen_attributes global variable is not available in his installation. This is most likely due to changes to WooCommerce and probably affect all newer versions, so i've updated the active_woocommerce_filters function above.
You can check using global $_chosen_attributes;
WooCommerce "Layered Nav Filters" only displayed if filters is active. you can check the code "includes/widgets/class-wc-widget-layered-nav-filters.php":
global $_chosen_attributes;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
// Price
$min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : 0;
$max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : 0;
if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price ) {
/* Your Code Here. */
}
is_filtered() is a WooCommerce built-in function.
It returns true when filtering products using layered nav or price sliders.
Use case here
if ( is_filtered() ) {
echo esc_html__('Some filters are active.', 'text-domain');
} else {
echo esc_html__('No filters are active.', 'text-domain');
}
I am developing a WooCommerce plugin (actually usual WP plugin, but works only when WooCommerce enabled), which should to change standard WooCommerce output logic. In particular I need to override standard archive-product.php template by my own.
I have found there is no problem to change template in theme, but can not how to do it in the plugin. How I can do it without any changes in WP & WooCommerce cores?
I think you need to do it via hooks (filters & actions) available for WooCommerce.
Here is a list:
http://docs.woothemes.com/document/hooks/#templatehooks
Here is where to get started on hooks:
http://wp.tutsplus.com/tutorials/the-beginners-guide-to-wordpress-actions-and-filters/
Here is I try something like this. Hope it will help.
Add this filter into your plugin:
add_filter( 'template_include', 'my_include_template_function' );
And then the callback function will be
function my_include_template_function( $template_path ) {
if ( is_single() && get_post_type() == 'product' ) {
// checks if the file exists in the theme first,
// otherwise serve the file from the plugin
if ( $theme_file = locate_template( array ( 'single-product.php' ) ) ) {
$template_path = $theme_file;
} else {
$template_path = PLUGIN_TEMPLATE_PATH . 'single-product.php';
}
} elseif ( is_product_taxonomy() ) {
if ( is_tax( 'product_cat' ) ) {
// checks if the file exists in the theme first,
// otherwise serve the file from the plugin
if ( $theme_file = locate_template( array ( 'taxonomy-product_cat.php' ) ) ) {
$template_path = $theme_file;
} else {
$template_path = PLUGIN_TEMPLATE_PATH . 'taxonomy-product_cat.php';
}
} else {
// checks if the file exists in the theme first,
// otherwise serve the file from the plugin
if ( $theme_file = locate_template( array ( 'archive-product.php' ) ) ) {
$template_path = $theme_file;
} else {
$template_path = PLUGIN_TEMPLATE_PATH . 'archive-product.php';
}
}
} elseif ( is_archive() && get_post_type() == 'product' ) {
// checks if the file exists in the theme first,
// otherwise serve the file from the plugin
if ( $theme_file = locate_template( array ( 'archive-product.php' ) ) ) {
$template_path = $theme_file;
} else {
$template_path = PLUGIN_TEMPLATE_PATH . 'archive-product.php';
}
}
return $template_path;
}
I check this for theme first loading. If the file is not found in theme then it will load from the plugin.
You can change the logic here.
Hope it will do your work.
Thanks