Woocommerce choose grid or list view for each category - wordpress

I want the possibility to choose between grid and list view for each Woocommerce category. I have found this plugin: https://nl.wordpress.org/plugins/woocommerce-grid-list-toggle/
However, the plugin is meant for the shopper to choose whether to display items in grid view or list view. What I truly want is the ability to assign a view for each category in the back-end.
Example:
Category A is displayed as grid
Category B is displayed as list
Breaking my head over this.

Similar to this question you need to filter template_include. You need to call your custom archive template archive-list-view.php and save it in your theme's woocommerce folder. Obviously, you can name it anything you like, you will just have to adjust the code below to match.
Folder structure:
/theme-folder/functions.php
/theme-folder/woocommerce/archive-list-view.php
On the template_include filter we will check if we are on the term archive for the nussmylch product category. If so, we'll look for and supply the new template. Otherwise, the standard template is used.
EDIT: incorrect WooCommerce function is_product_taxonomy() was used. is_product_category() is needed to check for a specific category.
add_filter( 'template_include', 'so_33615903_custom_category_template', 20 );
function so_33615903_custom_category_template( $template ) {
// check you are on the taxonomy archive for specific category
if ( is_product_category( 'nussmylch' ) ) {
$new_template = locate_template( array( 'woocommerce/archive-list-view.php' ) );
if ( '' != $new_template ) {
$template = $new_template ;
}
}
return $template;
}
Working Example

Related

How to hide some Custom Fields from Woocommerce Admin order page

When logged in as an admin and looking at an Order in Woocommerce, there's a section with all the Custom Fields. Out of the whole list I only want it to display two of them. How do I hide the rest from this view? I don't want to delete them, but just hide from this view.
For every custom field you want hidden, add the following 4 lines of code to functions.php or using Snippets plugin:
add_filter('is_protected_meta', 'my_is_protected_meta_filter1', 10, 2);
function my_is_protected_meta_filter1($protected, $meta_key) {
return $meta_key == 'automatewoo_cart_id' ? true : $protected;
}
If you want to hide more than one, add the lines above again and change 'my_is_protected_meta_filter1' to 'my_is_protected_meta_filter2', etc
if you’re using ACF pro, there is a hook you can use to remove the field on the back end, but it’s not something that’s documented..
You could use a hook to remove specific field if is_admin() returns true.
You may need to play with this a bit to get it to work, the ACF hook is
acf/get_fields
So, for example:
add_filter('acf/get_fields', 'your_function_name', 20, 2);
function your_function_name($fields, $parent) {
// remove the fields you don't want
return $fields;
}
$fields can be a nested array of fields => sub_fields.
You need to set the priority > 10 to run after the internal ACF filter
For orders in Woocommerce the post type is 'shop_order', so your code should be:
add_action( 'add_meta_boxes', 'remove_shop_order_meta_boxe', 90 );
function remove_shop_order_meta_boxe() {
remove_meta_box( 'postcustom', 'shop_order', 'normal' );
}

How do I add product attributes to the product page in WooCommerce?

I'm using WooCommerce and Elementor Pro. Is there any way to add specific product attributes (e.g. gross and net weight) below the Add to cart button?
It seems like an obvious thing but I haven't found options or snippets for it.
First you add attributes to product. Then you use this snippet in functions.php:
// maybe remove tab with attributes
add_filter( 'woocommerce_product_tabs', 'remove_info', 100, 1 );
function remove_info( $tabs ) {
unset($tabs['additional_information']);
return $tabs;
}
// show attributes
add_action( 'woocommerce_single_product_summary', 'summary_attributes', 35 );
function summary_attributes() {
global $product;
if ( $product->has_attributes() ) {
wc_display_product_attributes( $product );
}
}
Setting Up WooCommerce Attributes
go to Products > Attributes
Add the attribute name
Slug will automatically be created, and we can leave the rest of these options untouched.
Click “Add attribute” button and your attribute will be added.
Configure The Attributes
After creating attribute, now we can add different variation on your product. Click on the Configure Terms option.
Enter the variation
Add some short description
Click on the add new tab
To understand it in a better way you can follow this tutorial

Wordpress - custom template page for a parent category and all child categories

