Make WordPress Core

Opened 17 years ago

Closed 17 years ago

#3723 closed enhancement (fixed)

Tagging

Reported by: ryan's profile ryan Owned by: ryan's profile ryan
Milestone: 2.3 Priority: normal
Severity: normal Version:
Component: General Keywords: tags
Focuses: Cc:

Description

Support tagging in core. Tagging should be distinct and separate from categories since many people want to use both at the same time. Themes will need to update to use the tag template API.

Attachments (3)

tagging.diff (8.1 KB) - added by ryan 17 years ago.
Draft tag schema and API
tags.diff (9.2 KB) - added by ryan 17 years ago.
Tagging using categories and post2tag tables
taxonomy_type.diff (8.5 KB) - added by ryan 17 years ago.
Add category type field and use it instead of -1 counts

Download all attachments as: .zip

Change History (69)

@ryan
17 years ago

Draft tag schema and API

#1 @ryan
17 years ago

Would be nice to add the flickr-like UI from #3130.

#2 @technosailor
17 years ago

+1

You won't hear arguments from me on tagging. I've been a vocal supporter.

However, perhaps consider using a different table than tags as that is already in widespread use thanks to UTW.

#3 @ryan
17 years ago

Yeah, and some plugins use a "wp_" prefix for the functions in their tags API. Grrr.

Would be nice to share the table name used by bbPress (tags) for those wanting to integrate WP and bbPress, but playing nice with UTW is probably more important.

#4 @majelbstoat
17 years ago

What are the problems with just reusing the same table that UTW uses? That way, when people upgrade, the tags will still be there... And we can assume that when people upgrade to 2.2, they'll disable their tagging plugins, right? So we wouldn't have to worry about using 'wp_' prefixed functions either... Or am I missing something?

#5 @technosailor
17 years ago

I suppose in theory that would work except that is sort of like coming into someone's house in the middle of the night uninvited and, uh, stealing the milk. And cookies. Cookies, I say! How dare they?

And then what's to stop Christine from changing UTW's schema and issuing a DROP TABLE in UTW?

#6 @majelbstoat
17 years ago

Sure, but I'm just assuming that there won't be an UTW for 2.2, and WP could just take over where it leaves off - I'm pretty sure that there are other popular tagging plugins that use the same schema (What does Jerome's Keywords use?). And if someone's going to display their cookies in a glass jar, they should expect them to be taken! Don't think of it as stealing, think of it as... 'liberating' (that's the term nowadays, isn't it?) I think people would be happy to find that their tagging still 'just works' - imagine having to reenter all your old tags...

On another note, are we going to implement tag synonyms? I'm thinking from a multilingual perspective, but I know UTW already provides it as well.

Finally, isn't this an enhancement?

#7 @markjaquith
17 years ago

  • Component changed from Administration to General
  • Type changed from defect to enhancement

Yes, enhancement.

Using her schema seems sort of rude, and may cause unexpected results. You can bet anything that there will be a UTW > WP tag conversion script the minute this becomes stable in /trunk/, so don't worry about that.

#8 @ryan
17 years ago

I think Jerome's Keywords uses post meta.

I want whatever schema suits us best. Maybe UTW's will be fine, maybe not. The schema in my patch is borrowed from bbPress. Proposals are welcome. UTW users can be easily migrated with a small upgrade script if we use a different schema.

As for synonyms, maybe we should include that, not sure. In general, I'd prefer to have the built-in tagging be just the basics and leave more advanced stuff to plugins.

#9 @markjaquith
17 years ago

Ryan,

For synonyms, you could just include a "synonym_of" column (which would store the lower-case-dashed form of the tag that the current tag should point to). You don't have to populate it in core, and I don't think that functionality needs to be in core, but having the blank column there goes a long way toward making sure that various third party solutions will inter-operate. See: comment_parent for another good example of "if you do it, use this" sort of pointers.

UTW with its bells and whistles isn't going away, and it'd be great if it could be converted to use the WP tags table and just layer on the additional functionality.

#10 @majelbstoat
17 years ago

