I’ve been using FacetWP for a year or so and it’s, hands down, the smartest WordPress plugin I’ve ever bought. Certainly I could have coded it, but not having to and being able to extend it to do what I need has saved me months of work and support.
This is not to say it’s perfect. I’ve run into multiple quirks and headaches that resulted in me writing weird code to solve. And the solution to the null entry was no different. But it was, at the end, solvable.
A Null Entry
The majority of my data is saved in custom taxonomies. This makes it easy for me to grab and process. It’s also easy to list, because I can point people at /taxonomy/term
and FacetWP magically populates properly in the sidebar.
However. In one case, I have a checkbox. This is a simple post-meta to say if we love a show or not, and that check box, if it exists, is detected by FacetWP and I can easily get a list of all loved shows. The reverse is, sadly, not easy.
That’s because if the checkbox is empty, there is nothing saved. No post meta. And if there’s no data, then when FacetWP builds out it’s list, there’s nothing saved for the non-existent data, and therefore no way to list nothing.
An Imaginary Entry
The other problem, related to this, is that I use Taxonomies in a different way. That is, while I use them like everyone else does with tags and categories, I also use them to track ‘stars’ – gold or silver etc. Obviously that makes it easy to track with /stars/gold/
buuuuuuut what if I wanted to list all the shows without any stars?
How do I tell FacetWP ‘if there’s no taxonomy data saved for this, use a default?’
A Fake Facet
The answer lies within making a fake, that is unused, facet.
The tl;dr to how FacetWP works is that it generates it’s own table with the data it collects from it’s facets. In general, there’s a 1-to-1 relationship with the facet and how it outputs. If you’re saving the terms of a taxonomy (like star colors), then there’s an entry in the database for the show and it’s star. If something has multiple values (like tags) then it has multiple entries.
You can then alter the
The Facet
In order to make entries for my null or imaginary values, I made a facet that I didn’t use that I called all_the_missing
and I gave it the data source of “Post Types”:
The rest doesn’t matter. I’m not planing to display this, and I picked post types because it’s a quick bit to add the database without making it too heavy or complicated. Also I know it’ll exist for all my data.
The Filter
The magic to all this is my filter for facetwp_index_row
:
if ( 'all_the_missing' == $params['facet_name'] ) { // If we do not love the show... $loved = get_post_meta( $params['post_id'], 'shows_worthit_show_we_love', true); if ( empty( $loved ) ) { $params_loved = $params; $params_loved['facet_name'] = 'show_loved'; $params_loved['facet_source'] = 'cf/shows_worthit_show_we_love'; $params_loved['facet_value'] = 'no'; $params_loved['facet_display_value'] = 'No'; $class->insert( $params_loved ); } // If there are no stars $stars = get_the_terms( $params['post_id'], 'the_stars' ); if ( empty( $stars ) ) { $params_stars = $params; $params_stars['facet_name'] = 'show_stars'; $params_stars['facet_source'] = 'tax/the_stars'; $params_stars['facet_value'] = 'none'; $params_stars['facet_display_value'] = 'None'; $class->insert( $params_stars ); } return false; // skip default indexing }
Now this is also wrapped in an if ( get_post_type( $params['post_id'] ) == 'post_type_shows' ) {...}
check so this particular one only runs when shows are saved. But you can see what I do is when I run that specific facet, I check if the other data is available and if so, save it.
Improvements
I’d like to actually not have to save data when I don’t need it, but the need is enough that having this work was paramount. I can now sort when there’s no data, and that was what I needed.