MOSS 2007 Publishing web site definition template – onet.xml – syntax for properties and getting the right content types

The documentation for creating site definitions and provisioning for MOSS 2007 Publishing sites is almost non-existing on MSDN.

My first suggestion is to look at the out of the box publishing site definition “BLANKINTERNET”.
This site definition is located in the 12 hive: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\BLANKINTERNET
The template configuration for this site definition can be found in the file: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML\webtempsps.xml. Note that only the part in the element <Template Name="BLANKINTERNET" ID="53">... is applicable.

I will post a more complete article on how to create your own publishing site definition with custom page layouts, master pages and content types later when I have more time... For now I’ll just go over the elements on which I had most work getting them to work. It’s actually not quite hard as long as you know how to do it.

1. Make sure the required onet.xml and webtemp*.xml files are copied to the right directories

Your onet.xml file should go into the folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\[YOURSITEDEF]\XML
Provisioned files may go one level higher: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\[YOURSITEDEF]

webtemp*.xml file should go into: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML

2. onet.xml: referencing the correct site features

In order to get the publishing site features activated when you create a site based on your custom site template, make sure all required publishing site and web features are activated. Features at site level are defined and activated at the site collection level. Web features will be activated for every new web you create using this configuration.

... <!-- part ommitted for clarity -->
<
Configurations>
<
Configuration ID="-1" Name="NewWeb"/>

<Configuration ID="0" Name="[YOURSITEDEF]">

<SiteFeatures>

<!-- Workflow Features -->
<!--
Workflow Expiration -->

<Feature ID="C85E5759-F323-4EFB-B548-443D2216EFB5" />

<!-- Workflow Review -->
<
Feature ID="02464C6A-9D07-4F30-BA04-E9035CF54392" />

<!-- Workflow Signature -->
<
Feature ID="6C09612B-46AF-4B2F-8DFC-59185C962A29" />

<!-- Workflow Translation -->
<
Feature ID="C6561405-EA03-40A9-A57F-F25472942A22" />

<Feature ID="A392DA98-270B-4e85-9769-04C0FDE267AA">

<!-- PublishingPrerequisites -->

</Feature>

<Feature ID="7C637B23-06C4-472d-9A9A-7C175762C5C4">

<!-- ViewFormPagesLockDown -->

</Feature>

<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">

<!-- PublishingResources -->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<
Property Key="AllowRss" Value="false"/>
<
Property Key="SimplePublishing" Value="false" />
</
Properties>

</Feature>

<Feature ID="F6924D36-2FA8-4f0b-B16D-06B7250180FA">

<!-- Office SharePoint Server Publishing -->

</Feature>

</SiteFeatures>

<WebFeatures>

<!-- Include the common WSSListTemplateFeatures used by CMS -->

<Feature ID="00BFEA71-DE22-43B2-A848-C05709900100" > </Feature>

<Feature ID="00BFEA71-E717-4E80-AA17-D0C71B360101" > </Feature>

<Feature ID="00BFEA71-52D4-45B3-B544-B1C71B620109" > </Feature>

<Feature ID="00BFEA71-A83E-497E-9BA0-7A5C597D0107" > </Feature>

<Feature ID="00BFEA71-4EA5-48D4-A4AD-305CF7030140" > </Feature>

<Feature ID="22A9EF51-737B-4ff2-9346-694633FE4416">

<!-- Publishing -->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<
Property Key="ChromeMasterUrl" Value="~SiteCollection/_catalogs/masterpage/mymasterpage.master"/>
<
Property Key="WelcomePageUrl" Value="$Resources:cmscore,List_Pages_UrlName;/default.aspx"/>
<
Property Key="PagesListUrl" Value=""/>
<
Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1"/>
<
Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/mypagelayout.aspx"/>
<
Property Key="AlternateCssUrl" Value="" />
<
Property Key="SimplePublishing" Value="false" />

</Properties>

</Feature>

<Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">

<!-- Per-Web Portal Navigation Properties-->

<Properties xmlns="http://schemas.microsoft.com/sharepoint/">

<Property Key="InheritGlobalNavigation" Value="true"/>

<Property Key="IncludeSubSites" Value="true"/>

</Properties>

</Feature>

<Feature ID="94C94CA6-B32F-4da9-A9E3-1F3D343D7ECB">

<!-- Office SharePoint Server Publishing -->

</Feature>

</WebFeatures>

<!-- remaining elements ommitted -->

