As I mentioned back in
Tag filtering, anyone? I have solved the issue I found on my
blog with posts not being included when using the tag filtered
navigation. Tags were being correctly counted on the
navigation (shown right), but if you clicked on one of these links,
only some of the appropriate posts would show up.
I should start with a little more background in case you haven't
been following PardonMyReach. I'm using Umbraco 4.5.2 and the
blog4Umbraco package. I had a really easy time getting
Umbraco setup and the blog4Umbraco package installed, but there
were a number of minor issues that I discovered with my new blog as
I started using it, the aforementioned tag filtering issue being
one of them. Most of the time, I use Live Writer to create my
posts. I noticed that the blog posts that I was posting using
Live Writer weren't included when I used the tag filtering
navigation.
So one workaround (which I later found mentioned on some of the
forums) would be to open each post in the Umbraco back office
website for my blog and save it, which seemed to correct the issue,
or simply to use the back office to create my posts in the first
place. Neither of these options was particularly appealing,
so I kept looking into it.
In examining the database where my
content is stored, I found a table suspiciously named
cmsContentXML. Each row has two fields, intuitively named
nodeId and XML. In looking at the XML, I noticed a difference
in the XML between posts. Shown right are two such
examples. (Yes, I am lazy and just did a little image capture
- someday I'll get around to writing a style for displaying code
clearly in the blog.) You'll notice that the <tags>
element is actually empty (at least for all intents and purposes)
on the second post. Sure enough, when I filtered based on the
appropriate tag, the second post was omitted. Ah ha!
So for some reason, the tags weren't getting saved in the
content xml in the DB when I posted using Live Writer, but the
count of posts by tag were actually correctly displayed. I
also noticed in the DB that there are two other tables, cmsTags and
cmsTagRelationship. cmsTags is a mapping of tag ids to
tags. cmsTagRelationship is a mapping of content nodes to
tags. And this table was correct. Just to see if this
issue was likely an issue with the blog package or Umbraco, I
created a new document type with a tag property and tried creating
some content with the back office and with Live Writer and found
the same result. So I concluded the issue is actually in
Umbraco and not the blog4Umbraco package. I spent a little
time looking through the Umbraco source, but the issue wasn't
obvious to me and I wasn't really all that excited about patching
the CMS, so I turned my attention to trying to work around the
issue in the blog4Umbraco code. (It's also possible that this
is deprecated functionality and the tag relationship should be
determined from the tags library instead of the content node, but
this seems a little inconsistent with the other properties).
After looking at the code, I decided the easiest thing to do
would be to fix up the content node. So I looked at creating
an event handler. In blog4Umbraco, there are already several
defined, so I opened up BlogDateFolder.cs and added an event
handler of my own:

(Sorry again about the formatting on this - I guess I'll have to
look into displaying code more clearly. Actually, I tried to
post this as code wrapped in a <pre> tag, but it caused an
error. More issues to look at…)
As you can see, I found that the
umbraco.editorControls.tags.library.GetTagsFromNodeAsITags() method
correctly returns the tags associated with a node. So I
created a BeforePublish event handler and wired it up in the
constructor of BlogDateFolder. The method
Document_BeforePublish_Tag does the real work. In this
method, I simply get a list of tags using GetTagsFromNodeAsITags(),
create a comma delimited string of tags from this list, and reset
the empty tagProperty.Value to the string I create.
I liked the idea of making this a BeforePublish event handler
since it both fixes new posts from here on forward and also allows
me to fix the existing posts simply by republishing my content
tree.
I could probably clean this up quite a bit. Firstly, I
should probably use a string builder for better performance.
And I could also check to see if the tags need fixing in the first
place. I could also pull this out of blog4Umbraco and create
a separate package that would allow a user to configure which
ContentTypes to fix (in case they have more than just BlogPost that
they care about).