I would say that using Christine's schema validates her good design - and it is a good design, fully normalised for many to many relationships. We shouldn't not use it, just because it's been used already. If tagging plugins aren't going away, whatever we call the new table, aren't UTW and others going to have to use it anyway? Rather than saying UTW has to make code alterations to use a new table name, couldn't we just make WordPress use what's there already? Anyway, the name's not a major point - just trying to think about how this can be implemented so that the least number of things need to be re-engineered about it. You're probably right about unexpected results though... Maybe Christine, Jerome et al could be approached for some comments as they have quite a stake in this?

Having said all that, the schema Ryan proposed will do the job well. Do we need a tag_count column though? "SELECT COUNT(*) FROM $wpdb->tags WHERE tag_id = 'xx'" would do the job and doesn't risk the count getting out of sync. 'tag' is for the human readable, 'rawtag' for internal use, is that right? How come they're different sizes? Is rawtag going to be unique, or are we allowing 'London', 'london' and 'LONDON' as separate tags?

I like the synonym_of idea - again, not imperative, but helpful nonetheless.

#11 @ryan
17 years ago

COUNT() can be crazy expensive for some engines. MySQL engineers suggested we just store the counts, and so we do for comments per post, posts per category, links per category, and so on. We have API for eveything, so keeping counts in sync isn't too difficult.

raw_tag is the tag name as given by the user. tag is the sanitized version.

#12 @matt
17 years ago

Having a table exactly like wp_categories except for the name seems like a waste of time. That table already handles two types of categories, why can't it handle a third?

#13 @ryan
17 years ago

We could add a tagged_count field to the categories table, sure. Do the > count queries cost us enough to make a separate table more desirable, though?

Ryan

#14 @nbachiyski
17 years ago

Just some trivial notes on the code in the patch:

  • On line 31 in tag.php the $tag variable should be escaped before being used in the query (I know it is sanitized before INSERT, but who knows...);
  • The insertions and deletions of post tags in wp_set_post_tags could be done with just one query each, not lots of queries in a loop;
  • The count update could be done with 2 queries - one for the added ones, which increments their count with 1, and one for the deleted ones, which decrements their count with 1. Thus we will also get rid of the COUNT(*) calls;
  • We need a unique key on raw_tag in the $wpdb->tags table, because of the query in get_tag_id().

#15 @markjaquith
17 years ago

definitely store the counts. The way you make sure that even non-API updates don't totally screw your count is to use COUNT() on API'd updates. As long as you don't do count = count + 1, you should be fine.

We could use wp_categories I guess. But we should probably hide them from being managed on Manage > Categories. I think tags shouldn't really NEED management. They're spontaneous. If people want fancy stuff like merging and mass-tagging, leave that to third party solutions.

#16 @matt
17 years ago

We already have a ton of rewrite, API, etc infrastructure around categories. Mostly I see tagging as a new interface to the data. On the display side, people want their tags listed separately from their categories, and probably something like a tag cloud function.

On the admin side, you should be able to enter and edit them comma-separated in a long box under the post like del.icio.us. Tags should never be shown anywhere except in the concept of a post, no manage screen for them for example.

We should also probably support the colon and equal characters in tags now, to take advantage of the new machine tag movement that flickr is spearheading.

#17 @ryan
17 years ago

Problem with adding tags to categories table is that it will further complicate our post and link category queries by adding something else to exclude.

tagged_count = 0 OR link_count = 0 OR category_count != 0 OR ( link_count = 0 AND category_count = 0 AND tagged_count = 0 )

#18 @matt
17 years ago

If that's a huge concern, we can always set a flag, maybe bitwise.

#19 @ryan
17 years ago

Not a huge concern. Just airing out the laundry.

@ryan
17 years ago

Tagging using categories and post2tag tables

#20 @ryan
17 years ago

Here's an untested, partial patch that lays some groundwork for using the categories table for tags. A tagged_count field in the categories table tracks number of posts/pages using the tag and a new post2tag associates posts to tags.

