Home › Toolset Professional Support › [Resolved] Assistance Modifying Taxonomy Control
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 9:00 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | 9:00 – 12:00 | - |
- | 13:00 – 18:00 | 13:00 – 18:00 | 13:00 – 18:00 | 14:00 – 18:00 | 13:00 – 18:00 | - |
Supporter timezone: America/Jamaica (GMT-05:00)
Tagged: Views plugin
This topic contains 11 replies, has 2 voices.
Last updated by seanC-11 4 years, 11 months ago.
Assisted by: Shane.
This is the second support post I have created. It showed me a chat message on last submission with assigned support but then it timed out and deleted.
I have a WooCommerce page with multiple taxonomy based control filters. For one of the taxonomies I would prefer to only display 1 term (which will be set by a USER COOKIE.) If there are no matches ideally I would like it to remain with the 0 count showing. But most importantly I don't want to show ALL matching terms from the taxonomy. I just want to show the single term that will be predefined based on other UX areas where users will associate with a specific taxonomy term.
I attempted to implement the suggestion of hooking into get_terms to whitelist/blacklist specific terms but when doing so it affects all other taxonomies on the page. The script references the specific taxonomy in question and it does its job of restricting the terms but affects all the taxonomies.
Code is: function tssupp_restrict_terms( $terms, $taxonomies, $args, $term_query ){
// 2. which taxonomy (slug)
$taxonomy = 'fitment';
// 3. add terms to blacklist *OR* whitelist, not both
$blacklist = array();
$whitelist = array( '2017-toyota-tundra' );
if ($taxonomies[0] === $taxonomy ) {
if ( !empty( $blacklist ) ) {
foreach( $terms as $key => $term ){
if ( in_array( $term->slug, $blacklist ) ) {
unset($terms[$key]);
}
}
} else if ( !empty( $whitelist ) ) {
foreach( $terms as $key => $term ){
if ( !in_array( $term->slug, $whitelist ) ) {
unset($terms[$key]);
}
}
}
}
return $terms;
}
Might be a simple oversight or something that's not doable. I can look to implement other "work arounds" to resolve but was hoping for the most direct approach on this one.
Hi Sean,
Based on what I read here is that you want the taxonomies to be available based on what the user selects on the other filters correct?
There is a way to do this in toolset natively but this will affect all your other options. When a user selects a value in any filter the other filters will auto adjust to match the first selected filter in order to always produce a result.
Please let me know if you want instructions on how to do this.
Thanks,
Shane
Well sort of. The other filters all process as they do normally and everything appears to work fine. There is one taxonomy added as a control filter (and a query filter with URL Param) that has a total of 37,000+ unique terms. One product post type may be associated with as many as 100 of those taxonomy terms. Running the native Toolset process returns ALL terms for ALL products in a specific archive. I want that taxonomy control to retrieve counts for a single term in that taxonomy vs. returning all of them. Additionally - that term will vary from user request to user request.
e.g. a user has select 2017-toyota-tundra term. I want for that term and the matching term count to display within the filters on the left hand side where the user can toggle it on/off.
I believe this is a modification and looking for direction on the best hook / action to target a resolve on this.
As a note - I realize I can set a URL param or short code param for that taxonomy and force those selections on the page load. There are a few issues - primarily I want the user to be able to toggle it on/off to see the other available products, but I don't want Toolset to return all the other available terms as that will likely affect query/processing time. For each user interaction (if they have a fitment term pre-selected) I want only that specific term within the taxonomy considered.
Hi Sean,
Thank you for the detailed explanation.
So that I understand clearly I will be responding with some points.
Running the native Toolset process returns ALL terms for ALL products in a specific archive. I want that taxonomy control to retrieve counts for a single term in that taxonomy vs. returning all of them. Additionally - that term will vary from user request to user request.
You are correct in that all the option for the filters will be returned, however the moment the user selects an option the filter will re-adjust and change the count. So only Posts with that specific term will be returned.
e.g. a user has select 2017-toyota-tundra term. I want for that term and the matching term count to display within the filters on the left hand side where the user can toggle it on/off.
With the Native Toolset option you have this feature available, so the user Toggles on/off their selection and the previous options will become available and when they select "2017-toyota-tundra" the filters will re-adjust to the posts that are currently being displayed.
I realize I can set a URL param or short code param for that taxonomy and force those selections on the page load.
Thats correct however if you are going to filter your posts you will need to use a URL parameter for your pre-existing filters. This is because you won't be able to use the Shortcode parameter for your pre-existing filters.
There are a few issues - primarily I want the user to be able to toggle it on/off to see the other available products, but I don't want Toolset to return all the other available terms as that will likely affect query/processing time.
With the Toggle on/off it will return the full list of terms. However i'm not sure how you would want this to work when the user toggles on/off the term, not sure what else you will want to return when the user toggles the term off.
For each user interaction (if they have a fitment term pre-selected) I want only that specific term within the taxonomy considered.
Perhaps what you can do here is have predefined links that you want the user to go to. These links will have the appropriate URL parameter value for the filter so the user can link directly to the list they and from their they can continue filtering or Toggle off the pre-selection to have access to the full list.
Please let me know what you think of this.
Thanks,
Shane
You have a pretty good understanding of what I am going for, but just going to clarify a few things.
The issue with the taxonomy control via Toolset is the Fitment taxonomy is rather large, and I believe the various term calls iterating for every product for every matching term has a negatively compounding effect on page load speed. I was hoping to find a way to restrict the queries to a single term for both ease of use but also scalability.
So in summary, is there a way to restrict Toolset to only query for a specific term inside a taxonomy control and/or assistance with how to get the get_hooks solution to "white list" specific terms for only a single taxonomy. The script/hook is something I have seen Toolset supporters post but in my case it whitelists terms across all taxonomies.
Also, I don't really want to force the user to pre-select their specific term and really just display the facet. This was determined primarily to ensure the categories show product as some fitment terms will have no results in some categories.
We're currently working to implement an elasticpress solution to help improve the loading of product data. My categories show 8 second + query/load times in many cases. Part of this is caused by the amount of get_terms() queries that occur from both WooCommerce and Toolset.
Hi Sean,
The issue with the taxonomy control via Toolset is the Fitment taxonomy is rather large, and I believe the various term calls iterating for every product for every matching term has a negatively compounding effect on page load speed. I was hoping to find a way to restrict the queries to a single term for both ease of use but also scalability.
Do you have the forum link on hand where the Supporter provided some code for this. Generally we do not support custom coding but if it's a code that would fit your needs I can perhaps modify it for you to help restrict the terms.
The script/hook is something I have seen Toolset supporters post but in my case it whitelists terms across all taxonomies.
When you say whitelist you mean that it is including all the terms even the ones that you want to not be included ?
Please let me know so that I can better assist.
Thanks,
Shane
This supporter posted this code to a couple different replies, but here is one example: https://toolset.com/forums/topic/apply-several-query-filters-on-same-taxonomy/
At this point my concern is the get_terms() call for this specific taxonomy results in very high query times. This solution seems to suggest that this might work to limit the query/results from get_terms for a specific taxonomy.
To try and simplify: I have a Archive view (showing products from a product_cat archive.) I have a few different filters which all work correctly. One taxonomy filter has over 30,000 terms. An archive result may have 1000+ matches when loading the posts from that archive (think a 1000 term tag cloud getting output into the filter section.) I only want to retrieve / output the term & count for ONE term in that particular taxonomy (based on the current query / other selected filters) which would be set via a COOKIE (or similar.)
So let's say I have a taxonomy selected along with the archive that has a total found_count of 100 posts. Let's say 20 posts match the ONE term, then I want it to output that term with the (20) count as a checkbox. The native functionality is that the filter returns ALL term results. Also, the query / compute time required for outputting that is taxing and increasing the page load.
Hi Sean,
Sorry for the delay as the forum has been extremely busy and is causing delays in my ability to respond in a timely fashion.
The problem now with using this hook is that it won't be smart. It will always remove the terms that you don't want to display unless you remove the terms from the blacklist.
For this code you will need to add a conditional statement to check which taxonomy term page is currently being viewed, then unset a different set of taxonomy terms. This is how i'm thinking to make it dynamic.
For e.g if you're on Term A you only want term B to appear on the filter, so you will unset Term C and Term D.
This is how I currently understand the issue.
Right now Christian's code is unsetting based on the terms that are supplied but it needs modifications to check for the current archive .
The function you need to use to check the current archive page is.
https://developer.wordpress.org/reference/functions/is_tax/
So you will need to write this in a conditional to check the current archive's taxonomy and unset your terms accordingly.
Please let me know if this helps.
Thanks,
Shane
I will investigate if that's an option. We are looking to integrate WooCommerce with ElasticSearch and so we may be losing views to handle our product filters anyway. That being said, I did arrive at a solution. Not quite as elegant but seems to be effective without much cost.
For someone else needing assistance - I kept the query filter for the fitment taxonomy but removed the taxonomy-control shortcode in the search pagination to avoid the default behavior of outputting EVERY available term. I created a custom shortcode that 'extends' the WPV_view_archive_loop to access the current (ajax or page load) query_vars. I run a custom WP_Query with the requested variables but add a tax_query parameter for the single taxonomy term.
The shortcode than outputs the checkbox with the count of matching products (based on existing filters) inside the filter area of the view. Selecting the checkbox adds the URL_param and loads the filtered product list as designed.
I imagine there could be a few different issues with this approach but I was working to integrate elasticpress which doesn't support get_terms queries, so went with a traditional WP_Query to benefit from Elasticpress integration. So not quite as refined as I would prefer however I couldn't find an efficient alternative. I would have preferred to avoid the get_terms call all together as it seems to struggle with taxonomies with larger term counts.
Hi Sean,
I'm happy to see that you were able to get through this issue.
However I must apologize that I couldn't provide a better solution for this one.
If you're experiencing any issues or have any further questions please let me know.
Otherwise you can perhaps share the coded solution so it can assist other and mark this ticket as resolved so it will show up first for users with similar queries.
Thanks,
Shane
The code I utilized calls upon another function (includeCurrentSearch()) which essentially merges the archive loops current query vars with the value input for a single term in my taxonomy. This then outputs the HTML DOM reserved when I originally used the default Toolset output (the hacky part of this solution.) I would likely add some caching / setting transients to speed some things up, but the default caching already keeps the query relatively on the low side. Not sure how well it would scale adding many other filters though this is less a limit with ElasticPress.
function tw_output_fitment( $atts , $content = null ) {
// Attributes
$atts = shortcode_atts(
array(
'term_slug' => '',
),
$atts
);
global $WPV_view_archive_loop;
$wpvArchiveLoop = $WPV_view_archive_loop->query->query_vars;
$checked = '';
$current_query = json_decode(includeCurrentSearch($wpvArchiveLoop['tax_query']));
if(isset($_GET['wpv-fitment'])){
$checked = 'checked';
}
$found_posts = $current_query->data->found_posts;
$disabled = '';
if($found_posts == 0){
$disabled = 'disabled';
$found_posts = 0;
}
//@TODO - $fitment will be dynamically generated slug of user's vehicle
$fitment = '2017-toyota-tundra';
$name = get_term_by('slug',$fitment,'fitment');
$vehicleName = $name->name;
$content =
'<div id="fitment-ctn" class="form-check fitment-ctn">
<input type="checkbox" class="js-wpv-filter-trigger form-check-input fitment-check-input" name="wpv-fitment[]" value="2017-toyota-tundra" id="form-cd1ecd85b23a2339f4005f8ebf161cf9-1" '.$checked.' '.$disabled.'><label class="form-check-label fitment-label" for="form-cd1ecd85b23a2339f4005f8ebf161cf9-1">'.$vehicleName.' ('.$found_posts.')
</label>
</div>';
return $content;
}
add_shortcode( 'tw-output-fitment', 'tw_output_fitment' );
My issue is resolved now. Thank you!