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 );