I'm thinking queries for categories should query both categories and tags. category_name would match a proper category named "foo" or a tag named "foo" (which are the same object in the DB). Given one post categorized as "foo" and another tagged as "foo", a category query for "foo" would match both. This means that the /category/foo/ permalink is both a category and tag permalink. The user could set the permalink to be /tag/foo/ if so desired.

As for template functions, there will be separate API for tags so that themes can display category and tag info for a post separately. We might want a way for themes to say "combine tags and categories" so that they can exclusively use the category template functions. In this situation, get_the_category(), for example, would return both tags and categories.

#21 @majelbstoat
17 years ago

Please can we not reuse the main categories table for tags and make it even more monolithic than it already is. I'm not in touch with MySQL engineers or anything, but from my own experience, as well as everything I've ever read on the subject, the further you take the database away from normalisation, the less maintainable things become. You'll need more code just to do simple things like present Manage->Categories and more SQL for virtually everything that touches the Categories table. We already can't even do something as simple as SELECT * FROM wp_categories.

What would be the purpose of get_the_category returning tags as well? People are already complaining that they can't easily get the post categories anymore, without also getting link categories. Honestly, link categories shouldn't even really be in the categories table - and you've seen all the bad feedback regarding management of this in 2.1, which is at least in part due to the merging of those data sources.

Categories and tags aren't the same thing and having another table isn't a bad thing - core only has 10 tables anyway. And if you're going to be joining to the categories table anyway, you might as well join to a tags table...

#22 @ryan
17 years ago

I don't really care either way, although I think those who have to have completely separate link categories and post categories are obsessive tweakers who need extra hobbies. :-) I think SELECT * on the categories table with link cats, post cats, and tags in it is just fine. For me there is so much overlap between them all it wouldn't matter. It's just a big pool of keywords to be used for whatever. Simple, elegant, easy fo sheezy. The messy queries that test the counts for this and that were added to appease those who are more complicated and demanding than simple me. Some people don't like their eggs and pancakes to touch. Go figure.

The idea behind having everything in categories is to not store the same stuff over and over. There is often lots of overlap between link categories, post categories, and tags. They're all just taxonomy after all.

But, hey, whatever. I'll let everyone else argue over it awhile before I write any more code. This is not something I particularly care about, so I'll let the more passionate carry the water.

#23 @otto42
17 years ago

Putting tags into the categories table would be enough to make me switch away from Wordpress, or at least to patch it to disable all core tags entirely and go back to UTW.

In short, it's a dealbreaker.

I can understand combining link and post categories. That fits a big picture that I can see. I cannot understand combining categories and tags, and I will not use a system that attempts to do that.

But categories are not tags. They should not be combined. Doing so only confuses the system more and makes hacking on it and explaining it incredibly difficult.

#24 @ryan
17 years ago

Indeed, categories are not tags. They will not be used as such regardless of where they are stored. That's why there is a separate post2tag table. Point taken though.

#25 follow-up: @matt
17 years ago

"Putting tags into the categories table would be enough to make me switch away from Wordpress, or at least to patch it to disable all core tags entirely and go back to UTW."

I'm surprised you care more about the technical implementation of a feature than the user experience. We could put it in the options table and if it scaled and worked well people would use it. I haven't heard a good technical reason to not put it in the existing categories table, other than people who are obsessing over the semantics of what it's called.

WE ARE NOT SAYING CATEGORIES ARE TAGS. Please re-read that sentence, and look at the actual code being produced. If we thought they were the same thing, this issue wouldn't even exist.

#26 @majelbstoat
17 years ago

I can appreciate that they are similar and it would be tempting to reuse an existing table. I just think you'll be sacrificing lots of flexibility in the process. What if you want to add a new column relevant to only tags in the future? You end up adding it to a table full of categories, where many of the fields will just be blank, because they aren't relevant to that category/tag/link category.

I agree that the user-experience is the most important thing, but having a good technical implementation is very important in allowing developers to create that experience. The name of the table isn't important so much as the separation. Ryan's first diff defined a simple and effective schema. It allows easy integration with bbPress. Plugin authors can add columns to the tags table separately to add new functionality applying only to tags. That, or something similar, would be the implementation that got my vote.

