I have a taxonomy in which term order matters, but varies from post to post. So I want to be able to set the order that terms are displayed in on a per-post basis:
-
My first post | Tagged: Apples, Oranges, Bananas
-
Some other post | Tagged: Oranges, Bananas, Apples
Since this would vary from post to post, I need something other than the taxonomy-wide term ordering supported by plugins like Custom Taxonomy Sort and Taxonomy Terms Order.
I am looking for advice on how to implement this. Here is an outline of my current thinking:
Per-post term ordering using a custom field
-
Remove standard taxonomy metabox using
remove_meta_box()
-
Add custom metabox containing term ordering interface, e.g., drag-and-drop (or simple text input next to each term for an integer describing term’s order. (Or perhaps it’s possible to add drag-and-drop to the existing meta_box without having to remove and add a new one?**)
-
Using javascript, save a comma-separated list of term IDs, in order, in a hidden custom field, _mytermorder_taxonomyname. (Separate custom field for each taxonomy, e.g., _mytermorder_category, __mytermorder_tags, etc.)
-
Create a custom function
my_get_the_terms()
that loops through the IDs in the _taxonomyname_termorder custom field. If a post has terms but no _taxonomyname_termorder field (as with old posts), just return get_the_terms(). -
In relevant theme files, replace instances of
get_the_terms()
or other native term functions withmy_get_the_terms()
.
Do you have advice, alternatives, warnings, or related snippets? I’d be grateful for any thoughts. Thank you!
Concerns
- What if the list in the custom field gets out of sync with the actual term list (as it would if terms were added through an interface other than the post edit screen, such as the quick-edit/bulk edit form or Front-End Editor).
Solution: At the beginning of my_get_the_terms()
, we can check whether the IDs in the custom field match the terms returned by get_the_terms. If not, default to get_the_terms.
-
New terms wouldn’t be captured on first use, because they don’t yet have an ID. You’d have to save a new term before it would work. (I could live with this, but it is a problem.)
-
The meta box has to list terms in the right order when the post edit page loads.
** For drag-and-drop sorting in the default metabox, I discovered that I can use jQuery UI’s .sortable, already available in the admin; for a non-hierarchical taxonomy, it’s $('#taxonomyname .tagchecklist').sortable()
.
I’m not sure if I understand exactly what your trying to accomplish but I’ve outlined a way for you to sort the order of terms associated with the current post.
Html for the term order metabox:
Javascript to make the above list sortable and save the order using ajax.
*Note: requires jQuery UI-Sortable.
WordPress ajax function to save the order as a custom field:
This will save a list of the term id’s in order sorted as a serialized array:
_term_order => array(
term_order => ‘123,312,110,34,44,27’
)
To show the list of ordered terms on the front end:
I’m sorry for bringing this question back to life after such a long time. This need is something that I came across recently and while searching for an answer bumped into this question.
After some digging I found out that apparently WordPress has had for quite some time (ticket #5857) a
term_order
column inwp_term_relationships
table to tackle this particular problem.To make use of this colum and term ordering you need to add
to
register_taxonomy
$args
, when registering a custom taxonomy, or toregister_taxonomy_args
, if modifying an existing taxonomy.Naturally this doesn’t give you nice drag’n’drop term ordering on the edit view, but just saves the terms in the order they are attached to the post. And you need to watch out for any greedy plugins you might have installed on your site, which might mess with this.
I think this is the first time ever I noticed these arguments in the
register_taxonomy
documentation page as they are perhaps a little poorly noted there. But on the source file they are documented better, taxonomy.php, register_taxonomy()Below is a workaround that helped me a lot. I have tried to explore register_taxonomy and args at wp documentation, and finally made it.