Skip to content

Instantly share code, notes, and snippets.

  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save twoelevenjay/a2195b052c4feb046d7f71fcae5c4d1b to your computer and use it in GitHub Desktop.
Move WooCommerce subcategory list items into their own <ul> separate from the product <ul>.
<?php
/**
* Move WooCommerce subcategory list items into
* their own <ul> separate from the product <ul>.
*/
add_action( 'init', 'move_subcat_lis' );
function move_subcat_lis() {
// Remove the subcat <li>s from the old location.
remove_filter( 'woocommerce_product_loop_start', 'woocommerce_maybe_show_product_subcategories' );
add_action( 'woocommerce_before_shop_loop', 'msc_product_loop_start', 40 );
add_action( 'woocommerce_before_shop_loop', 'msc_maybe_show_product_subcategories', 50 );
add_action( 'woocommerce_before_shop_loop', 'msc_product_loop_end', 60 );
}
/**
* Conditonally start the product loop with a <ul> contaner if subcats exist.
*/
function msc_product_loop_start() {
$subcategories = woocommerce_maybe_show_product_subcategories();
if ( $subcategories ) {
woocommerce_product_loop_start();
}
}
/**
* Print the subcat <li>s in our new location.
*/
function msc_maybe_show_product_subcategories() {
echo woocommerce_maybe_show_product_subcategories();
}
/**
* Conditonally end the product loop with a </ul> if subcats exist.
*/
function msc_product_loop_end() {
$subcategories = woocommerce_maybe_show_product_subcategories();
if ( $subcategories ) {
woocommerce_product_loop_end();
}
}
@fkoomek
Copy link

fkoomek commented Jul 21, 2021

Do you have a link to your page? I think it could be done with pure CSS, it would be probably the easiest solution.

@fkoomek
Copy link

fkoomek commented Jul 21, 2021

Otherwise, this should work. Replace existing code with this. You will probably also need some CSS. If you want to change for example ordering of the categories check out this page https://docs.woocommerce.com/document/woocommerce-shortcodes/#section-14

/*Separate product categories from products and display 3 categories per row*/

add_action( 'init', 'subcat_custom_number' );
function subcat_custom_number() {
	// Remove the subcat <li>s from the old location.
	remove_filter( 'woocommerce_product_loop_start', 'woocommerce_maybe_show_product_subcategories' );
	add_action( 'woocommerce_before_shop_loop', 'msc_product_loop_category_custom', 10 );
}

function msc_product_loop_category_custom() {
	
	    $term_id  = get_queried_object_id();
        $taxonomy = 'product_cat';

        // Get subcategories of the current category
        $terms    = get_terms([
            'taxonomy'    => $taxonomy,
            'hide_empty'  => true,
            'parent'      => $term_id
        ]);


        // Loop through product subcategories WP_Term Objects
        foreach ( $terms as $term ) {
            $term_link = get_term_link( $term, $taxonomy );

            $output .= $term->term_id . ',';
        }
       $output2 = substr_replace($output, "", -1); //output ids of subcategories
	
	$subcategories = woocommerce_maybe_show_product_subcategories();
	if ( $subcategories ) {

		echo do_shortcode('[product_categories ids="'. $output2 . '" columns="3"]'); //show subcategories
	}
}

@johnsimeon
Copy link

I will test it!
Thanks a lot!!!

@fkoomek
Copy link

fkoomek commented Jul 21, 2021

I updated the code. Now it works automatically, so you don't have to specify anything. Still, you'll probably need some CSS for a little bit of styling. Let me know if it works.

@ndwhyy
Copy link

ndwhyy commented Feb 4, 2022

Is it possible to add a divider or a shortcode between these two

    elements?

@fkoomek
Copy link

fkoomek commented Feb 4, 2022

function msc_product_loop_end() { $subcategories = woocommerce_maybe_show_product_subcategories(); if ( $subcategories ) { woocommerce_product_loop_end(); echo '<hr id="sub_divider">'; } }

You can try to add the


element to the last function. As I added the id attribute to the element, you can then style it to your needs.

@ndwhyy
Copy link

ndwhyy commented Feb 5, 2022

Absolutely wonderful, thanks a lot mate! A quick Google search also taught me I can use shortcodes with do_shortcode. I also managed to show a title before the subcategories as well by echoing it after the "woocommerce_product_loop_start".

@fkoomek
Copy link

fkoomek commented Feb 5, 2022

No problem. I just noticed missing quotation mark in my code (in id). Sorry, I fixed it 🙂

@ndwhyy
Copy link

ndwhyy commented Feb 8, 2022

Thanks a bunch! I ended up using do_shortcode so I didn't even realize. Now I have nice titles for both loops! But when there are no subcategories, the product loop doesn't have a title. Can I somehow add this in functions.php so I don't have to manually add it in each category?