In WP 5.4.2 I want to create a custom archive page for a category and all it's child categories. I am aware of the template file hierarchy:
1. category-slug.php
2. category-ID.php
3. category.php
4. archive.php
5. index.php
but if I understand correctly and if I did all the testing right, the category-slug.php, or the category-id.php scheme applies to a single category regardless of the category hierarchy.
Let's say I have following categories:
colors (id 2)
- red (id 10)
- green (id 11)
- blue (id 12)
I need a single template file for all of them. Simply creating category-colors.php or category-2.php doesn't work. It applies to the single category (colors) only. I want it to apply to all the current child categories, as well as all the child categories I add in the future. Is it possible? If so, please advice how.
There are a couple of ways to do this, but using the category_template filter to let you use a custom category template seems the most common.
The function below will let you dynamically check back through the parent levels of the current category until it finds a template called "category-[parent slug]" for the closest ancestor category or it reaches the top level - whichever is first.
Suppose you have something like:
- products
- hardware
- food
- dairy
- vegetables
On the dairy page, it will first check if you have a slug called category-dairy.php.
If you do, it will return it.
If you don't, it will look for category-food.php.
If that's not found, it will look for category-products.php.
Add this to your functions.php - this is untested by the code is well commented so you can understand how it works:
function get_template_for_category( $template ) {
if ( basename( $template ) === 'category.php' ) { // No custom template for this specific term, let's find it's parent
// get the current term, e.g. red
$term = get_queried_object();
// check for template file for the page category
$slug_template = locate_template( "category-{$term->slug}.php" );
if ( $slug_template ) return $slug_template;
// if the page category doesn't have a template, then start checking back through the parent levels to find a template for a parent slug
$term_to_check = $term;
while ( $term_to_check ->parent ) {
// get the parent of the this level's parent
$term_to_check = get_category( $term_to_check->parent );
if ( ! $term_to_check || is_wp_error( $term_to_check ) )
break; // No valid parent found
// Use locate_template to check if a template exists for this categories slug
$slug_template = locate_template( "category-{$term_to_check->slug}.php" );
// if we find a template then return it. Otherwise the loop will check for this level's parent
if ( $slug_template ) return $slug_template;
}
}
return $template;
}
add_filter( 'category_template', 'get_template_for_category' );
References:
WP Codex category_template Reference
WP Developer locate_template Reference
Make categories use parent template

Show product variations on the product category and shop pages

I'd like to display product variations for some (not all) variable products on the shop and product-category pages based on a custom field I'm planning to add to each variable product. To keep pagination working, I can hook in to the woocommerce_product_query hook in WC_Query::product_query($q) but I can't figure out how to modify the query to give me what I'm after.
The logic I want to apply is:
//Pseudo-code
$loop = $query->get_all_products // i.e. not just for one page
foreach ( $loop as $product) {
if ($product->is_simple) {
display_simple($product)
} else {
$variations = wc_get_products($product->get_children());
foreach ($variations as $product) {
if ($product->custom_show_on_archive_pages) {
display_variation($product)
}
}
}
}
The problem with the above (apart from being pseudo-code) is that it assumes we have an array called $loop but actually we have a query object.
My ideal would be to modify the query so that it generates the results as per the pseudo-code, and then my archive-product.php template can use an if/else to display simple vs variable products.
Something like this in my functions.php:
add_action( 'woocommerce_product_query', 'show_variable_products');
function show_variable_products( $q ) {
$meta_query = $q->get('meta_query');
// Do something
$q->set('meta_query', $meta_query);
}
I'm wondering if I need to actually run multiple queries somehow:
The original query but filtered to parent products
The children of these parent products (i.e. the variations), filtered to those with custom field checked
The original query but filtered to simple products
Merge (2) and (3)
Would this be possible?
Alternatively, is there another solution (that does not involve buying a plugin)?

Populate Custom Category Taxonomy with Data in WP Plugin

I'm writing a wordpress plugin that allows people in the admin to hide/show content specific to US states. I have a custom category taxonomy called States, and it lists all of the states. Admins can check which states they want the post to appear in. Pages and posts will not show up in the loop if the user's state doesn't match up with the posts' selected states.
Now, my question is, how do I populate the plugin with all of the states' data upon install (or remove it upon uninstall)?
This should work. You'll need to add the rest of the states, and make sure that your taxonomy is actually called "States", but other than that it should be fine:
<?php
$foo_states = array(
'Alabama',
'Alaska',
'Arizona',
'Arkansas'
);
function foo_install() {
global $foo_states;
foreach ( (array) $foo_states as $state ) {
wp_insert_term($state, 'States');
}
}
register_activation_hook(__FILE__, 'foo_install')
function foo_uninstall() {
global $foo_states;
foreach ( (array) $foo_states as $state ) {
wp_delete_term(get_term_by('name', $state, 'States')->term_id, 'States');
}
}
register_deactivation_hook(__FILE__, 'foo_uninstall');
?>

Resources