#27 follow-up: @matt
17 years ago

"What if you want to add a new column relevant to only tags in the future?"

Instead of "what ifs" what would be helpful to the discussion is "this is a specific thing that won't work if tags and categories are in the same table."

Reusing tables has worked out well for us in the past, for example we don't have separate tables for posts and pages and attachments, etc. It actually allows us a lot more flexibility, and prevents table bloat. (Remember installing PHP Nuke and getting 40-someodd tables?)

#28 @MichaelH
17 years ago

The analogy to the post table isn't quite fair as each row in wp_posts is differentiated by the post_type column. When a category is initially created it is fair game to be used as either a post category or a link category and only after it is claimed by a published post (categories are not claimed by draft posts but that's another story!) or a link, does it become off-limits to the other.

Under the current schema there may be no way to keep a category from being claimed as a tag. In that sense a post category is a link category is a tag. Maybe a column for category_type is called for.

Notes:

  1. In the event a column for category_type is added, upgrade process will need to deal with the fact a category might be assigned to both a post and a link.
  1. In wp_categories should there be a tagged_private column?
  1. Is this the time to discuss tagging pages as well as posts?

#29 @andy
17 years ago

There is no point when a category becomes off-limits to links or posts. It is applied via the post2cat/link2cat tables.

I think the reason for keeping postcats/linkcats/tags in the same table is that the metadata is identical. A category "Dogs" will have the same description and slug as the tag "Dogs".

There is no need for a category_type column.

Where we may get some additional benefit is in consolidating the link2cat/post2cat/post2tag tables into a single table called relationships or some such.

CREATE TABLE rels (
 rel_table ... /* posts, links, comments, users, etc. */
 rel_type ... /* category, tag, label, etc. */
 rel_cat_id ... /* key to categories table */
 rel_item_id ... /* key to item table (posts, etc.) */
) ...

If we avoid enums, this can be used for all sorts of crazy *onomies and plugins. It might also make for tighter integration with bbPress and who knows what else.

#30 @MichaelH
17 years ago

There is no point when a category becomes off-limits to links or posts. It is applied via the post2cat/link2cat tables.

Had to see it to believe it but I stand corrected. Once a Category is used for a link, it's not displayed as a Category when writing a Post but you can "Add" it as a post Category. Actually you can add whatever you want for a Category and I guess that's the point.

#31 @xmarcos
17 years ago

There is no point when a category becomes off-limits to links or posts. It is applied via the post2cat/link2cat tables.

The main goal of this structure is performance, the schema you suggest may take down the db server if you have some decent traffic.

#32 @xmarcos
17 years ago

Tag as a core functionality: +1

UTW have some problems/limitations that needs to be fixed, and the schema is rather poor to be used as a base. In order to implement this as a core feature, the database table should be modified so tags can have a "nice name" and the proper "tag slug" (for permalinks use), as we currently have in posts.

The UI should be rather simple, I'm for the delicious implementation, suggest feature and existing tags list should be included as well, plus a way to add complex tags as Flickr uses.

Regarding themes and plugins, the API should be really simple and the schema could be something like this,

tag_id
tag_name
tag_slug
tag_count

With that simple, yet powerful structure you can build a decent API, plus, we will need some hooks in the admin UI in order to allow developers to add some extra features, and some options to configure basic functionality of the feature.

#33 in reply to: ↑ 25 @Otto42
17 years ago

Replying to matt:

I'm surprised you care more about the technical implementation of a feature than the user experience.

I'm not a user, I'm a developer. I write code. I write plugins. I modify things. So I most definitely care about the technical implementation. A poor technical implementation makes things that much more difficult to deal with.

As for user experience, the links/posts category integration hasn't gone all that well on that front so far, what makes you think shoving tags in with the categories willy-nilly would work any better?

I haven't heard a good technical reason to not put it in the existing categories table, other than people who are obsessing over the semantics of what it's called.