</Configuration>

3. The right syntax for AvailablePageLayouts and AvailableWebTemplates

The Publishing Web Feature (ID 22A9EF51-737B-4ff2-9346-694633FE4416) contains some properties that allow us to specify master pages, page layouts and available web templates.

The syntax for specifying the values in the onet.xml file is not documented (as far as I could find).

AvailablePageLayouts

Your custom page layout should be deployed to the site collection by activating a page layout provision feature for example.

For a single page layout, the syntax is available in the BLANKINTERNET site definition:

<Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/mypagelayout.aspx"/>

For defining multiple AvailablePageLayouts I found that the separator is : (colon) by looking at the Search site definition (SRCHCEN):

<Property Key="AvailablePageLayouts" Value="~SiteCollection/_catalogs/masterpage/
mypagelayout.aspx:~SiteCollection/_catalogs/masterpage/mypagelayout2.aspx
"/>

AvailableWebTemplates

If you want to restrict the list of available web templates you can do this with the AvailableWebTemplates property.

<Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1"/>

For specifying multiple web templates, I found the syntax thanks to a post in a forum: http://www.eggheadcafe.com/software/aspnet/29217247/availablewebtemplates-key.aspx

Someone found the syntax by looking at the Microsoft.SharePoint.Publishing.PublishingWeb class using reflector. Snippet from the solution mentioned in the forum:

AvailableWebTemplates Key Format is:
LCID-[sitetemplatename][#sitetemplatenumber];LCID-[sitetemplatename]
[#sitetemplatenumber];LCID-[sitetemplatename][#sitetemplatenumber]

1033-BLANKINTERNET#1;1049- BLANKINTERNET #1;*- BLANKINTERNET #2

*-BLANKINTERNET#2 - ALL Languages
(Thanks Sorgi?)

So if we know the separator is ; (semi-colon) the element should look like:

<Property Key="AvailableWebTemplates" Value="*-MYSITEDEF#1;*-MYSITEDEF#3"/>

Please see the Microsoft.SharePoint.Publishing.PublishingWeb class reference on MSDN: http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishingweb.aspx. Looking at the class properties will also give you more insight into how to use the properties in the onet.xml file.

4. Using multiple configuration and hiding them in the UI

The webtemp*.xml file may contain multiple template configurations. You may make some of these hidden for example if you want to create those specific sites via code only. Use for Hidden="TRUE" this.

webtemp*.xml snippet:

<!-- ... snippet:-->

<Template Name="MYSITEDEF" ID="10020">

<Configuration ID="0" Title="My site template" Hidden="FALSE" ImageUrl="/_layouts/1033/images/img.gif" Description="This is a publishing site template" SubWebOnly="FALSE" DisplayCategory="My own category">

</Configuration>

<Configuration ID="1" Title="My site template – Autocreated contact section" Hidden="TRUE" ImageUrl="/_layouts/1033/images/img.gif" Description="This template is used by code to generate the contact site." SubWebOnly="TRUE" DisplayCategory=" My own category" VisibilityFeatureDependency="97B7C2D9-51E6-4add-844E-D133D25B7B15">

</Configuration>

<!-- ... snippet end-->

5. Making your own content types available

When you use custom page layouts chances are you are also using custom content types. By using the AvailablePageLayouts properties your custom page layouts become available but there is still a problem. By default the Pages library only contains the MOSS publishing content types, as you can see in this screenshot:

Users will be available to create new pages using your page layout but all the custom properties you use in their related content types are missing. The page layout may not show any property in edit mode. If you go the Site Settings > Site content types, you will see your custom content types and their site columns.
You may manually add the content types to the Pages library by going to Site Actions > Site Settings > Modify Pages Library Settings. Choose “Add from existing site content types” and choose the content types. Once this is done your custom page layouts should start working normally.
Doing the manual setting is one possibility but having to do this manually for every new web is not really an option.
I ended up creating a web feature that is automatically activated by the site template definition. My feature contains a ReceiverAssembly and class in which I add the desired content types to the Pages library.

Code snippet:

string pageLib = Microsoft.SharePoint.Publishing.PublishingWeb.GetPagesListName(web);

SPContentTypeCollection allContentTypes = web.Site.RootWeb.AvailableContentTypes;

SPContentTypeCollection usedContentTypes = web.Lists[pageLib].ContentTypes;

foreach (SPContentType contentType in allContentTypes)

{

if (contentType.Hidden==false && contentType.Group.ToLower().StartsWith("Mygroupname ") == true)

//if the content type does not yet exist in the library add it:

{

if (usedContentTypes[contentType.Name] == null)

{

web.Lists[pageLib].ContentTypes.Add(contentType);

}

}

}

That’s it for me!

 

Feedback

Posted on 18 May 2007 @ 16:16

Hi, Katrien!

This was a very useful posting for me, so I think it's only fair I give something back ;-)

There is a way to make your own content types available without code - by using content type binding. So, what you do is create a feature like this (I removed <> to get it through to you):

Feature
xmlns="http://schemas.microsoft.com/sharepoint/"
Id="...guid..."
Title="Content Type Binding Feature"
Description=""
Scope="Web"
Hidden="FALSE"
Version="1.0.0.0"

ElementManifests
ElementManifest Location="ContentTypeBinding.xml" /
/ElementManifests
/Feature

And a ContentTypeBinding.xml file that contains this:

Elements xmlns="http://schemas.microsoft.com/sharepoint/"
ContentTypeBinding ContentTypeId="...YourId1..." ListUrl="Pages" /
ContentTypeBinding ContentTypeId="...YourId2..." ListUrl="Pages" /
Elements

Feel free to drop me a line if this wasn't clear.

Frank

Posted on 22 May 2007 @ 15:59

Thanks!!!

great post!

Posted on 28 May 2007 @ 11:36

Hi Frank,
Thanks for your post. I like your solution a lot and will probably try that next time!

Regards,
Katrien

Posted on 02 October 2007 @ 10:09

I have tried out Frank's Content Type Binding Feature and it works like a charm!

Nice and simple and thanks to ContentTypeBinding Features I can now set a custom site definition for a Web to use MY page layout with a custom content type.

When adding the Feature ID to a WebFeatures node in onet.xml make sure to add the Feature ID reference AFTER the features which create the Publishing Pages Library, otherwise you get an error, must be a dependency issue, you can't bind a content type to a list that doesn't exist yet.

Posted on 24 October 2007 @ 07:39

i am trying to deploy custom page layouts in site definition as per your article. for each pagelayout i have to mentioned associated content type and content type id. How can i get the content type id while deploying.Basically i want to deploy the site definition with custom page layouts in another server. in this case content type id will vary from server to server. how to handle this issue....Kris

Posted on 29 October 2007 @ 18:56

Hi Kris,
Sorry for the late reply, I was away last week.

If you are creating your content types (and their IDs) using a feature then these do not change from one server to another.
Unless you are creating content types via the MOSS interface?

Katrien

Posted on 01 November 2007 @ 14:33

Works like a charm, thanks a lot! :)

Posted on 10 January 2008 @ 17:56

Following the steps outlined in your article, I created my custom publishing site definition with a cutom master page. When I create the site, however, I get this error: The specified ChromeMasterUrl
'~SiteCollection/_catalogs/masterpage/PublishingMasterPage.master' must be a server-relative url within site collection '/sites/sdfs'.

What does this mean and how do I fix this?

Thanks for any help/suggestion.

Posted on 10 January 2008 @ 19:00

Peter,
I'm assuming 'PublishingMasterPage.master' is the name of your custom publishing page layout?
You need to make sure this layout is already activated by calling the feature that install your custom page layout in the section SiteFeatures of the onet file.

Or maybe I'm wrong, can you let me know to what the 'PublishingMasterPage.master' corresponds?

Katrien

Posted on 10 January 2008 @ 19:30

Thanks Karen,

Publishingmasterpage .master is a minimal master page I found in Heather Solomon's site. I only changed this line in the onet.xml file "Property Key=ChromeMasterUrl Value=~SiteCollection/_catalogs/masterpage/mymasterpage.master "
and left the pagelayout property unchanged.

Posted on 10 January 2008 @ 19:53

Sorry my mistake, I meant master page (and wrote page layout).

How do you install this minimal master page? Did you create a feature?

The master page must be installed in order for it to be available to the site definition. You might want to check out my other post about creating custom page layouts using features (http://katriendg.com/aboutdotnet/2007-6-moss-2007-publishing-page-layout.aspx). The same approach applies to install custom master pages.

Posted on 10 January 2008 @ 21:47

Thanks Katrien,

I'll create a feature to do this. I don't need to include that feature in the onet.xml file, correct?

Peter

Posted on 10 January 2008 @ 21:50

Peter,
You should indicate your feature in the referred SiteFeatures section of the one.xml. In this way the feature that installs the custom master page will automatically be activated when the site is created.

The feature itself should have a scope set to 'Site' and be installed upfront.

Hope that does it!
Katrien

Posted on 10 January 2008 @ 22:51

Katrien,

It worked. You're awesome. I've been pulling my hair with this one for almost a month now. Finally, I've seen the light!

Thank you.

Peter

Posted on 28 March 2008 @ 17:05

Hi Katrien,

I was wondering if you had any tips on adding a preconfigured content query web part to the onet file? I have exported the CQWP as a xml file, but now I am unsure where to place it in the onet.xml

Thanks!

Doug

Posted on 29 March 2008 @ 16:12

Hi Doug,

This is certainly possible, you should be able to setup your required default settings on an existing site and then choose "Export" for the web part.
The correct place to put that is by using a custom Module element. In the Module element you can then insert a AllUsersWebPart element.
See the Modules and Module elements in this SDK documentation for an example: http://www.usingsharepoint.com/SharePointSDK/tscamlovONET_SV01084510.htm

Hope this gives you an idea on how to configure the onet.xml.

Katrien

Posted on 24 June 2008 @ 06:27

Hey Katrien,

It was a nice post.

Thanks!

Posted on 04 July 2008 @ 15:22

Hi Katrien,

Thanks for your help above. I have another related question..

I have deployed my custom templates in a solution and have released an upgrade with a new template in it. This template is available in the Site Actions >> Create Site section, but is only appearing as an option in sites created after the solution was redeployed (I am controlling what site templates may be selected as sub sites in the onet file with the AvailableWebTemplates property).

Is there a way of making the template available to existing sites, so in a way refer back to the new template model?

I guess on site creation the template is checked, the site is created and any changes made to the template after the fact are not picked up on by existing sites.

Thanks again! Doug

Posted on 18 July 2008 @ 21:44

Hi Doug,
There is a way of enable or add functionality to existing sites (after they have been generated). This is called feature stapling. I found one post that might help you in the right direction: http://blogs.msdn.com/cjohnson/archive/2006/11/01/feature-stapling-in-wss-v3.aspx

Hope this helps,
Katrien

Posted on 10 December 2008 @ 12:49

Hi,

When you pick a "Publishing portal" template, you actually select
< Template Name="BLANKINTERNETCONTAINER" ID="52" >. Then the provisioning goes through \12\TEMPLATE\xml\InternetBlank.xml back to < Template Name="BLANKINTERNET" ID="53" > definition. I'm just mentioning it because it took me some time to figure this out. I based my template just on the BLANKINTERNETCONTAINER and got into some weird errors durring provisioning.

Regards,
Greg

Posted on 11 December 2008 @ 11:24

Thank you for the nice and useful post regarding ONET.XML and publishing.

I was wondering is it possible to embedd the name of the Mail Server Address, inside the ONET.XML file, i.e (in the Calendar webpart-code in ONET.XML)?

Ideally, I would like to be able to display email,calendar etc., for any user, when they log onto 'MySite', without the need for the user having to enter any server details etc.
Is this possible to achieve, using an entry referencing the mail server, inside the ONET.XML file?

Regards,

Dan

Posted on 12 December 2008 @ 19:16

Hi Dan,
I would think the ONET.XML is not the right place to store this information. When you create a site definition you really want to be able to reuse this on several servers with different settings. Normally this type of information is stored in web.config or some custom config settings in a new list.

Cheers,
Katrien

Posted on 30 January 2009 @ 11:06

Hi,

Sites Created Using this Tmeplate will support variation and variation workflow?

Posted on 02 November 2009 @ 18:00

Thanks.... did you ever create a more complete article on how to create your own publishing site definition with custom page layouts, master pages and content types? I would love to see it if you did.

Thanks

Posted on 21 January 2010 @ 01:47

I have a question. I am creating a site definition and I need annonymous access. after creating the site unfortunately the annonymous access is not working and users are redirected to the login.aspx while I need users have access to the whole site. I checked permissions and the permission shows that it is inherited and the root site annonymous access is configured to all web. When I remove the site again it works! When I try microsoft publishing site it works perfectly. but my custom site def is not working at all. I copied all the features I thought there might be something in features but it is not the issue. The issue should be something that microsoft is setting when the publishing site is created. Is there anyone out there know anything about it?

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Copyright © 2007 Katrien De Graeve.