I am trying to create a custom layout for one of our product pages in Woocommerce. I have searched and followed so many tutorials, but none are working for me. I copied 'single-product.php' and placed it into my active child theme in the folder 'woocommerce'. I then duplicated this and renamed it 'single-product-landing.php'.
I then placed the following code into my functions.php page:
add_filter( 'template_include', 'custom_single_product_template_include', 10 );
function custom_single_product_template_include( $template ) {
if ( is_product() && ( has_term( 'custom', 'product_cat') ) ) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-landing.php';
}
return $template;
}
Then I tried changing items in single-product-landing.php but nothing is changing, so it can't be picking it up. To confirm, I have the product assigned to the 'custom' category.
I should also add that my product is a 'variable' product, am not sure if that has any affect on anything here.
EDIT: I have found the following code in my 'single.php' file - I think this may be interfering. Problem is, if I delete this nothing shows on any of my pages (even those not affected by the new template):
<?php
if(get_theme_mod('product_layout') == 'custom') {
wc_get_template_part( 'content', 'single-product-custom' );
} else {
wc_get_template_part( 'content', 'single-product' );
}
?>
Any idea how I can modify this to still have content show but not over-rule the template change that i'm trying to make?
Page templates are loaded after the template_filter has been run, so adding that code to a page template file will have no effect. To make that run, place the same code in your child theme's functions.php.
The 566 at the end of the add_filter line refers to the filter's loading priority and not a category id. Simply put, the higher the number the later the filter will be loaded.
Finally, your if statement can be simplified a little using Woocommerce functions - if ( is_product() && ( has_term( 'custom', 'product_cat') ) ) { - doesn't make much difference, but it's tidier.
Related
I've tried all the solutions posted to StackOverflow and still no dice.
Woocommerce mentions that "archive-product" will not be able to be overwritten if you use woocommerce.php, so what is the correct way to loop woocommerce_content(); ? and still be able to edit archive-product? No matter what I do, I can't edit archive-product. I did have success with this, but this seems like bad practice;
if ( is_singular( 'product' ) ) {
woocommerce_content();
} else {
//For ANY product archive.
//Product taxonomy, product search or /shop landing
woocommerce_get_template( 'archive-product.php' );
}
Another solution most people find in function.php (which I already use)
function mytheme_add_woocommerce_support() {
add_theme_support( 'woocommerce' );
}
add_theme_support('woocommerce');
I haven't seen anyone asking about this in my hours of research and would love some help.
This is very vague and basically just tells you that you can't edit the archive-product (without any solution of how to do so)
https://docs.woocommerce.com/document/template-structure/
Within WooCommerce I have been making some edits to templates. So far this has been straight forward.
Now I am trying to add some columns into the 'Order Details' table under 'my-account > view-order'.
I am in the template view-order.php which is a template under 'myaccount' in WooCommerce.
Instead of seeing some code in a template to edit, I am seeing the following code:
<?php do_action( 'woocommerce_view_order', $order_id ); ?>
Where is the code from this action called and can I edit it?
Thanks for all time and help.
You need to look at WooCommerce plugin includes/wc-template-hooks.php core file (line 259):
add_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );
As you can see, the function woocommerce_order_details_table() is hooked in. So now let's find this function that is located in includes/wc-template-functions.php core file (starting line 2584).
As you will see this hooked function call the template file order/order-details.php.
So now you can make some changes:
1). Overriding the template file order/order-details.php via your active child theme or theme as explained in this documentation.
Note: The template file order/order-details.php is also used in Order received (thankyou), so take care to target your changes using the following condition:
// For view order
if ( is_wc_endpoint_url( 'view-order' ) ) {
// Here your changes
}
// For other cases
else {
// Here keep the original code
}
2). Or/and you could also remove this hooked function to replace it by your own custom function, with something like:
remove_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );
add_action( 'woocommerce_view_order', 'custom_order_details_table', 10 );
function custom_order_details_table( $order_id ) {
if ( ! $order_id ) {
return;
}
// Here below add your own custom code
}
You can also call your own custom template in that custom function, that will be used exclusively in order view endpoint...
Related: WooCommerce action hooks and overriding templates
WooCommerce Documentations:
Template structure & Overriding templates via a theme
WooCommerce Conditional Tags
I am helping a friend with their Wordpress site and all of their blog posts are showing in reverse order (oldest first). I haven't found any plugins responsible and haven't identified any code that was added. I also tried adding the code
//function to modify default WordPress query
function wpb_custom_query( $query ) {
// Make sure we only modify the main query on the homepage
if( $query->is_main_query() && ! is_admin() && $query->is_home() ) {
// Set parameters to modify the query
$query->set( 'orderby', 'date' );
$query->set( 'order', 'DESC' );
$query->set( 'suppress_filters', 'true' );
}
}
// Hook our custom query function to the pre_get_posts
add_action( 'pre_get_posts', 'wpb_custom_query' );```
They are using the theme RT-Theme 18
Does anyone have any idea why this might be happening?
As mentioned by #fraggley, start off by disabling all plugins and setting the theme to TwentyTwenty (the default theme). The RT-Theme 18 also exhibits similar behaviour in their demo with no obvious setting to change this behaviour. If you aren't already, ensure you're making customisations in a child-theme. Without creating a new function, try using a standard loop to start off to see whether the order is still incorrect.
<?php
get_header();
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_content();
endwhile;
else :
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
get_footer();
?>
This would typically be placed in your home.php or index.php at the root of your child theme. WordPress provides good documentation on this in their codex. You can determine this by checking which file the original code occurs in the parent theme. So if the loop occurs in the parent theme home.php, create a file called home.php in the same relative location on your child theme. More documentation on this here.
How would you enqueue a script in a theme that you only want to show on the blog and single posts?
I checked other questions here but didn't get convincing answer.
I got the following code from Wordpress site from a question as :
function enqueue_files() {
if ( is_page( 'your-page' ) ) {
// enqueue specific page script files here
} else {
// enqueue common scripts here
}
}
add_action( 'wp_enqueue_scripts', 'enqueue_files' );
So after taking a look at is_page() function I am confused that as I need to only show them at single posts & blog pages and while the following function would work only for static pages and since I want it to be dynamic for all of single posts pages and blog pages so how would I be able exactly to do that then with which function?
Use is_singular. It combines is_page() with is_single().
Linky.
It'll also activate on attachment pages though. If that's a problem for you, just use is_page() || is_single().
You don't need to pass the page/post slug (and it'll actually break what you are trying to accomplish. So you just do:
if ( is_page() || is_single() ) {
// if ( is_singular() ) { // or this if you prefer. :)
// enqueue specific page script files here
}
If you want to detect the blogroll, use is_home, I thought you were only targeting single posts.
Link.
Enqueue specific scripts only for the blog homepage and single posts of post type post:
function enqueue_files() {
if ( is_singular('post') || is_home() ) {
// enqueue specific scripts for blog homepage and single posts of post type post
} else {
// enqueue common scripts here
}
}
add_action( 'wp_enqueue_scripts', 'enqueue_files' );
Explanation
is_singular('post') checks if a singular post of specified post type post is being displayed (thanks #Umair Shah Yousafzai for this hint)
is_home() determines if the query is for the blog homepage
I'm using woocommerce, I changed single-product.php and placed an "if" statement inside the loop to load a custom page for a specific product.
<?php while ( have_posts() ) : the_post();
if (is_product_category( 'Benefit')) {
woocommerce_get_template_part( 'content', 'single-product-benefit' );
}else{
woocommerce_get_template_part( 'content', 'single-product' );
}
endwhile; // end of the loop. ?>
My problem is the content-single-product-benefit.php called by the first part of the "if" is ALWAYS loaded (for all products).
I suspect a very stupid php syntax error but I spent an hour on this and can't see it. Both php pages called work fine on their own. Somehow I can't get that "if" right. What am I doing wrong??
Thx for your help ^^
is_product_category() function only works if archive page is being displayed, same as the Wordpress is_category() function. Since you use this function inside the single-product.php file, and that is template for a singular page, above functions will not work. Try with:
has_term( 'Benefit', 'product_cat', $post );