Fix ONET.XML and win a prize!

Cheap huh? Okay after yesterdays ObjectMother fiasco I think I've calmed down now. Thanks to those who posted the comments and information. I always find it hard to get good examples of unit testing out there and it's always hard to know what to test. All the TDD examples I've seen are so simple and the some of the examples you can find are usually large frameworks that are generally testing infrastructure. There doesn't seem to be a good set of samples out there that actually tests business objects.

Anyways, back to SharePoint and how I adore ONET.XML and all it's happiness. Here's a simple challenge for someone with more Xml skills than I do (which isn't saying much).

We all know (or should know) we can embed Web Parts on a page and automagically have them populate the pages when a site is created using the <AllUsersWebPart> tag in the </Project/Modules/Module/File> section of ONET.XML. The contents of this tag is essentially the DWP you would see from an exported Web Part. Take any Web Part, export, copy and paste into ONET.XML and Bob's your uncle. For the Content Editor Web part, this Xml fragment is surrounded by a CDATA tag. Okay, everyone's on the same page so far. Good.

The challenge is that when you export the Content Editor Web Part it embeds a second CDATA tag for the actual HTML content you created. The problem is that the result in ONET.XML isn't valid Xml and when the site gets created an error is thrown. Here's the Xml that causes problems:

<AllUsersWebPart WebPartZoneID="PageTitle" WebPartOrder="1"><![CDATA[<WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/WebPart/v2">
<Title>My Title</Title>
<FrameType>None</FrameType>
<Description>Use for formatted text, tables, and images.</Description>
<ZoneID>MyZone</ZoneID>
<Assembly>Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
<ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[<div class="ms-pagetitle">My Text Here</div>]]></Content
>
</
WebPart>]]></AllUsersWebPart>

The problem occurs after the content (My Text Here) and the "]]". SharePoint (and any Xml editor) thinks this is closing off the first CDATA that was created up at the beginning of the <AllUsersWebPart> tag.

So what should be the fix? Post your answer in the comments and I'll verify it later today. Winner gets a free copy of Enterprise Integration Solutions by Devin Spackman and Mark Speaker.

Update: We have a winner! Jim Duncan was the first to point out to remove the embedded CDATA tag and encode the HTML within the <Content> tags. Here's the corrected Content Editor Web Part that you can embed in an ONET.XML file:

<AllUsersWebPart WebPartZoneID="PageTitle" WebPartOrder="1"><![CDATA[<WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/WebPart/v2">
<Title>My Title</Title>
<FrameType>None</FrameType>
<Description>Use for formatted text, tables, and images.</Description>
<ZoneID>MyZone</ZoneID>
<Assembly>Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart</TypeName>
<ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><&lt;div class="ms-pagetitle"&gt;My Text Here&lt;/div&gt;</Content
>
</
WebPart>]]></AllUsersWebPart>

Published Tuesday, March 29, 2005 6:47 AM by Bil Simser
Filed under:

Comments

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 9:11 AM by Colin Walker
Does this help?

http://msdn.microsoft.com/library/en-us/odc_SP2003_ta/html/ODC_SPSCustomizingSharePointSites2.asp?frame=true#odc_spscustomizingsharepointsites2_usingmodules

specifically:
"Note HTML definitions do not allow for nested <CDATA> tags. However to work around this, you can remove the inner tag and use HtmlEncode on its content"

I'm not actually after the prize but just stumbled across this anyway.

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 9:26 AM by Colin Walker
Alternatively just escape the internal [[ ]] with &#91; and &#93;

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 11:26 AM by Ivaylo
Split the outer CDATA into two: at the inner occurence of ]]>:

<![CDATA[
...
]]]><![CDATA[]>
...
]]>

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 11:43 AM by Bil Simser
Colin,

The MSDN document is nice but doesn't say how to use HtmlEncode on the content inside ONET.XML. Also you cannot escape the internal [[]] signs as SharePoint says it's misformed Xml.

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 11:44 AM by Bil Simser
Ivaylo,

While this is valid in XmlSpy, SharePoint doesn't like it so that's a no-go.

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 12:32 PM by Jim Duncan
To follow up on Colin's comment, you might try this (though I haven't):

<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">[%=Microsoft.SharePoint.Utilities.SPEncode.HtmlEncode('<div class="ms-pagetitle">My Text Here</div>')%]</Content>

I would be interested to know if that works (and will likely try it out later).

A way I've found to make this work is to put the content in a seperate .htm file and set the ContentLink element (Leaving the <Content> empty).

Of course, you must also then include the .htm file in a <File> element inside the <Module>




# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 2:01 PM by Bil Simser
Hi Jim,

The %=Microsoft.SharePoint.Utilities option didn't work either. I will try the content link, but that's a real pain as it now means I have to have 1 web page with a single line of text in it just to print out something on each page that includes this Web Part. I'd rather just write a custom Web Part for this with a property then.

Thanks.

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 2:58 PM by Jim Duncan
Hmm.

I wonder if they mean you just need to HtmlEncode the content yourself:
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">&lt;div class="ms-pagetitle"&gt;My Text Here&lt;/div&gt;</Content>

or maybe even:
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">&amp;lt;div class="ms-pagetitle"&amp;gt;My Text Here&amp;lt;/div&amp;gt;</Content>

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 3:13 PM by Bil Simser
Aha. We have a winner! That did it Jim (the first option). At least it clarifies how you can accomplish it. Please email me your address info so I can send the book off.

# re: Fix ONET.XML and win a prize!

Tuesday, March 29, 2005 6:42 PM by Jim Duncan
Glad it worked (don't know why I never tried that myself).

Address on the way...

# re: Fix ONET.XML and win a prize!

Wednesday, March 30, 2005 2:24 AM by Cyriel
Actually there is still a small bug in Jim's solution published in this post:

<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><&lt;div class="ms-pagetitle"&gt;My Text Here&lt;/div&gt;</Content>

That left angle bracket before the 1st &lt; isn't supposed to be there.

Corrected markup (for your cut and paste pleasure):

<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">&lt;div class="ms-pagetitle"&gt;My Text Here&lt;/div&gt;</Content>

# re: Fix ONET.XML and win a prize!

Thursday, April 21, 2005 6:34 PM by Jack
Thank you guys for your work. I have searched all over for the answer to this. You guys are lifesavers.