Fine. Here's one: you actually do completely different things with tags than you do with categories. All the queries dealing with categories would have to be changed to make them ignore tags. You'll have to write a bunch of new ones to deal with tags, and in so doing will have to make them more complex so that they will ignore the now intermingled categories. And why? Because you don't want to create a new table to hold things that are, in fact, completely new?

Why make all your queries more complex when you can just separate the tags from the categories? Implementation details, above all else, should make sense.

My point is that there's no good technical reason to shove tags into the categories table and potentially break everything dealing with categories. Especially when you have recently broken categories and have yet to fix them to operate correctly themselves.

#34 in reply to: ↑ 27 @Otto42
17 years ago

Replying to matt:

Instead of "what ifs" what would be helpful to the discussion is "this is a specific thing that won't work if tags and categories are in the same table."

This is a specific thing that won't work if tags and categories are in the same table:

  • All plugins that use the categories table.
  • All plugins that display links.
  • All plugins that display posts.
  • About half a dozen common ways of displaying tags (clouds, search by tags, etc) become overly complicated and difficult to do, resulting in longer running queries and putting excessive and unnecessary load on the DB.

#35 follow-up: @markjaquith
17 years ago

I wasn't a fan of merging post and link categories, but a lot of the problems we had there were because of backwards compatibility needs. With tags, there is no backwards compatibility to worry about.

And I don't think that any post category or link category queries would have to change.

SELECT * FROM $wpdb->categories WHERE category_count > 0;

That wouldn't be affected by a new tag_count column.

Neither would

SELECT * FROM $wpdb->categories WHERE link_count > 0;

Because link cats and post cats are in the same table, they already have to ignore each other (or more specifically, only look for the specific type of category they want). Because they're looking for something specific and not ignoring something specific, it doesn't matter how many more x_count columns you add, the old queries should still work.

Tag clouds and more advanced tag applications I can't speak for... so if you have a specific example of a query that wouldn't work, speak up.

#36 in reply to: ↑ 35 @Otto42
17 years ago

Replying to markjaquith:

Because link cats and post cats are in the same table, they already have to ignore each other (or more specifically, only look for the specific type of category they want). Because they're looking for something specific and not ignoring something specific, it doesn't matter how many more x_count columns you add, the old queries should still work.

Except that they don't work even now. If I have no posts in a category, it shows up as a possible category for links. You can't reasonably use parent categories to organize your categories without them showing up as available links categories. The behavior is odd and inconsistent.

Here's some questions:

What would "category parent" mean with regards to a tag in the categories table? Tags don't have hierarchy in any implementation I know of.

What would happen if I removed a tag from a post? I assume you'd remove the entry from the post2tag table, and then reduce the tag_count on that tag by 1. What happens when it hits zero? Suddenly the tag shows up as a category on the posts and links screens? Okay so we remove it instead. Uh oh, now what if a category and tag have the same name? So my delete has to check the other counts before deleting.

It just overly complicates things, as I see it. I have nothing against reuse of tables for new things, but only when it makes sense.

And I like the post and link category integration, mind you. That makes sense to me. I can see interesting possibilities because of it.

But integrating with tags? Ick.

As soon as I think of a specific example, I'll post it.

#37 @majelbstoat
17 years ago

Say I want to implement a plugin that adds a template tag which outputs a link to take you to a page explaining more about what that tag means (could be Wikipedia, could be elsewhere). To do this, I'd want to add a column to the tags table 'links_to' which will store the URL associated with that tag. If the categories table is reused, all of a sudden we have yet another column that doesn't mean anything for categories and link categories. The same applies for any plugin that wants to add a column holding interesting information for a category, or a link category.

It's not so much that you can't make all these things work if it's all lumped together in one table, it's just that it makes the majority of tasks more complicated, as well as introducing unnecessary redundancy.

#38 @ryan
17 years ago

A recent idea is to not not have a separate post2tag and instead add a cat_type field to post2cat so that both cat_type=category and cat_type=tag relationships can reside in the same table. The idea is that since you would always want to get both cats and tags for a post keeping them in one table would be faster.

