Blogger

  • This email address is being protected from spambots. You need JavaScript enabled to view it.

    Recent items

Login

Thursday, 16 May 2013 07:27

Setup a SPList to use the Enterprise Keyword feature and load data with a tool (also populating the Keyword and Tags field)

Written by
Rate this item
(0 votes)

Often, the customers asks us to can use the keyword and tags feature into a lists, a document library, etc.

To enable this feature into a list, you may into the list and after from the ribbon, click on List tab, List settings, Enterprise Metadata and Keywords Settings, enable the flag like the picture below.

Now when you are create/edit a new list item, you have the Keyword (and tags) field.

If we need to have this feature already enabled when we deploy and create a custom List, we need to add the settings into the ContentType definition and into the List Definition.

Step 1: First of all, we need to add the the field ref of the fields into the content type

{codecitation}

<ContentType
  ID="0x010100603A64185EFC45C0B8F0274C31CEA0CF"
  Name="KeywordDocument"
  Group="Custom Content Type"
  Description="Custom Content Type with Enterprise Keyword">
 
  <FieldRefs>
    ...
    <FieldRef
      ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"
      Name="TaxKeywordTaxHTField"
      Hidden="TRUE" />
 
    <FieldRef
      ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}"
      Name="TaxKeyword" />
 
    <FieldRef
      ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"
      Name="TaxCatchAll"
      Hidden="TRUE" />

{/codecitation}

Step 2: If you already have the list (and the ListDefinition), you need to add the fields also into the fields tag of the list definition.

{codecitation}

<Fields>

    <Field Type='TaxonomyFieldTypeMulti'
      DisplayName='Enterprise Keywords'
      StaticName='TaxKeyword'
      Name='TaxKeyword'
      ID='{23f27201-bee3-471e-b2e7-b64fd8b7ca38}'
      List="Lists/TaxonomyHiddenList"
      WebId='~sitecollection'
      ShowInViewForms='TRUE'
      DefaultListField='TRUE'
      Required='FALSE'
      Hidden='FALSE'
      ShowField="Term$Resources:core,Language;"
      Mult='TRUE'
      Sortable='FALSE'
      Group="$Resources:osrvcore,field_KeywordsGroupName"
      Description="$Resources:osrvcore,field_KeywordsFieldDesc"
      AllowDeletion='TRUE'>
      <Customization>
        <ArrayOfProperty>
          <Property>
            <Name>SspId</Name>
            <Value
              xmlns:q1='http://www.w3.org/2001/XMLSchema' p4:type='q1:string'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>00000000-0000-0000-0000-000000000000</Value>
          </Property>
          <Property>
            <Name>GroupId</Name>
          </Property>
          <Property>
            <Name>TermSetId</Name>
            <Value
              xmlns:q2='http://www.w3.org/2001/XMLSchema' p4:type='q2:string'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>00000000-0000-0000-0000-000000000000</Value>
          </Property>
          <Property>
            <Name>AnchorId</Name>
            <Value
              xmlns:q3='http://www.w3.org/2001/XMLSchema' p4:type='q3:string'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>00000000-0000-0000-0000-000000000000</Value>
          </Property>
          <Property>
            <Name>UserCreated</Name>
            <Value
              xmlns:q4='http://www.w3.org/2001/XMLSchema' p4:type='q4:boolean'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>false</Value>
          </Property>
          <Property>
            <Name>Open</Name>
            <Value
              xmlns:q5='http://www.w3.org/2001/XMLSchema' p4:type='q5:boolean'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>true</Value>
          </Property>
          <Property>
            <Name>TextField</Name>
            <Value
              xmlns:q6='http://www.w3.org/2001/XMLSchema' p4:type='q6:string'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>{1390a86a-23da-45f0-8efe-ef36edadfb39}</Value>
          </Property>
          <Property>
            <Name>IsPathRendered</Name>
            <Value
              xmlns:q7='http://www.w3.org/2001/XMLSchema' p4:type='q7:boolean'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>false</Value>
          </Property>
          <Property>
            <Name>IsKeyword</Name>
            <Value
              xmlns:q8='http://www.w3.org/2001/XMLSchema' p4:type='q8:boolean'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>true</Value>
          </Property>
          <Property>
            <Name>TargetTemplate</Name>
          </Property>
          <Property>
            <Name>CreateValuesInEditForm</Name>
            <Value
              xmlns:q9='http://www.w3.org/2001/XMLSchema' p4:type='q9:boolean'
              xmlns:p4='http://www.w3.org/2001/XMLSchema-instance'>false</Value>
          </Property>
          <Property>
            <Name>FilterAssemblyStrongName</Name>
          </Property>
          <Property>
            <Name>FilterClassName</Name>
          </Property>
          <Property>
            <Name>FilterMethodName</Name>
          </Property>
          <Property>
            <Name>FilterJavascriptProperty</Name>
          </Property>
        </ArrayOfProperty>
      </Customization>
    </Field>
    <Field Type="Note"
      DisplayName="TaxKeywordTaxHTField"
      StaticName="TaxKeywordTaxHTField"
      Name="TaxKeywordTaxHTField"
      ID="{1390a86a-23da-45f0-8efe-ef36edadfb39}"
      ShowInViewForms="FALSE"
      Required="FALSE"
      Hidden="TRUE"
      CanToggleHidden="TRUE" />

    <Field Type="LookupMulti"
      DisplayName="Taxonomy Catch All Column"
      StaticName="TaxCatchAll"
      Name="TaxCatchAll"
      ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}"
      ShowInViewForms="FALSE"
      Required="FALSE"
      Hidden="TRUE"
      ShowField="CatchAllData"
      Mult="TRUE"
      List="Lists/TaxonomyHiddenList"
      WebId="~sitecollection"
      Sortable="FALSE"
      AllowDeletion="TRUE"
      Sealed="TRUE" />

