Home › Toolset Professional Support › [Resolved] short code for filtering custom field
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 |
---|---|---|---|---|---|---|
- | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | - |
- | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | - |
Supporter timezone: Europe/London (GMT+00:00)
This topic contains 5 replies, has 2 voices.
Last updated by Nigel 1 year, 2 months ago.
Assisted by: Nigel.
I have a custom product. That custom product has a custom field, 'Main Flavor'. I want to create a view that will display other products that have the same value in the custom field 'Main Flavor'.
I followed the post that recommended the use of short code, and I replicated everything as stated in the post.
https://toolset.com/forums/topic/filtering-by-custom-field/
The problem appeared in the short code itself because I still haven't fully figured out how to create the necessary short codes.
In the post, the user has one word as the name of the custom field. Mine has two words in the name.
In the post on the screen shot, the support shows that in the field for short code you only enter the name from the custom field, But in the textual part it gives an example of short code for the whole view ([wpv-view name="Your View Name" donor="[types field='donor' item='$current_page' output='raw'][/types]"] from that post).
I tried all possible variants but I could not adjust the filter.
If I enter in Shortcode attribute field any character like ' $ = [ ], capital letters or space I get the following:
Only lowercase letters and numbers allowed as shortcode attributes
I tried only with the name of the custom field and I get the same message there.
I renamed that custom field from 'Main Flavor' to mainflavor and entered only 'mainflavor' in the Shortcode attribute field, but in that case the filter did not work and all products were listed.
I need help with this, and what to enter in my case or better said what to enter in the Shortcode attribute field so that the filter works.
I hope that I will figure out sometime soon how to form short codes and use them, not only in this case, but in general.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi there
Passing arguments to Views is a legacy feature which is not fully supported by the block editor for Views, but it is possible to mix the two approaches to achieve what is required, as I'll outline below.
First, let me share a link to the legacy documentation about this feature: https://toolset.com/documentation/legacy-features/views-plugin/passing-arguments-to-views/
Now, let me describe what's involved.
This is an example of a shortcode which includes a shortcode attribute "food":
[wpv-view name='view-of-animals' food='banana']
This shortcode inserts a View ("view-of-animals"), and it passes a value ("banana") to the View via the attribute "food".
So the View might include a Query Filter which will limit the output to those animals that eat bananas.
Let's say our animal posts have a custom field "Favourite food". We can add a Query Filter for the Favourite food custom field. The value that should be filtered by is the value passed by the attribute (i.e. "banana").
We have named the attribute we are using for this purpose "food", so in the Query Filter we specify "food" as the shortcode attribute that will provide the value for the "Favourite food" field to filter by.
So, note, we didn't call our shortcode attribute "Favourite food". We can call the attribute whatever we want (single word in lower case), we just need to be consistent in the name given for the shortcode attribute in the Query Filter and the attribute actually added to the View shortcode.
I hope that clarifies why you were having the problems you were when trying to use "Main Flavor" as the name of your attribute. (Maybe try "mainflavor" instead.)
Regarding the solution in the other thread you linked to, this is when you want the value of the shortcode attribute passed to the View to filter by to be dynamic.
Rather than creating a "banana" page and inserting
[wpv-view name='view-of-animals' food='banana']
on that page, and then creating a "nuts" page and inserting
[wpv-view name='view-of-animals' food='nuts']
you would want to create a Foodstuffs post type, and insert the View into a template for Foodstuff posts and dynamically generate the value provided by the food attribute, something like
[wpv-view name='view-of-animals' food='[wpv-post-slug]']
Views includes the powerful ability to use shortcodes as arguments for other shortcodes (which isn't ordinarily possible).
If you were working with the legacy editor this would be the end of the story.
We need to think a little more to get this to work with the block editor, though.
Note that working with shortcode attributes in Query Filters implies that you are inserting the same View in multiple places. (You don't provide a shortcode attribute where the original View is made.)
The UI of the View block when inserting an existing View doesn't provide a way to pass shortcode arguments.
The only way to provide shortcode arguments is when actually inserting via shortcode, as in the examples I've been using here.
You can either simply insert such a shortcode manually into a Shortcode block, or you can use a Fields and Text block: switch to HTML mode and click the Toolset button to open a dialog for inserting shortcodes, including for Views. You'll need to add the shortcode attributes.
(You can go to Toolset > Settings and under Admin bar options you'll see an option to add a helper menu to the admin toolbar for generating Toolset shortcodes that you can then paste into a suitable block.)
First of all, thank you for the comprehensive answer.
The word 'legacy' doesn't sound good for the future.
Now I'm a little confused.
So what is the best way to achieve what I need?
The mentioned post was something closest to my question and what I want to achieve.
1. I have a custom post type, let's call it 'Products'.
2. In that custom post type, I have 4 different custom fields, Main Flavor, Main Color, Main Effects, and Manufacturer (I don't use them on the front end, they are made exclusively for listing products with similar values).
3. I have a Template for that custom post type where I show one product (single post).
Question:
How can I create sections on the product page where I will list similar products based on the values from the specified custom fields?
First section 'Main Flavor' should list all products that have the same value in the custom field 'Main Flavor'.
Second section 'Main Color' should list all products that have the same value in the custom field 'Main Color'.
And so on...
To me, the logical solution is to use 'View', which will be created only for that purpose and will not be used on any other page. So in my case, 4 different views.
And now we come to my problem.
How to filter the products in those views, because these views are on the product page, and the value is not static. Each product has different values. So the filtering criteria is dynamic and comes from the product that is currently open.
In the filtering section I see a lot of options, but in my case only 2 can be used, URl parameter and Shortcode attribute, right?
And here I don't know what to do next.
Please tell me what is the best approach to achieve the described. Am I on the right track or not?
If my approach is ok, can you please tell me specifically in my case, which of these two parameters should I use, and what to put in the corresponding field.
Custom field name is 'Main Flavor' and field slug is main-flavor (you have a screen shot).
Thanks in advance
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Your scenario is essentially the same as the one I described, just with different post types and field names.
You have a template to display products.
In that template you want to insert a View to display other products that have the same value for the Main Flavor custom field (and you will do similarly for other custom fields).
The solution without coding is to create the View somewhere else (I suggest you make a Content Template not assigned to any post types that simply acts as a container for the View block, you can call it "Container for Same Main Flavor View", and call the View you insert "Same Main Flavor").
This View includes a Query Filter for the Main Flavor custom field, whose value comes from a shortcode attribute. You can name the shortcode attribute anything; for the avoidance of doubt lets call it something distinct from main flavor, and you can use the same attribute name with each of these similar Views you will make. Let's go with "same-as" as the name for the shortcode attribute. (I think it is okay to use hyphens; if you find you cannot then omit it.
Now, back to the template for products where you will insert this first View.
You need to insert the View using a shortcode to be able to add shortcode attributes, which I described before. And you will need to generate the value of the Main Flavor field that you will pass to the View with a types shortcode (we want the raw value stored in the database, in case this is different from the display value, such as when you use select fields).
That means you will insert the View using a shortcode like this:
[wpv-view name="Same Main Flavor" same-as="[types field='main-flavor' output='raw'][/types]"]
Do something similar for the other 3 custom fields.
As a footnote, all of the above is to avoid having to write any code. You could avoid having to use shortcode attributes and could insert Views directly in situ in the product template instead of first creating them somewhere else if you were comfortable with PHP, when it would be fairly straightforward to use the Views API (specifically the wpv_filter_query hook) to modify the View query to apply the required filters.
OK, I understand how this should be done.
I followed your instructions and the filter is now working.
The problem is in the following:
Due to the structure (design) of the page, it is necessary to set this view in the WordPress template for this custom post type, which we are talking about.
The theme I'm using is twenty twenty three, and I know toolset doesn't support this theme. Maybe one day the developers will start improving the toolset so it will be supported. Until then, we have to find solutions, as we know and as we can.
When I use the short code we're talking about in the WP template for the corresponding custom post type, the filters don't work (the view works). If I use the short code in the toolset template for this custom post type, then the filters work.
It is perfectly fine to do this in the toolset template. The problem is that in the toolset template I did not find how to display the Post content (body) of the current custom post.
I tried with the paragraph and the following:
POST SOURCE:
Current Post
SOURCE:
Post Content (Body)
I tried with the Toolset block Single Field and the following:
FIELD TYPE:
Standard field
POST SOURCE:
Current Post
SOURCE:
Post Content (Body)
Noon of the above worked, and I don' know how to show post content.
Going back and using the twenty twenty one theme is not an option for me.
If there is no other way how to display post content, then displaying similar posts with the help of short code is not a good solution.
If there is no other trick or workaround, can you briefly explain to me how the view can be filtered with the help of php. I'm not a developer but my son knows php well.
Btw, the filter doesn't accept 'hyphens'.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
I'm not sure why you are having problems outputting the post content from a Toolset template.
For that you would use the Single Field block, as shown in my screenshot.
If you wanted a code solution instead, it would work like this.
Make a View to show related products that have the same Main Flavor as the currently displayed product, inserted into the template for products.
You will add a Query Filter for the Main Flavor field. This time set it to some arbitrary value (e.g. 999). The code we add will modify this arbitrary value in the actual query, replacing it with the value of the Main Flavor field from the currently displayed product.
You will need to make a note of the ID of the View (at Toolset > Views; if you can't see this, in Toolset > Settings make sure the legacy interface is exposed).
Do the same for the other 3 fields, so that you have 4 Views (and know their IDs) in total.
Add the following code to your site. You can add it to your theme's functions.php, or you can add a snippet at Toolset > Settings > Custom Code.
You will need to edit the first lines to put in the View IDs (e.g. 123) that correspond to the field they include a Query Filter for (e.g. 'main-flavor'). This array uses the slugs of the fields. If they are wrong in my example, correct them.
function ts_filter_query_fields( $query_args, $view_settings, $view_id ){ // Edit to specify the view ID which is filtered by the given field slug $views_and_fields = array( 123 => 'main-flavor', 345 => 'main-color', 456 => 'main-effects', 567 => 'manufacturer' ); $view_ids = array_keys( $views_and_fields ); if ( in_array( $view_id, $view_ids ) ){ // Get the value of the field for the current post global $post; $meta_key = 'wpcf-' . $views_and_fields[ $view_id ]; $value = get_post_meta( $post->ID, $meta_key, true ); // Update the query filter for this field with this value $query_args['meta_query'][0]['value'] = $value; } return $query_args; } add_filter( 'wpv_filter_query', 'ts_filter_query_fields', 10, 3 );
I expect that should work, but if you have problems, perhaps you son can go over the code and check it.
(The reference for the wpv_filter_query is here: https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query)
This code has worked for me, thank you very much Nigel!