Woocommerce change product style and display it on a page - wordpress

Sorry in advance for my approximative english. I would like to change product page style on woocommerce for a specific product category (don't display pictures and some other important layout changes). Already made it and it works, the problem is that I would like to display these products on a single page. I tried using woocommerce integrated shortcode [product_page id=$id], the problem is that the custom style and layout I created on content-single-product.php (in woocommerce folder) is not applied using this shortcode. I tried to copy my script on class-ws-shortcodes.php (woocommerce folder) but it didn't worked. What should I do to display the products on a specific page, with the real style of these products page (the custom one I created), and not the woocommerce shortcode one?
Thanks in advance for your answers

There are two ways to achieve this, it just depends on whether you want to edit single-product.php or content-single-product.php. Both will get you to the same end result.
To do the former, you can use default WordPress functionality and filter the template under given conditions via template_include
add_filter( 'template_include', 'so_29984159_custom_category_template' );
function so_29984159_custom_category_template( $template ){
if ( is_single() && get_post_type() == 'product' && has_term( 'custom_category', 'product_cat' ) ) {
$template = locate_template( 'single-product-custom.php' );
}
return $template;
}
Or if you'd rather create a custom content-product.php template part, you can use WooCommerce's wc_get_template_part which works in pretty much the same way.
Technically I think you can use the same conditional logic, but I tweaked it here to point out the variables WooCommerce makes available at the filter.
add_filter( 'wc_get_template_part', 'so_29984159_custom_content_template_part', 10, 3 );
function so_29984159_custom_content_template_part( $template, $slug, $name ){
if ( $slug == 'content' && $name == 'product' && has_term( 'custom_category', 'product_cat' ) ) {
$template = locate_template( 'content-product-custom.php' );
}
return $template;
}
In either case the single-product-custom.php or content-product-custom.php would be in your theme's root folder. To put them somewhere else, just change the path in the locate_template() argument.

You can not do coding in wordpress's file i.e. page.php to modify woocommerce pages. Its wrong way. You simply override WooCommerce pages into your theme folder and then modify any pages which you want to do. All templates/pages are located in a woocommerce/templates folder.
Here you can find documentation.
http://docs.woothemes.com/document/template-structure/

edit woocommerce/templates/content-single-product.php for single product view

Related

Custom post template in a plugin erase theme's one

i work with sportpress on Wordpress. I have a custom plugin that add a lot of function to it.
I created a template for the custom post-type of sportpress. They are in my plugin but i don't find how to make them prioritary on theme. The theme isn't a custom'one, so i don't want to delete or modify anything in it.
I have tried several things but theme's file is everytime superior.
Things tried :
naming the file 'single-....php',
filter : add_filter( 'template_include', 'toornament_template' ),
shortcode in theme file (works but not what i want...),
Thanks a lot...
EDIT :
here is what i tried exaclty, it works with another type of post that has no theme template, but not for the one that has single-post template in the theme...
add_filter( 'template_include', 'player_template', 1 );
function player_template( $template ) {
if ( is_singular( 'sp_player' ) && file_exists( plugin_dir_path(__FILE__) . 'templates/player-tpl.php' ) ){
$template = plugin_dir_path(__FILE__) . 'templates/player-tpl.php';
}
return $template;
};

Woocommerce: how to jump directly to product page when category only holds one item

I have a top menu which permits the display of product categories.
In this case, the name of the application I am selling.
When this menu item is clicked, it shows the contents of the category - as it should do.
However, as this category only contains one item, I want to jump straight to the product page, instead of displaying a category page with one item.
Here is a link to the page in question : boutique.zimrahapp.com/categorie-produit/app/
I have not been able to find either a hook or a template where I can adjust the output or do a redirect.
Has this kind of thing already been done ?
The above code didn't work for me. I have a solution that works, but it redirects all single archive results. In my case I wanted to also redirect single tags.
/* Redirect if there is only one product in the category or tag, or anywhere... */
function redirect_to_single_post(){
global $wp_query;
if( is_archive() && $wp_query->post_count == 1 ){
the_post();
$post_url = get_permalink();
wp_safe_redirect($post_url , 302 );
exit;
}
}
add_action('template_redirect', 'redirect_to_single_post');
I had asked this same question here: Woocommerce: How to automatically redirect to the single product if there is only one product on a category page?
WooCommerce redirects a search query with only one result to that result. You can see how they are doing it here.
Modifying their code you get something like this:
function so_35012094_template_redirect() {
global $wp_query;
// Redirect to the product page if we have a single product
if ( is_product_category() && 1 === $wp_query->found_posts ) {
$product = wc_get_product( $wp_query->post );
if ( $product && $product->is_visible() ) {
wp_safe_redirect( get_permalink( $product->id ), 302 );
exit;
}
}
}
add_action( 'template_redirect', 'so_35012094_template_redirect' );
Untested, so watch out for copy/paste fails. Always use WP_DEBUG so you can figure out what went wrong.

Hook taxonomy template to category template

I've created a plugin which registers a custom post type and a custom taxonomy for me.
Now, whenever I visit: www.mysite.com/events_categories/category I should get a list of all the posts under that category. I want to use my own template and not Wordpress' default category template. Also, I want this template to be used for ALL categories, not just one category.
I used this code:
function taxonomy_template() {
global $post;
if( is_tax( 'event_categories' ) ) {
$tax_tpl = dirname( __FILE__ ) . '\taxonomy-event_categories.php';
}
return $tax_tpl;
}
add_filter( 'template_include', 'taxonomy_template' );
And while it works for the taxonomy, it makes everything else on the site go blank. This is because the $tax_tpl is empty if the page I'm on isn't a taxonomy.
I've tried using template_redirect, but no luck either.
So I want to know how to hook my template (taxonomy-event_categories.php) to the Wordpress' category template.
Hope you guys have a solution, because I've looked everywhere and it's possible to find the solution, yet I see many plugins doing this effortlessly.
Okay, so I solved it using this code:
add_action('template_redirect', 'taxonomy_template');
function taxonomy_template( ){
$tax_tpl = dirname( __FILE__ ) . '\taxonomy-event_categories.php';
if( is_tax('event_categories') ) {
include $tax_tpl;
die();
}
}
I've no idea why this works because I think I already tried this specific code, but it didn't work. Let's just hope it will keep working.

WordPress 4.0 - Display author's content on custom post type

Here my problem.
I have several users that are allowed to publish content.
I have create a custom post type to be used has a personal page.
I create a new custom post for each of the user.
They can publish media, events, posts... on this custom post, using tools provided by the theme Flawless.
The Flawless tools publish by default all the content, so if you want to add a gallery, it will show all gallery by all users. I want to limit the gallery display to only the current author of the custom post. And the same for all type of content a user may want to add to his page.
My understanding was that pre_get_posts was perfect in this kind of situation.
The goal was to publish on their custom post only their content, so I used the action pre_get_posts with this function:
function only_current_author( $query ) {
if ( !is_admin() && $query->query_vars['post_type'] != 'nav_menu_item' ) {
$post_id = get_queried_object_id();
$author_id = get_post_field( 'post_author', $post_id );
$query->query_vars['author'] = "$author_id";
}
}
add_action( 'pre_get_posts', 'only_current_author' );
This was working fine on my localhost with WordPress 3.9
Now I have updated to WordPress 4.0, and I got an error 404.
I don't understand exactly what cause the issue, and what is different between the two WordPress version, but I think this is what caused the error 404 is that I'm not able to get the author id of the current custom post.
So, I wonder, do you know alternative to define the author id inside the pre_get_posts action ?
Or should I use another method to filter what will be display?
I try several alternative, like adding an extra Query or adding the $query->query_vars in the template in my custom template, but none worked.
I try to get the author id using the name of the custom post found in the $query, nothing seems to work.
Thanks for your help.
So, after a good night of sleep, I return to my problems and found a solution.
Thanks to give me your feedback if you think this solution is appropriate.
function only_current_author( $query ) {
if ( !is_admin() && $query->query_vars['post_type'] != 'nav_menu_item' ) {
global $wp_query;
$post_id = $wp_query->post->ID;
$post_type = $wp_query->post->post_type;
if( $post_id != 0 && $post_type == 'cpt_mdj' ) {
$post_author_id = get_post_field( 'post_author', $post_id );
$query->query_vars['author'] = $post_author_id;
}
}
}
add_action( 'pre_get_posts', 'only_current_author' );
So, the issue was that $post_id = get_queried_object_id(); returned null, from that it was impossible to pre filter the query with the author id.
Using $wp_query, I was able to get the post id, and then the author id.
Side question, what is the difference between $query and $wp_query, they are identical when I var_dump, but give different result.
Thanks!

Disable Shop page on Woocommerce to protect categories

Im trying to disable "shop" page in Woocommerce. Basically im creating a shop theme to sell prints and image downloads for a photographer.
Because i need to create private galleries i created a custom post type where i use the woocommerce category shortcode to show products and then i password protect the post type.
This is a workaround for password protecting the woocommerce categories (if someone knows a better one please explain).
The problem is that is someone goes to /shop they will all products, including the "protected ones". So i need to disable the shop page and i need to do it programmatically on my theme functions. Any thoughts?
To disable the shop page, copy over the archive-product.php file from the /wp-content/plugins/woocommerce/templates/archive-product.php and put in /wp-content/themes/{Your Theme}/woocommerce/archive-product.php
Open up the file and overwrite everything in file with the following code below:
<?php
global $wp_query;
$wp_query->set_404();
status_header(404);
get_template_part('404');
Save the file, and now your Shop page is gone and replaced with a 404 Page!
Add this to functions:
function woocommerce_disable_shop_page() {
global $post;
if (is_shop()):
global $wp_query;
$wp_query->set_404();
status_header(404);
endif;
}
add_action( 'wp', 'woocommerce_disable_shop_page' );
Docs: WooCommerce Conditional Functions Documentation
WooCommerce has a filter for the array that it uses to create the Product post type: woocommerce_register_post_type_product.
Rather changing the archive template to force it to redirect, you can completely remove the post type’s archive, but changing the has_archive attribute on the post type on creation.
add_filter('woocommerce_register_post_type_product', function($post_type) {
$post_type['has_archive'] = false;
return $post_type;
});
You should then remove the shop page in the CMS by going to WooCommerce » Settings » Product » Display, and clicking the “x” on the “Shop Page” option.
You might need to flush the permalink cache, which you can do just by clicking the “Update” button in Settings » Permalinks.
*Edit -
Apparently the page setting I suggested below no longer works. If WooCommerce doesn't have a plugin setting to change it, I personally would use a wordpress redirect plugin like Redirection. This way you can automatically redirect them from the undesired shop page to whatever page displays your products. It avoids a 404 issue and keeps everything in tact. It also avoids editing template files which adds complications to non-developers.
Old Answer:
Have you tried Woo settings?
Admin area, left main menu, Woocommerce > Settings
Click the pages tab.
Under Pages setup is "Shop Base Page", on the dropdown, there's a small "x" to right right. Click that to get rid of the page.
If there are links elsewhere that need to be fixed let me know and I'll find the hooks/filters to remedy it.
template_redirect is the last hook before page render so in my use case I ask if the page being viewed is the "shop" page and if it is I redirect to (in my case) a pricing page.
function my__template_redirect(){
if(is_shop()){
wp_redirect(site_url() . '/pricing/', '302');
}
}
add_action('template_redirect', 'my__template_redirect');
The last suggestion didn't work for me with WP 4.6.1 and WooCommerce 2.6.4. Hiding products in the Publish tab works for me.
http://paperhedge.com/hide-products-from-displaying-in-shop-page-woocommerce/
To disable the default shop page and leave the /shop/ slug free for custom pages use this:
function remove_woocommerce_default_shop( $args, $post_type ) {
if (class_exists('WooCommerce')) {
if ( $post_type == "product" ) {
$args['has_archive'] = true;
}
return $args;
}
}
add_filter('register_post_type_args', 'remove_woocommerce_default_shop', 20, 2);
You need to hook a couple (or maybe more) things:
/* hide category from shop pages */
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! is_admin() ) {
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( YOUR-CATEGORY-SLUG, YOUR-CATEGORY-SLUG-2 ), // Don't display products in the knives category on the shop page
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Change, obviusly YOUR-CATEGORY-SLUG, YOUR-CATEGORY-SLUG-2 for your cat or cats to hide from shop pages.
Then, you need to hide them from menues too, right?:
/* hide category from menues */
add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
function get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
// if category and on the shop page (change it with is_woocommerce() if want to hide from all woo pages)
if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() ) {
foreach ( $terms as $key => $term ) {
if ( ! in_array( $term->slug, array( YOUR-CATEGORY-SLUG, YOUR-CATEGORY-SLUG-2 ) ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
But i don´t think this solve 100% the thing, since then, what about search results?
Try this
Create new page named "Shop"
Go to "woocommerce" > "Settings" > "Product" > "Display tab"
Select shop page named "Shop" then click save changes
Back to "Pages" then delete "Shop" page (keep the page on trash,
don't delete permanently)
This method works fine for me

Resources