I have successfully created a web template as a farm solution on a SharePoint 2013 on premises farm and can use it to deploy site collections as well as subsites.
In the web template I have used a copy of the teamsite onet.xml and have added all the standard teamsite features including ones that would normally be stapled to the site feature and web feature sections.
I have removed any lists / libraries from being provisioned in the onet.xml.
I have created 2 web scoped features. The first one provisions a set of libraries programmatically.
The second one, which is also the last web feature in the onet.xml is supposed to delete all entries from the quick launch then add back in my custom entries.
When I run this feature in an existing site it does what it is supposed to.
When it runs as part of the site creation process it adds my quick launch entries but there seem to be other ones that are added in by SharePoint afterwards.
I am wondering if either my 'clearing' of the quicklaunch is failing inside the site creation process or if certain items are added to the quicklaunch after web features in a web template ?
I have included the code that I am using. Apologies if it should have been abbreviated..
public class KG2013Core_QLaunch_CaymanOLEventReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//custom extension to get web in feature.
using (SPWeb spWeb = properties.GetWeb() as SPWeb)
{
SPSite spSite = properties.GetSite() as SPSite;
SPWeb spRootWeb = spSite.RootWeb;
//configure the quicklaunch menu
configureQuickLaunch(spWeb);
}
}
public static void configureQuickLaunch(SPWeb spWeb)
{
ClearQuickLaunch(spWeb);
AddQuickLaunchList(spWeb,"Engagement Admin", "Engagement Tasks");
AddQuickLaunchList(spWeb,"Engagement Admin", "Engagement Calendar");
}
public static void ClearQuickLaunch(SPWeb spWeb)
{
SPNavigationNodeCollection quickLaunch = spWeb.Navigation.QuickLaunch;
for (int i = quickLaunch.Count - 1; i > -1; i--)
{
quickLaunch[i].Delete();
}
quickLaunch.Parent.Update();
spWeb.Update();
}
public static void AddQuickLaunchList(SPWeb spWeb, string header, string listname)
{
SPNavigationNodeCollection quickLaunch = spWeb.Navigation.QuickLaunch;
// try to get the list
SPList list = spWeb.Lists.TryGetList(listname);
if (list != null)
{
string name = list.Title;
string url = list.DefaultViewUrl;
// NOTE : quickLaunch.Count provided the wrong number. Probably due to active instance of web object.
if (quickLaunch.Parent.Children.Count > 0)
{
if (header != null)
{
//try to get quick launch header
SPNavigationNode nodeHeader = quickLaunch.Parent.Children.Cast<SPNavigationNode>().Where(n => n.Title == header).FirstOrDefault();
//if header not found create it
if (nodeHeader == null)
{
nodeHeader = quickLaunch.AddAsLast(new SPNavigationNode(header, ""));
nodeHeader.Update();
}
//try to get node item under header
SPNavigationNode nodeItem = nodeHeader.Children.Cast<SPNavigationNode>().Where(n => n.Title == name).FirstOrDefault();
//If item not found under heading then create it
if (nodeItem == null)
{
nodeItem = nodeHeader.Children.AddAsLast(new SPNavigationNode(name, url));
}
else
{
nodeItem.Url = url;
}
nodeItem.Update();
nodeHeader.Update();
}
else
{
//try to get node item under quicklaunch
SPNavigationNode nodeItem = quickLaunch.Parent.Children.Cast<SPNavigationNode>().Where(n => n.Title == name).FirstOrDefault();
//If item not found then create it
if (nodeItem == null)
{
nodeItem = quickLaunch.AddAsLast(new SPNavigationNode(name, url));
}
else
{
nodeItem.Url = url;
}
nodeItem.Update();
}
}
else
{
if (header != null)
{
SPNavigationNode nodeHeader = new SPNavigationNode(header, "");
quickLaunch.AddAsFirst(nodeHeader);
SPNavigationNode nodeItem = nodeHeader.Children.AddAsLast(new SPNavigationNode(name, url));
nodeItem.Update();
nodeHeader.Update();
}
else
{
SPNavigationNode nodeItem = new SPNavigationNode(name, url);
quickLaunch.AddAsFirst(nodeItem);
nodeItem.Update();
}
}
}
}
}