I'm developing a feature that will be provisioned to a SharePoint 2007 web. The feature config files are below.
What I want to happen when the feature is installed and activated:
For now I get errors when trying to activate the feature, but if I create the list and the folder manually then the file is placed there.
So the question is, how do I make sure the list and the folder are created automatically?
feature.xml
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="5EAAAAD9-E885-43f8-B2FD-4C63271E7BAA"
Title="ABC"
Description="ABC"
Version="1.0.0.0"
Hidden="FALSE"
Scope="Web"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elements.xml"/>
<ElementFile Location="CustomPages/yyy/page1.aspx" />
</ElementManifests>
</Feature>
elements.xml
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="Module1" Url="xxx/yyy" RootWebOnly="TRUE" Path="CustomPages/yyy">
<File IgnoreIfAlreadyExists="TRUE" Type="GhostableInLibrary" Url="page1.aspx"></File>
</Module>
</Elements>
If you can use custom code you can override the FeatureActivated event receiver
of the feature to create the list and folder.
You will need to create another feature to run before the feature that provisions the files and give the file provision feature a dependency on the first to ensure that the list is available.
Alternatively you can add a list definition and instance via xml. I personally avoid this route whenever possible but you can find guidance for this at MSDN - Creating List Definitions with Custom List Columns for SharePoint Server 2007
Example for adding a list via code (caveat - I don't have 2007 to test against but this does work on 2010 and I don't think I've used any 2010 specific code)
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = properties.Feature.Parent as SPWeb; // Assuming web scoped feature
SPList customPagesList;
bool listExists = true;
//Check to see if the list exists, this method sucks but 2007 doesn't have web.TryGetList()
try
{
customPagesList = web.GetList("/CustomPages"); // server relative url of the list
}
catch (FileNotFoundException e)
{
listExists = false;
}
if (!listExists)
{
// Create list and record returned guid
Guid customPagesListGuid = web.Lists.Add("CustomPages",
"Library to store web pages used in the site", SPListTemplateType.DocumentLibrary);
//Get list from stored guid
customPagesList = web.Lists[customPagesListGuid];
// Set list properties and add required content types
customPagesList.Title = "CustomPages";
customPagesList.OnQuickLaunch = false; // Set to true to display on the quick launch
customPagesList.ContentTypesEnabled = true;
customPagesList.NoCrawl = true; // Set to false if you want pages indexed by search
customPagesList.EnableFolderCreation = true;
customPagesList.EnableSyndication = false; // Turn off rss
SPContentType webPartPageCT = web.AvailableContentTypes[SPBuiltInContentTypeId.WebPartPage];
SPContentType basicPageCT = web.AvailableContentTypes[SPBuiltInContentTypeId.BasicPage];
customPagesList.ContentTypes.Add(webPartPageCT);
customPagesList.ContentTypes.Add(basicPageCT);
// Remove the default content type added on list creation if it is not needed
DeleteContentType(customPagesList.ContentTypes, "Document");
// Commit changes
customPagesList.Update();
//Get library from stored guid
SPDocumentLibrary customPagesLibrary = (SPDocumentLibrary)web.Lists[customPagesListGuid];
customPagesLibrary.Folders.Add("/Lists/CustomPages/yyy", SPFileSystemObjectType.Folder);
string rootFolderUrl = customPagesLibrary.RootFolder.ServerRelativeUrl;
SPListItem newFolder = customPagesLibrary.Folders.Add(rootFolderUrl, SPFileSystemObjectType.Folder, "yyy");
newFolder.Update();
}
}
private void DeleteContentType(SPContentTypeCollection ctCollection, string ctName)
{
foreach (SPContentType ct in ctCollection)
{
if (ct.Name.Equals(ctName))
{
ct.Delete();
}
}
}