</Fields>

{/codecitation}


At this point, we are usually done. The columns were added to the list definition and the columns does indeed show up in the list.

Step 3: The keywords added to items in the list does not show up. What is missing is the event receiver that takes care of the keyword synchronization. Add an Event Receiver to the project. Make sure to select the list you just created as the event source when going through the wizard, and any events in the events list (we will replace the code generated, so it does not matter which).

Step 4: Delete the event receiver's code file (.cs file) so you are only left with the Elements.xml file.

Step 5: Open the event receiver's Elements.xml file and replace whatever <Receiver> tags where generated with these:

{codecitation}

<Receiver>
    <Name>TaxonomyItemSynchronousAddedEventReceiver</Name>
    <Synchronization>Synchronous</Synchronization>
    <Type>ItemAdding</Type>
    <SequenceNumber>10000</SequenceNumber>
    <Assembly>Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
    <Class>Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver</Class>
    <Data></Data>
</Receiver>
<Receiver>
    <Name>TaxonomyItemUpdatingEventReceiver</Name>
    <Synchronization>Synchronous</Synchronization>
    <Type>ItemUpdating</Type>
    <SequenceNumber>10000</SequenceNumber>
    <Assembly>Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
    <Class>Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver</Class>
    <Data></Data>
</Receiver>
{/codecitation}

Step 6: The important thing to make sure is that the value of the ListTemplateId attribute on the <Receivers ListTemplateId="xxxxx"> ... </Receivers> tag is the same as the value of the Type="xxxxx" attribute on the < ListTemplate ... /> tag. Otherwise the event receivers will not attach to the right list.

In the next section, I show how you can populate the field code behind (for example, imagine that you have an excel file and use it to populate the list al fill also the Enterprise keyword field).

{codecitation}

internal void LoadReports(string excelPath, SPWeb rootWeb)
        {
            try
            {
                SPList repList = rootWeb.GetList("Lists/Reports");

                ListHelper.ClearList(repList);

                if (repList != null)
                {
                    Console.WriteLine("Lists found!");

                    var wb = new XLWorkbook(excelPath);
                    var ws = wb.Worksheet(2);

                    TaxonomyField tf = repList.Fields.GetFieldByInternalName("TaxKeyword") as TaxonomyField;

                    foreach (IXLTable tb in ws.Tables)
                    {
                        for (int i = 2; i < tb.RowCount() + 1; i++)
                        {
                            IXLRangeRow rw = tb.Row(i);

                            try
                            {
                                string value = string.Empty;

                                SPListItem newItem = repList.AddItem();
                                int j = 0;


                                newItem["Title"] = rw.Cell(j).Value != null ? rw.Cell(j).Value.ToString() : string.Empty;
                                j = 1;
                               
                                newItem["PDFReportURL"] = rw.Cell(j).HasHyperlink ?
                                    repList.ParentWeb.Site.Url + rw.Cell(j).Hyperlink.ExternalAddress.AbsolutePath + (rw.Cell(j).Value != null ? ", " + rw.Cell(j).Value.ToString() : string.Empty)
                                    : string.Empty;

                                j = 2;
                                newItem["Description"] = rw.Cell(j).Value != null ? rw.Cell(j).Value.ToString() : string.Empty;

                                j = 3;
                               
                                TaxonomyFieldValueCollection taxFVC = new TaxonomyFieldValueCollection(tf);
                                value = !string.IsNullOrEmpty(rw.Cell(j).ValueCached) ? rw.Cell(j).ValueCached : string.Empty;
                                string[] values = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                                List<Guid> itemsToAdd = new List<Guid>();

                                //we need to initialize it every time otherwise we have timeout exception and cannot operate
                                TaxonomySession session = new TaxonomySession(repList.ParentWeb.Site);
                                TermStore termStore = session.TermStores[tf.SspId];
                                TermSet termSet = termStore.GetTermSet(tf.TermSetId);

                                foreach (string a in values)
                                {

                                    string val = a.StartsWith(" ") ? a.Substring(1) : a;

                                    while (val.StartsWith(" "))
                                        val = val.StartsWith(" ") ? val.Substring(1) : val;

                                    Term myTerm = null;

                                    try
                                    {
                                        myTerm = termSet.Terms[val];
                                    }
                                    catch (ArgumentOutOfRangeException)
                                    {
                                        myTerm = termSet.CreateTerm(val, 1033);
                                        termStore.CommitAll();
                                    }

                                    if (myTerm != null && !string.IsNullOrEmpty(myTerm.Name))
                                        itemsToAdd.Add(myTerm.Id);

                                }

                                Guid[] ids = itemsToAdd.ToArray();
                                TermCollection oTerms = session.GetTerms(ids);
                                tf.SetFieldValue(newItem, oTerms);

                                newItem.Update();
                                Logger.WriteLog("Item " + i + "added.");

                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(string.Format("Error manipulating line {0}.", i));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }

{/codecitation}

 

Read 26774 times Last modified on Thursday, 16 May 2013 20:38

Leave a comment

Make sure you enter all the required information, indicated by an asterisk (*). HTML code is not allowed.