I'm still not sure how well combining everything into the categories table will play out when it comes to the Manage->Categories page. When deleting a category from Manage->Cats, we would have to make sure not to delete the cat if it is also a tag. If we leave the category in the table to serve exclusively as a tag, do we show it in Manage->Cats or hide it? How will someone resurrect it as a category if it is hidden? They could do so through the post and link quickadds, I suppose. Also, a category called Parent>Child is not the same as Child. A tag named Child belongs with cat? We need to be consistent about which cat the tag associates with and what happens when the cat's parent changes. The existence of Manage->Categories makes sharing the category table a bit of a pain in the ass.

#39 @majelbstoat
17 years ago

All of these questions and suggested work arounds strengthen the argument for entirely separate structures, using wp_post2tag and wp_tags. And adding a cat_type to post2cat just to force tags in doesn't seem logical because, as everyone here agrees (and I'm not saying again just to be inflammatory), tags are not a kind of category.

#40 @ryan
17 years ago

That tags are not categories is acknowledged. All proposed schemas allow for them to be used separately.

#41 @Otto42
17 years ago

Why add a column to distinguish between tags and categories in the same table, when simply creating a new table makes a heck of a lot more sense?

There seems to be an intense desire to shove a square block into a round hole here, but nobody's explaining *why* they want to do so...

#42 @ryan
17 years ago

I'm not particularly sold on the notion of a centralized taxonomy table, but here's a possible design.

Tagging a post

  • Comma separated tags are entered into a text box in the write post page.
  • write_post() parses $POSTtags? and sends an array of tags (tag names, not ids) to wp_insert_post().
  • wp_insert_post() passes tags to wp_create_tags() along with a post id.
  • wp_create_tags() passes the list of tags to wp_create_categories().
  • wp_create_categories() creates the tags in the categories table if they do not already exist and returns an array of IDs.
  • wp_create_tags() then calls wp_set_post_tags() with the array of tag IDs and the post ID.
  • wp_set_post_tags() creates relationships between the post and the tags in the post2tag table.
  • wp_set_post_tags() increments the tagged_count field for each tag.

Displaying tags for a post

  • Templates can use the_tags() and get_the_tags().
  • get_the_tags() gets all tags with a relationship to the post in the post2tag table.

Listing all tags

  • Templates can use wp_list_tags() and get_tags().
  • get_tags() retrieves all objects from the categories table with a tagged_count > 0.

Managing categories

  • The manage category list must filter out categories that are being used exclusively as a tag. (link_count != 0 or count != 0) should be included.
  • If a category that already exists as a tag is added via Manage Categories, it must be brought into the list somehow even though it does not yet have a count or link_count. A special count of -1 is used to signify unclaimed categories that should be listed.
  • When adding a new category or a category that has a tagged_count but no count or link_count, set count and link_count to -1.
  • Once the category is claimed by a post, set count to 1 and link_count to 0. Vice versa when the category is claimed by a link.
  • If an unclaimed category is claimed by a tag, set count and link_count to 0.
  • A category cannot be deleted if tagged_count is > 0. Instead, when deleting the category the count and link_count are set to zero so that the category is excluded from the category lists.
  • If the category is later re-added via Manage Categories, count and link_count are set to -1.
  • Currently, categories can have the same name and nicename if they have different parents. With multiple categories having the same name, a tag needs to somehow consistently associate with one category even if that category should be reassigned to a different parent. This association needs to be maintained so that the same tagged_count is always incremented.

Listing categories

  • get_categories() needs to be able to exclude categories with counts of -1 or 0 when fetching categories for the front page. It needs to exclude only categories with counts of 0 when fetching categories for the lists in Manage Categories and the edit post and edit link pages.

#43 @JeremyVisser
17 years ago

Ryan, unfortunately each bullet point has a separate UL element (coming from the extra linebreak after each list item in the WikiFormatting). Sorry to point that out after all that effort. ;)

#45 @johnbillion
17 years ago

