.Some further musings on Categories and Tags sparked by my need for some of my components to use tags but sometimes to restrict the range of tags that can be selected. This started as a need to simplify the tag inputs for xbFilms and xbBooks where the same group of tags (eg Genres) might be used in both components along with other tags.
The obvious solution might be to have a separate database field for Genre but this adds unnecessarily to the complexity of the data structure (especially since there might be a many-to-many relationship between items and genres - a comedy western film and a western adventure book).
The built in tags provide a lot of flexibility including the ability to share them across components, to simply display the assigned tags for an item on the views, and the fact that they can be arranged in a hierarchy so that all genre tags can be children of a common parent
Genres. Hence the ChildTag field type.
Categories in Joomla can also have a hierarchy, and they have a property to allow the Category form field to return multiple category selections. Personally I can't see the use case for this since categories are specific to a component, and built in components all use category as a single value per item. I suppose you could write a component that allowed multiple categories per item - but then you'd have to have a many-to-many link table to join categories to items an implement all the logic required to manage that - whereas if you used tags instead of categories then all that stuff is (pretty much) built in.
What neither the standard CategoryField not the TagField form field types is a "level" property to restrict the number of levels in the heirarchy to include in the choice. I think I can see the need for a
levels property in addition to
parent to further restrict the choice. It would be easy enough to implement in overriding the TagField::getOptions() method, A similar thing could be done for categories although the field definition gets its options from
HTMLHelper::_('category.options', $extension, $filters); so you have to override two functions - the CategoryField itself and the HtmlHelper function.
Tags are a lot more flexible - not only can you have multiple tags for each item, you can also re-use tags between components. But this flexibility comes with a cost - partly because not enough attention has been given to the tag views and facilities available in core Joomla. (this seems to still be the case in J4)
Using my xbCulture components as an example both films and books are often assigned to "genres" - and a genre may apply to both books and films. eg There is a genre of horror films and a genre of horror books. Or "Nordic Noir" or "Westerns". Furthermore a work may be assigned to more than one genre - being both a comedy and a western, or a romance and a drama, and using a tree structure as is available with categories doesn't really help - comedy is not a sub-genre of western or vice versa. You can see the problem with this in music ID3 tags were "Genre" is a flat list with a song belonging to a single genre. At first it included
Jazz. But then along comes Folk-Rock and Jazz-Rock and new mutually exclusive genres have to be added. The list of 'standard' genres is now ridiculously long, whereas if a song could belong to multiple genres it would be much improved - you could play all
rock songs, or just the ones with
In a similar way you might want to classify works by topics, or themes. Or a hundred different groupings for your particular need.
This is all very well, but you can quickly arrive at having many many tags - meaning when you want to assign an item you either have a very long list (hopefully organised sensibly) to choose from, or using Ajax autocomplete you have to remember whether you were using "art" or "painting" for books about the painterly arts.
In summary, when thinking about the data structure for a component with two or more types of item in separate tables (which may be linked in a one-to-many or many-to-many relationship or unrelated) and which have various ways of classifying the items you have various option.:
- If a classification list is only used for one type of item within one component then it should probably be a separate field. in the data table.
- if the items in the list are just a single pre-defined value then you can use a simple list for data entry (creating or editing an item or filtering on a value)
- if the user can add new values when entering or editing then you can use a combo box for data entry but you will probably want to define a new field type as a subclass of combo which will get all of the existing values from the database to populate the list.
- If the items in the list have a description which you might want to display as well as a short name or title, then you may want to use either Joomla categories or Joomla tags. In this case you can use the built in Joomla facilities for defining the values and descriptions and selecting and displaying them. (although both category and tag component views are somewhat limited and you'll probably end up writing your own.)
Note that tags will also be available to all other components using Joomla tags, including the built-in ones like articles/content, banners, etc. Categories are specific to your component.
- If the main item can have more than one value from the list then it is possible to use categories with multiple selection enabled, but then you won't be able to use any of the standard layouts to enter or display them - you'd be better off using tags.
- If the classification list is shared by more than one type of item in your component then categories may be ok so long as there is only a single value allowed per item.
- If you want to make the items in your list, whether or not you are using the description as well as the name/title, available outside your component then tags are the way to go. But remember that standard articles will have access to all the defined tags.
- If you want to keep the values in your list private to your component then don't use tags - have your own list of values.
- If you want to have more properties than just title and description for your classification list entries, or if you want just title and description but also want a private list, then you need to create an addition data table for the list entries and probably a link table as well if an item can have multiple values from the list.
- If you have a lot of tags then you may wish to extend or override the standard category or tag classes to restrict selection to a particular branch of the hierarchy for some classifications.