Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I want to use taxonomy fields for my "shared documents" and announcements. I can create the column afterwards.

But what is the best way to do it automatically when a user creates these lists or a site containing them is provisioned?

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

The easy way to do this is to change the underlying content types for these lists at the site collection level (i.e. Site Actions > Site Settings > Site Content Types (under Galleries).

Announcements is pretty straightforward because there is an Announcements content type. You can add the column to that content type and any existing or newly created lists (...at the root site/web or any subsites) that are derived from that content type will inherit that new column.

You can use the same approach with Shared Documents, but be aware that Shared Documents is derived from the Documents content type and adding a column to that content type would be affecting all libraries if you make that change.

Another reasonable, but much more involved, approach is to create a custom site template that has these lists/libraries the way you want them and make sure new sites are created using that template.

EDIT: Here's a code snippet for creating the columns during feature activation...

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
        using (SPSite site = new SPSite(((SPSite)properties.Feature.Parent).ID))
        {
            SPWeb web = site.RootWeb;

            SPContentType ct = web.ContentTypes["Announcement"];
            Microsoft.SharePoint.Taxonomy.TaxonomyField fld = ct.Fields.CreateNewField("TaxonomyFieldType", "Keywords") as Microsoft.SharePoint.Taxonomy.TaxonomyField;
            fld.SspId = [TermStoreID];
            fld.TermSetId = [TermSetID];
            ct.Fields.Add(fld);
            // update content type along with children (true) and surpress errors on sealed or read-only content types (false)
            ct.Update(true, false);
        }
    }

You'll need to provide the term store and term set Id's to complete this, but it should give you a general idea on approach.

share|improve this answer
    
Thank you. Is there a way to do it only with a site definition or something else in visual studio so I don't need to adjust it manually after deploying to a new site? –  Anatoly Mironov Jul 26 '11 at 13:19
    
Yes, you can programatically add the columns to those base content types during deployment of your solution via the feature receiver. I can drop a code snippet in the answer if you need it. –  Rob D'Oria Jul 26 '11 at 14:05
    
Thank you, I would appreciate a code snippet. –  Anatoly Mironov Jul 26 '11 at 14:27
add comment

You can also add keywords column to your lists as described here

public override void WebProvisioned(SPWebEventProperties properties)
{
    base.WebProvisioned(properties);

    SPList announcements = null;
    try
    {
        announcements = properties.Web.Lists["Announcements"];
    }
    catch { }
    if (announcements == null) return;

    //Courtesy to http://point2sharepoint.blogspot.com/2011/04/add-enterprise-keywords-column_3251.html
    //get an instance of SPTaxonomy assembly
    Assembly taxonomyAssembly = Assembly.LoadWithPartialName("Microsoft.SharePoint.Taxonomy");

    //get an instance of internal class for the keyword association
    Type listFieldSettings = taxonomyAssembly
                            .GetType("Microsoft.SharePoint.Taxonomy.MetadataListFieldSettings");

    //pass the list to the internal class's constructor
    object listSettings = listFieldSettings.GetConstructor(new Type[] { typeof(SPList) })
        .Invoke(new object[] { announcements });

    //get an instance of KW property and set the boolean
    listFieldSettings.GetProperty("EnableKeywordsField", BindingFlags.NonPublic |
                                BindingFlags.Instance).SetValue(listSettings, true, null);
    listFieldSettings.GetProperty("EnableMetadataPromotion", BindingFlags.NonPublic |
                            BindingFlags.Instance).SetValue(listSettings, true, null);
    //update the list
    listFieldSettings.GetMethod("Update", BindingFlags.NonPublic | BindingFlags.Instance)
            .Invoke(listSettings, null);
}
share|improve this answer
add comment

Powershell version

function SetMetadataListFieldSettings
{
param (     
    [string]$Url = $(throw "Url parameter not specified"),
    [string]$ListName = $(throw "ListName parameter not specified"),
    [Boolean]$EnableKeywordsField = $(throw "EnableKeywordsField parameter not specified"),
    [Boolean]$EnableMetadataPromotion = $(throw "EnableMetadataPromotion parameter not specified"),
) 

[Microsoft.SharePoint.PowerShell.SPAssignmentCollection]$gc = Start-SPAssignment

try
{
    [Microsoft.SharePoint.SPWeb]$spWeb = Get-SPWeb "$Url"  -AssignmentCollection $gc 
    if ($spWeb -eq $null) { throw "spSite variable is null" }

    [Microsoft.SharePoint.SPList]$spList = $spWeb.Lists["$ListName"]
    if ($spList -eq $null) { throw "spList variable is null" }

    # Load Microsoft.SharePoint and Microsoft.SharePoint.Taxonomy assemblies
    [System.Reflection.Assembly]$sharePointAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
    [System.Reflection.Assembly]$taxonomyAssembly = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Taxonomy")

    Write-Host -NoNewLine "Create MetadataListFieldSettings instance for : $ListName" 
    # get SPList System.RuntimeType 
    $spListType = $sharePointAssembly.GetType("Microsoft.SharePoint.SPList")

    # create instance of the internal MetadataListFieldSettings class referencing the relevant list
    $spMetadataListFieldSettingsType = $taxonomyAssembly.GetType("Microsoft.SharePoint.Taxonomy.MetadataListFieldSettings")
    $spMetadataListFieldSettings = $spMetadataListFieldSettingsType.GetConstructor($spListType).Invoke($spList)

    Write-Host -f Green "...Done!"

    # create binding flags values
    [System.Reflection.BindingFlags]$bindingFlags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance

    Write-Host -NoNewLine "Update MetadataListFieldSettings for : $ListName" 
    # set instance properties
    $spMetadataListFieldSettingsType.GetProperty("EnableKeywordsField", $bindingFlags).SetValue($spMetadataListFieldSettings, $EnableKeywordsField, $null)
    $spMetadataListFieldSettingsType.GetProperty("EnableMetadataPromotion", $bindingFlags).SetValue($spMetadataListFieldSettings, $EnableMetadataPromotion, $null)

    # update the list
    $spMetadataListFieldSettingsType.GetMethod("Update",$bindingFlags).Invoke($spMetadataListFieldSettings, $null)

    Write-Host -f Green "...Done!"
}
catch
{
    Throw $_.exception
}
finally
{
    $gc | Stop-SPAssignment
}

}

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.