EDIT: the following works, but it also adds a second title when there are subcategories.. I don't know how to modify it to my needs. :p

add_action( 'woocommerce_before_shop_loop', 'amc_add_content_before_loop' );
function amc_add_content_before_loop() {

	if ( is_product_category() ) {
		echo do_shortcode('[title text="PRODUCTS" tag_name="h2"]');
	}

}

@fkoomek
Copy link

fkoomek commented Feb 10, 2022

Hi. Do you have a link to your site please?

@ndwhyy
Copy link

ndwhyy commented Feb 10, 2022

Example with a category that has subcategories: [redacted]
No subcategories, no title :( : [redacted]

@fkoomek
Copy link

fkoomek commented Feb 10, 2022

And what is the full code you are currently using?

@ndwhyy
Copy link

ndwhyy commented Feb 10, 2022

Here's the current code:

/**
* Move WooCommerce subcategory list items into
* their own <ul> separate from the product <ul>.
*/

add_action( 'init', 'move_subcat_lis' );

function move_subcat_lis() {
	// Remove the subcat <li>s from the old location.
	remove_filter( 'woocommerce_product_loop_start', 'woocommerce_maybe_show_product_subcategories' );
	add_action( 'woocommerce_before_shop_loop', 'msc_product_loop_start', 40 );
	add_action( 'woocommerce_before_shop_loop', 'msc_maybe_show_product_subcategories', 50 );
	add_action( 'woocommerce_before_shop_loop', 'msc_product_loop_end', 60 );
}

/**
 * Conditonally start the product loop with a <ul> contaner if subcats exist.
 */
function msc_product_loop_start() {
	$subcategories = woocommerce_maybe_show_product_subcategories();
	if ( $subcategories ) {
		woocommerce_product_loop_start(); echo do_shortcode('[title text="ALAKATEGORIAT" tag_name="h2"]');
	}
}

/**
 * Print the subcat <li>s in our new location.
 */
function msc_maybe_show_product_subcategories() {
	echo woocommerce_maybe_show_product_subcategories();
}

/**
 * Conditonally end the product loop with a </ul> if subcats exist.
 */
function msc_product_loop_end() {
	$subcategories = woocommerce_maybe_show_product_subcategories();
	if ( $subcategories ) {
		woocommerce_product_loop_end(); echo do_shortcode('[title text="TUOTTEET" tag_name="h2"]');
	} 
}

@fkoomek
Copy link

fkoomek commented Feb 10, 2022

Try to replace the end of the code with this:

/**
 * Conditonally end the product loop with a </ul> if subcats exist.
 */
function msc_product_loop_end() {
	$subcategories = woocommerce_maybe_show_product_subcategories();
	
	if ( $subcategories ) {
		woocommerce_product_loop_end();
		}
		
//if category has products, show title PRODUCTS title		
if (have_posts()){	
echo do_shortcode('[title text="TUOTTEET" tag_name="h2"]');
}
}

Also, I added a condition that the word Products will show only when the category has some products. If you want to delete this condition, put echo do_shortcode('[title text="TUOTTEET" tag_name="h2"]'); outside have_posts condition...

Is it what you were trying to achieve?

@ndwhyy
Copy link

ndwhyy commented Feb 10, 2022

Well I'll be damned, that sure did the trick! This was exactly what I was trying to achieve, thank you so much! :)

@fkoomek
Copy link

fkoomek commented Feb 10, 2022

Glad to help sir :)

@twoelevenjay
Copy link
Author

@anddilolz and @fkoomek, you two are awesome!

@ndwhyy
Copy link

ndwhyy commented Feb 11, 2022

@twoelevenjay @fkoomek mad props to you both!

@EchoA331
Copy link

@twoelevenjay first o all, thank you for sharing with us, your code above. I use is and it is very helpful !

Is it also possible, combining the code above to align all categories and products to center?
ie the shop page has 4 columns and there is only 2 subcategories, can be center aligned ?
or a subcategory has only 3 products, can also appeared centered ?

kind regards

e.a

@fkoomek
Copy link

fkoomek commented Jul 10, 2022

@EchoA331 It Is possible, you have to use CSS for that.

@EchoA331
Copy link

@twoelevenjay

thanks for your reply, unfortunately I do not know how !
I found many similar examples on the web, but none was working. Thanks anyway ! Have a nice day !

@fkoomek
Copy link

fkoomek commented Jul 11, 2022

Do you have a link to your site?

@fkoomek
Copy link

fkoomek commented Jul 11, 2022

@EchoA331 Try to add this to your custom CSS code:
#main .products.row { justify-content: center; }

@EchoA331
Copy link

EchoA331 commented Jul 16, 2022 via email

@EchoA331
Copy link

EchoA331 commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment