Skip Navigation

[Resolved] How to filter by the first character of a custom field?

This thread is resolved. Here is a description of the problem and solution.

Problem: I would like to allow my users to filter a View by the first letter of a custom field. For example, I want the user to be able to filter with "R" and show all results where the custom field value begins with "R".

Solution: There's no way to filter by the nth character in a field value. The best way to do this is to use two separate custom fields. The first custom field will contain the complete information, and the second custom field will contain only the first character of that information. You can choose to manually add this single character during the post creation workflow, or you can choose to write some PHP code that will handle it automatically upon saving a post.

Then, filter your View by the single-letter custom field to achieve the desired filter results.

Client's example PHP code to set this single character field automatically when a post is saved:

add_action('save_post', 'schreib_alf_v_sortname_upd', 100);
function schreib_alf_v_sortname_upd($id){
    // only do this for reports post type
    if (get_post_type($id) != 'reports')
      return;
    // get the lowercase first letter of the full field value
    $a = lcfirst(substr(get_post_meta($id, 'wpcf-sortname', true), 0, 1));
    // set the correct value of the single character field
    update_post_meta($id, 'wpcf-alf', $a);
}

Relevant Documentation:
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
https://codex.wordpress.org/Function_Reference/update_post_meta

This support ticket is created 7 years, 4 months ago. There's a good chance that you are reading advice that it now obsolete.

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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 5 replies, has 2 voices.

Last updated by pattyS-2 7 years, 4 months ago.

Assisted by: Christian Cox.

Author
Posts
#551710

Hello,

I am working on importing a magazine site into wordpress, my first project using Toolset. I always found answers in the (really good!) documentation, but now is the time I need help please:

I have a Views Archive of a Custom Post Type "reports" and a custom field "sortname".
I want to add the possibility for the visitors to see an alphabet, and when clicking on one of the letters, see all posts that have a "sortname" beginning with that special letter.

So I added the letters, (transmitting a parameter in the url for example ?alf=b) and added a filter for the custom field "sortname" and the url parameter "alf". Now I don't see a comparison option that allows "begins with" or similar.

How can this be done?

I found wpf_filter_query in the docs, but I am no developer and know only very very little of php. So what I tried just had no effect at all.

Thank you for help
Patty

#551834

I can think of a few different ways to accomplish this. Here is the best approach I can recommend:

Create a second custom field that will hold a single letter. Whenever a post is published or updated, save the first letter of the sortname custom post field into the new custom field. This can be done automatically using PHP, or you and your authors can do it manually when a post is created. Instead of filtering your View using sortname, filter using the new custom field.

If you choose to go with the manually approach, it requires no extra code and can be accomplished with the regular Views GUI. The automatic approach will require a small amount of PHP added to a functions.php file, and I can help you get that set up if you'd like.

#552789

Thank you very much. Ok, I added the new field, as you supposed, and managed to write a custom function that filled the content for all imported posts so far. And now I have more questions.

I like the automatic approach that you are talking of.
I had a look on wordpress.org action hooks and tried some, but I guess I don't understand that hook thing enough. Can you help please?

That's what I added to functions.php

add_action('save_post_reports', 'schreib_alf_v_sortname_upd');
function schreib_alf_v_sortname_upd($id){
	  $a = lcfirst(substr(get_post_meta($id, 'wpcf-sortname', true), 0, 1)); 
	if ( ! add_post_meta($id, 'wpcf-alf', $a, true))
	 	update_post_meta($id, 'wpcf-alf', $a);
}

And one more question, the new field should not be editable for authors/editors, I'd prefer that it is not even visible in the backend. Is that possible without writing code, using the Toolset ACCESS PlugIn ?

Thank you again for your support
Patty

#552994

Nice work so far! A couple of hints:

add_action('save_post_reports', 'schreib_alf_v_sortname_upd');

You'll have better results if you use the 'save_post' action instead of 'save_post_reports'. Types uses the save_post action to update some post meta information, and save_post_[post-type-slug] fires before save_post. If you want to apply the callback code to reports only (if your post type slug is 'reports'), use 'save_post' and apply a conditional inside the function callback:

add_action('save_post', 'schreib_alf_v_sortname_upd');
function schreib_alf_v_sortname_upd($id){
    if (get_post_type($id) != 'reports')
      return;
    $a = lcfirst(substr(get_post_meta($id, 'wpcf-sortname', true), 0, 1)); 
    if ( ! add_post_meta($id, 'wpcf-alf', $a, true))
        update_post_meta($id, 'wpcf-alf', $a);
}

Also, I don't think the add_post_meta conditional is necessary. Refer to the documentation here:
https://codex.wordpress.org/Function_Reference/update_post_meta

This may be used in place of add_post_meta() function. The first thing this function will do is make sure that $meta_key already exists on $post_id. If it does not, add_post_meta($post_id, $meta_key, $meta_value) is called instead and its result is returned.

So the resulting code is:

add_action('save_post', 'schreib_alf_v_sortname_upd');
function schreib_alf_v_sortname_upd($id){
    if (get_post_type($id) != 'reports')
      return;
    $a = lcfirst(substr(get_post_meta($id, 'wpcf-sortname', true), 0, 1)); 
    update_post_meta($id, 'wpcf-alf', $a);
}

Give this a shot and let me know the results.

#553291

Thank you very much for your solution and hints, and for explaining about the code, this is really very helpful for me learning how to get things done with the Toolset PlugIns. 🙂

Unfortunately, it is still not working yet. When I edit something in a report's post body, also edit its sortname and then save, it is all correctly saved, but the alf field still has the old value.
When I add a new report, fill sortname and save, the alf field remains empty.

I deactivated all PlugIns Except Toolset's Types and Views.
Also switched to the twentyseventeen theme and copied only the one hook+function into its functions.php file, but still the same behaviour.

What am I missing? do I need to register the function somewhere in the Toolset settings?
I have no idea. Can you please help again?

Thank You

#553537

Okay first, try adding a priority to your save_post action:

add_action('save_post', 'schreib_alf_v_sortname_upd', 100);

If this does not resolve the issue, I'll need to take a closer look in your wp-admin area to see what's going on. I may need to create a clone of your site using the Duplicator plugin, so I can install the site locally and run a few tests. If that's okay with you, please provide login credentials in the private reply fields here.