WooCommerce - How to create multiple single product template based on category?
There is probably more than one way to do this, but they all kind of turn around the idea of filtering the template before it is included.
You could totally skip WooCommerce's simple-product.php
template (without needing to override that template) and go directly to simple-product-mock.php
and create everything there. You'd do that by filtering template_include
.
add_filter( 'template_include', 'so_25789472_template_include' );
function so_25789472_template_include( $template ) {
if ( is_singular('product') && (has_term( 'mock', 'product_cat')) ) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-mock.php';
}
return $template;
}
You could edit single-product-mock.php
to call content-single-product-mock.php
and hard-code that file. Nothing requires you to keep using Woo's hooks and functions. The point of them is just to make it easy for you to customize.
Or to be really tricky, you could duplicate templates such as single-product/title.php
into a single-product-mock
folder... ex: single-product-mock/title.php
and then any time we're on a single product template in the mock category, we'll intercept calls to the single-product/something.php
template and redirect them to single-product-mock/something.php
if it exists and keep pointing to the single-product/something.php
if it does not. We'll do this via the woocommerce_locate_template
filter.
add_filter( 'woocommerce_locate_template', 'so_25789472_locate_template', 10, 3 );
function so_25789472_locate_template( $template, $template_name, $template_path ){
// on single posts with mock category and only for single-product/something.php templates
if( is_product() && has_term( 'mock', 'product_cat' ) && strpos( $template_name, 'single-product/') !== false ){
// replace single-product with single-product-mock in template name
$mock_template_name = str_replace("single-product/", "single-product-mock/", $template_name );
// look for templates in the single-product-mock/ folder
$mock_template = locate_template(
array(
trailingslashit( $template_path ) . $mock_template_name,
$mock_template_name
)
);
// if found, replace template with that in the single-product-mock/ folder
if ( $mock_template ) {
$template = $mock_template;
}
}
return $template;
}
Update to filter wc_get_template
instead.
/**
* Change wc template part for product with a specific category
*
* @param string $templates
* @param string $slug
* @param string $name
* @return string
*/
function so_25789472_get_template_part( $template, $slug, $name ) {
if ( $slug == 'content' && $name = 'single-product' && has_term( 'test', 'product_cat' ) ) {
$template = locate_template( array( WC()->template_path() . 'content-single-product-test.php' ) );
}
return $template;
}
add_filter( 'wc_get_template_part', 'so_25789472_get_template_part', 10, 3 );
Woocommerce Multiple single product templates using single-product.php to redirect
Use a single-product-custom.php
template for any product in the "custom" category:
add_filter( 'template_include', 'so_43621049_template_include' );
function so_43621049_template_include( $template ) {
if ( is_singular('product') && (has_term( 'custom', 'product_cat')) ) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-custom.php';
}
return $template;
}
NB: If you use the same action hooks in your single-product-custom.php
template you will get the same look as the default single-product.php
. You could 'rename' all the hooks and then could add existing functions (such as those for add to cart buttons, etc) to the new hooks in order to achieve a totally custom look.
Using a custom single product template for a specific product category in Woocommerce
The code that you are using works just perfectly. Your code is a bit incomplete too:
add_filter( 'template_include', 'custom_single_product_template_include', 50, 1 );
function custom_single_product_template_include( $template ) {
if ( is_singular('product') && (has_term( 'custom', 'product_cat')) ) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-mock.php';
}
return $template;
}
So the problem could be related to:
- The location of that custom template, that should be in a 'woocommerce' folder inside your active child theme (or inside your active theme).
- Woocommerce support need to be enable for your theme.
Solutions:
- be sure that inside your active child theme (or active theme) there is a "woocommerce" folder and add inside it your custom template
single-product-mock.php
(but not inside a "templates" sub-folder) - To check Woocommerce support is enabled:
- Copy the default
single-product.php
template inside the "woocommerce" folder located in your active child theme (or active theme) - Go in backend Woocommerce > Status … and you will normally see in "templates" section (at the end of this page):
With an active child-theme:
With an active theme: - If is not enable, you should search and look to the related Woocommerce documentation.
- Copy the default
One of those, should solve your issue.
Woocommerce single product - template by categories
It's looking for a file titled content-single-product-customcateg.php
That file doesn't exist so it's falling back to the default.
if ( has_term( 'customcateg', 'product_cat' ) ) {
woocommerce_get_template_part( 'content', 'single-product-customcateg' );
} else {
woocommerce_get_template_part( 'content', 'single-product' );
}
Can you add the contents of your content-single-product-customcateg.php by the way?
Need a seperate layout for single product of a category
Using just your working filter, you can directly change your new template file single-product-56772.php
without calling any other file.
If you want to call the wc_get_template_part( 'content', 'single-product-56772' );
from single-product-56772.php
then you have to create that file in your woocommerce folder and name it content-single-product-56772.php
.
Your files structure should look like this:
woocommerce
|- single-product-56772.php
|- content-single-product-56772.php
Multiple Woocommerce Product Templates
The best it to use elseif
:
if ( in_array( 'legal', $categories ) ) {
woocommerce_get_template_part( 'content', 'single-product-legal');
}elseif (in_array('show', $categories)){
woocommerce_get_template_part('content', 'single-product-show');
}else {
woocommerce_get_template_part( 'content', 'single-product-merc');
}
Rather than adding a seperate elseif for merchandise you can just do it in the else like above because by default if it is not legal or show it must be merchandise, but you may just add another elseif as well with the same basic structure.
Related Topics
Check If String Contains Word in Array
How to Use File_Get_Contents() to Compare Two Files
How to Match Accented Characters with PHP Preg
Pdo Exception Questions - How to Catch Them
Retrieving the Last Inserted Ids for Multiple Rows
Assets Not Referencing to Public Folder (Laravel)
How to Tell If a Timezone Observes Daylight Saving at Any Time of the Year
How to Call a Python Script from PHP
Load Block Outside Magento, and Apply Current Template
How to Make Codeigniter Accept "Query String" Urls
Alternative to Money_Format() Function
How to Get MySQL 8 to Run with Laravel
Browser Displays � Instead of '
Symfony\Component\Httpkernel\Exception\Notfoundhttpexception Laravel