I want to add a page to my site definition which is hidden ie. doesn't appear in the navigation, by default.
The page is provisioned in the onet.xml file as follows;
<File Url="SomePage.aspx" Type="GhostableInLibrary" Path="default.aspx">
<Property Name="Hidden" Value="TRUE" />
<Property Name="Title" Value="Some Page" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype_welcomepage_name;" />
<Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/pagelayouts/mypagelayout.aspx, My Page Layout" />
</File>
As you can see I have tried setting a property of Hidden but this seems to have no effect. Is there any way to set the page to be created in the site but not shown int he navigation. I have relatively limited experience with site definitions so am probably approaching it wrong?
UPDATE: I decided to approach this a different way and "simply" hide the navigation item in a feature event receiver run when the site is provisioned. However this turns out to be far from simple.
At first I tried to access the Navigation of the SPWeb
((SPWeb)properties.Feature.Parent).Navigation.TopNavigationBar;
But this is a null reference. So I created a PublishingWeb from the web and looked in there
PublishingWeb pw = PublishingWeb.GetPublishingWeb((SPWeb)properties.Feature.Parent);
pw.Navigation.GlobalNavigationNodes;
But this is also a null reference. Some searching on Google turned up this article - http://blog.mastykarz.nl/programmatically-configuring-menu-items-sharepoint-2010/ - which explains that the navigation is not populated until it is first updated through the UI and provides a fairly low level powershell solution to populate this navigation by creating a fake SPContext, grabbing a PortalSiteMapProvider and getting the navigation from there. I rewrote this into my feature receiver and have code looking like this:
SPWeb web = (SPWeb) properties.Feature.Parent;
PublishingWeb pw = PublishingWeb.GetPublishingWeb((SPWeb)properties.Feature.Parent);
HttpRequest request = new HttpRequest("", web.Url, "");
StringWriter sw = new StringWriter();
HttpResponse response = new HttpResponse(sw);
HttpContext.Current = new HttpContext(request, response);
SPControl.SetContextWeb(HttpContext.Current, web);
ProviderSettings ps = new ProviderSettings("CombinedNavSiteMapProvider", "Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
ps.Parameters["NavigationType"] = "Combined";
ps.Parameters["EncodeOutput"] = "true";
PortalSiteMapProvider psmp = (PortalSiteMapProvider) ProvidersHelper.InstantiateProvider(ps, typeof(Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider));
PortalSiteMapNode current = (PortalSiteMapNode) psmp.CurrentNode;
SiteMapNodeCollection nodes = current.GetNavigationChildren(NodeTypes.Default, NodeTypes.Default, OrderingMethod.Manual, AutomaticSortingMethod.Title, true, -1);
Alas the nodes collection is empty. I have tried using the GlobalNavSiteMapProvider and the CombinedNavSiteMapProvider with the same results. However when the receiver finishes the site does indeed have navigation items.
This seems like such a basic requirement that nearly every SharePoint development would need; some deployable control of navigation.
Is this really the way we are supposed to do this? Is there not a simple solution? And if it is the recommended way does anybody know why the nodes collections are always empty for me?