Indeed, categories are not tags. They will not be used as such regardless of where they are stored.

That tags are not categories is acknowledged.

Changesets [5110] and [5111] are trainwrecks which completely go against the whole "tags are not categories" thing.

  • Why are tag permalinks the same as category permalinks?
  • Why does the proposed default theme in [5111] treat tags as categories?
  • Why are tags listed under Manage -> Categories when tags aren't categories?
  • Why does the tag archive have a title of "Archive for the 'whatever' category" when tags aren't categories?

I appreciate that this is a preliminary implementation, but can somebody please explain to me in what way these tags work differently to categories?

Is support for viewing posts by multiple tags (eg. posts tagged with x and y, like del.icio.us) planned?

#46 @Otto42
17 years ago

Hah! I like how, if you ever use a word as a tag, you can never use it as a category ever again.

Oh and this:
$tag_id = wp_create_category( $tag );

No. Tags are certainly not categories (insert rolleyes here).

#47 @ryan
17 years ago

WordPress database error: [Duplicate entry '1-1' for key 2]
INSERT INTO wp_post2cat (post_id, category_id, rel_type) VALUES ('1', '1', 'tag')

When adding a tag that is already being used as a category for that post. Perhaps a bit edge case, but I can see people wanting to use a Photography category and include Photography in the tags for a post.

#48 @ryan
17 years ago

Need to do tag=tag-slug instead of category_name=slug and use a tag.php template that falls back to category.php.

#49 @ryan
17 years ago

My database error is because I had the change from #3900. When we incorporate that, we need to either make the rel_type part of the key or prevent posts from having a tag and a cat of the same name.

#50 @ryan
17 years ago

johnbillion, all of that is to-do. Otto42, words used as tags can be used as categories. Where is this breaking for you? Tags and categories share a lot of code, but they can be applied to a post independently and used differently. Anyhow, we'll see how this works, or not. I need to implement all of my bullet points above as well as johnbillion's.

#51 @Otto42
17 years ago

ryan:
Create a new post.
Give it a category of, say, "posts".
Also give it a tag of "posts".

Look at the database: You only have one entry with a cat and tag count of 1 each. You'll also see it as an available Category in Manage->Categories.

Now edit it and remove it from the posts category. Leave the tag.

Now go to Manage->Categories. Voila, it's not there anymore. You just "deleted" the category by removing the posts from it...

Now, for extra fun, add the "posts" category via Manage->Categories.
Notice how it has a different ID? Check the database. You now have two entries of "posts".
You can repeat some of those steps over and over again to create as many fake, broken categories rows as you like.

#52 @ryan
17 years ago

Thanks for the steps to reproduce. Looks like I have a lot of bug squashing to do.

#53 @Otto42
17 years ago

Agreed, however I think the problem is more structural than that. You're mixing two things together that just don't really belong together. You've got all these count columns in there and are trying to keep them all separate that way, and that just seems like a bad hack to me.

Not criticizing, just saying. It just seems like a heck of a long way to go to avoid joining a few extra tables here and there.

#54 follow-up: @ryan
17 years ago

Having a single table for taxonomoy is nice for slurping all taxonomy for a post in one go. In many applications the differences between a tag and a category don't matter. They are both taxonomical meta-data. The global tag pools on wordpress.com won't care between the two, for example. Categories are already being used as tags there. Technorati et al won't care either. The global taxonomy approach does make keeping Manage->Categories straight more difficult, however. I would love to simply axe Manage->Categories and do everything on the fly via the edit post and edit link pages, but I can imagine the revolt. ;-) Perhaps we could add a type bitfield to the categories table so that we can avoid some of the gymnastics with the counts. If a category object is marked as a category in the type field, it would be displayed in the manage cats list. If a category belongs to no posts or links, it would still be listed until it is deleted via Manage Cats. Deleting would consist of masking out the category bits in the type bitfield or completely deleting if the bitfield is empty. Either consulting or ignoring the type bitfield would yield a separated or merged taxonomy, as desired.

#55 in reply to: ↑ 54 @Otto42
17 years ago

Replying to ryan:

Perhaps we could add a type bitfield to the categories table so that we can avoid some of the gymnastics with the counts. If a category object is marked as a category in the type field, it would be displayed in the manage cats list. If a category belongs to no posts or links, it would still be listed until it is deleted via Manage Cats. Deleting would consist of masking out the category bits in the type bitfield or completely deleting if the bitfield is empty.

What do these crazy gymnastics gain you though? I mean, you've got a list of words here which can be categories or tags. So you put in a flag to say which they are, or maybe they can be both. Fine. Brilliant. But how is this any better than two tables: one for tags, and one for categories? I mean, you've got one table with a flag to say whether an entry is on one side of the fence or the other (or both). It's just really, really silly and violates virtually all relational database principles.

Sure, you can treat categories as tags if you like. Yes, a lot of services do that. But that's a nasty hack to begin with, and the only reason they do that is that tags were not in the Wordpress core when they started looking for them. If you're adding tags to the core, then treating categories as tags should be *removed*. Categories should not have rel="tag" on them, IMO. They are not tags. Which is sorta my whole point, I guess.

Now, I would support eliminating categories entirely in favor of tags (as tags are more useful, IMO), but you're right, the outcry would be tremendous. But this half-way solution is worse than any possible alternative as I see it. It over complicates things for absolutely no benefit.

Either consulting or ignoring the type bitfield would yield a separated or merged taxonomy, as desired.

SQL has this nifty thing called a JOIN. Depending on what tables you joined, you could get a separated or merged taxonomy, as desired. ;)

#56 @majelbstoat
17 years ago

Unfortunately, it doesn't look like there's much point in arguing about this anymore, despite the clear flaws in the design. There's no way all those recent commits are going to be reverted. Take a look at [5149] for instance:

+		if ( '' != $q['tag'] ) {
+			$reqcat= get_category_by_slug( $q['tag'] );

It looks very much like it's just been copied and pasted from the categories code. Very disappointing. I'm half-minded to change this ticket type to defect.

#57 @ryan
17 years ago

I'm not too keen on this approach either. I can see the reasons for going this route though. Creating new tables and API for the taxonomy du jour (how many different flavors are there now) can get old, and doing extra queries for what is just more bits of taxonomy is a bit lame. But, as we can see, the code gets messy compared to just creating a separate API and table. I don't care enough either way though. I'd probably rather not have two taxonomy systems. I already use cats and tags and think those who need both are a little obsessive compulsive with their labeling. ;-)

#58 @filosofo
17 years ago

I already opened a ticket for this, but I'd like to point out here that at least two of the new tagging functions clash with bbPress tagging functions, which makes bbPress integration--so smooth in recent months--break down.

@ryan
17 years ago

Add category type field and use it instead of -1 counts

#59 @ryan
17 years ago

(In [5184]) Bit twiddling. Add type bitfield to categories table. see #3723

#60 @ryan
17 years ago

(In [5232]) Add get_tags(). See #3723

#61 @ryan
17 years ago

(In [5243]) Allow passing an empty tag set to wp_set_post_tags() so all tags can be removed from a post. see #3723

#62 follow-up: @ryan
17 years ago

(In [5271]) tag_exists(), category_object_exists(), and some tag and cat create fix ups. see #3723

#63 in reply to: ↑ 62 @youngmicroserf
17 years ago

I just read in the timeline that tagging will be moved to WP 2.3. If that is so, and some of the considerations in this thread are the reason for this decision, I would like to recommend to have a look at the recently published "simple tagging" plugin by Michael Wöhrer (http://sw-guide.de/wordpress/plugins/simple-tagging/), which is now being maintained here (http://trac.herewithme.fr/project/simpletagging/). Thanks.

#64 @rob1n
17 years ago

  • Milestone changed from 2.2 to 2.3

Tags are bumped to 2.3.

Also, we should split this into separate tasks, says Matt. Agreed.

#65 @foolswisdom
17 years ago

  • Version 2.1 deleted

#66 @ryan
17 years ago

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.