tisdag 21 juni 2011

Different CQWP rendering behavior when upgrading to SP2010

In the past I started to love and hate the Content Query Web Part since you can use it with audience targeting. In the MOSS days you had a very good control of what was happening and what to render. A rather annoying behavior though was that - even in rather normal situations - the query didn't give you the result you wanted.

My customer wanted to render an audience filtered calendar that showed the upcoming 7 events from [Now] and beyond, not [Today] and beyond. Since there is no such thing as <Now/> that you can use in a caml query, I used <Today/>, increased the row limit and in the item style (ItemStyle.xsl) filtered out the items not matching the rules. But sometimes I still didn't get the 7 events I wanted. I found out that the audiene filtering is not included in the query, but is made on the result of the query. So if I requested 20 items, the audience filtering maybe took away 15 items and the rendering rules in the xsl maybe took away 2. So instead of the expected 7 items I got 3.

The only simple solution to solve this was to increase the row limit even more and it worked fine.

But now the behaviour of the rendering is quite different. In theold days the result was rendered as a <table> but now it's a <ul><li> thing. Better HTML, but it has issues. When you render a table row with only empty cells it doesn't show anything. but an empty <li> in a <ul> renders an empty row. So when I filter out an item in the item style it still renders an empty row since the <li> tag is rendered in ContentQueryMain.xsl.
My solution to this was to set the style attribute in the <li> to display:none;. And how to do that? First the <li> tag must be rendered as a tag, not as a text string that is the case in the default ContentQueryMain.xsl (the $BeginListItem variable). In the OuterTemplate.CallItemTemplate I rendered an <li class="dfwp-item"> tag instead of <xsl:value-of disable-output-escaping="yes" select="$BeginListItem" /> so that the last rendered tag is a fully qualified xml-tag. In my item style, if the item doesn't match the rules, I set the attribute of thea fully qualified xml-tag. In my item style, if the item doesn't match the rules, I set the style attribute of the last rendered xml-tag (i.e. the <li>-tag) with <xsl:attribute name="style">display:none;</xsl:attribute>.

Works beautifully!

Audience targeting failing after upgrade to SharePoint 2010 pt2

In the former post I described an issue that can arise when upgrading MOSS to SP2010 concerning audience targeting. The solution in most cases turns out to be to change the name attribute in fields from Target_x0020_Audiences to Audience. In som cases that will not work. For uncustomized list schemas containing items, the new field named Audience is actually just added to the list instance.

That will of course result in major issues since there are two fields in the list with the same id but with different names. When opening an item in such a list, the aspx-form will crash. My only solution to this was to make  create a temporary list based on the same template (where the audience field has the correct name), copy all items from the original list, delete the original list and create a new one with the same name, copy the items back and delete the temporary list.

The issue here being that all references to the original list will be lost, like List View Web Parts or CQWPs pointed to that specific list.

I went for this solution because time became critical and the customer accepted to make the manual patches.