Support Portal ContactGet in touch

Where’s my Content Type?

   Words by CRM Consultancy

   on 08/06/2018 10:00:00

When working with Documents in SharePoint, Content Types are a great tool to help manage our types of document and what Metadata we might want to track for different document types.

However if our SharePoint Topology involves multiple Sites then we may find ourselves with the challenge of which Content Types we want to see in which Sites.

If we consider the following scenarios:

Content Types in a Single Top-Level Site

The simplest scenario, where we have a fixed set of Content Types that is shared across all our SharePoint Locations whether Sub-Sites or Document Libraries.

This is simple to manage as we can configure our SharePoint logic to read the list of Content Types from the top level site irrespective of which Web we are working with at the time.

Each Subsite or Document Library may then be connected to a different Entity Type in CRM but we manage a single set of universal Content Types across the board.

Top-Site Content Types

So using the above as an example of our SharePoint Structure, we would have:

  • Site per Department in both CRM and SharePoint
  • Document Library per Account record in CRM
  • Folder for each Project added to a Company
  • Sub-Folder for each Project Task added to a Project
  • Using a universal set of Content Types defined in the Top-Level Site
  • So each Department would share the same list of Content Types at all times

This is easy to manage but limited if we need different Content Types in different Departments.

In CRM using DocMan this can be implemented by configuring our Metadata Entity for the Department as:

image

Coding this against SharePoint, this means we can look into the RootWeb to find the Content Types we are looking for:

ContentTypeCollection siteContentTypes = this.SPSite.RootWeb.ContentTypes;
client.Load(siteContentTypes);
client.ExecuteQuery();

foreach (var item in siteContentTypes)
{
    if (item.Name == contentTypeName)
    {
        // Content Type Exists in the Top-Level Site
        contentTypeID = item.Id.StringValue;
    }
}

Content Types per Site

This is the more common scenario, where we will have a series of Subsites that each have their own Content Types. 

Often the Top-Level Site in this scenario is fixed and will only be accessible to Global Administrators.

So our Content Types will instead be stored at the Subsite Level and so allow each Subsite to have a common or individual list of Content Types.

Top-Web Content Types

In this example we would then have:

  • Site per Department in both CRM and SharePoint
  • Document Library per Account record in CRM
  • Folder for each Project added to a Company
    • Sub-Folder for each Project Task added to a Project
    • Each Department Site would have its own set of Content Types specific to that Department
      • As we can see above, Departments 1 and 2 having their set of Content Types

    The configuration in CRM being similar but with a small change to track where the Content Types are located:

    image

    This instructs CRM to use the Content Types located within the Departmental Site (as the Current Web for the Account Entity) instead of the Content Types located in the Top-Level Site. (which we may not have access to store and use for Content Types)

    Coding this in SharePoint is similar:

    ContentTypeCollection webContentTypes = this.SPWeb.ContentTypes;
    client.Load(webContentTypes);
    client.ExecuteQuery();

    foreach (var item in webContentTypes)
    {
        if (item.Name == contentTypeName)
        {
            // Content Type exists in the Web
            contentTypeID = item.Id.StringValue;
        }
    }

    Content Types in a N-Level Hierarchy

    Where we have a more complex structure that involves Middle-Tier Sites with multiple Child Subsites, we may want to reflect a hierarchy in where we store the Content Types, these are stored at the Middle-Tier Parent Sites rather than having to be located in each of the Child Sites.

    This structure could look similar to:

    Top-Child Parent Webs

    In this structure, we have:

    • Site per Department in both CRM and SharePoint
    • Subsite per Company between CRM and SharePoint
    • Document Library for each Project added to the Company in CRM
    • Folder for each Project Area added to the Project
    • Sub-Folder for each Project Task added to a Project Area within a Project
    • Content Types stored at the Parent Department Level, and not the Child Company Level – so we still have one set of Content Types per Department rather than a set per Company

    The Configuration in CRM would then work across the configuration for Department and Company.

    image

    image

    The code behind this in SharePoint is the same, as we are simply reading the Content Types from a different Web – however the way we organise this code is more tricky, as we loop through each Configuration Record in the chain to determine whether to look at the Current Web (i.e. for the Company say) or the Parent Web. (in this case, the Department)

    This process of controlling where our Content Types are stored and so ensuring that the list of Content Types in use for a particular area in CRM can be key to good governance of larger SharePoint Sites – and has some similarities with how Security in SharePoint can be managed at a similar Individual Site Level, Parent Site Level or Top-Level Site via Inheritance.

    The Inheritance meaning we have good management of a small number of unique Content Types at each level, with a similar good structure to our logic to read the Content Types from the right location at the right time.

    This reduces the duplication of the same or similar Content Types, as any duplication becomes more difficult to manage over time. (in the same fashion as Code and Paste Programming is almost always bad!)

    image

    Content Types and Document Libraries

    We would typically track Content Types per Site in the format we have reviewed above, so the Top-Level, Mid or Sub Site can contain the list of applicable Content Types.

    However we can also instruct each Document Library to only use particular Content Types for storing Documents in that Library.

    Where we are creating new Document Libraries automatically based from CRM, we would recommend code to automatically attach the Content Types from the Site that we are adding the Document Library to:

    if (listContentTypes != null)
    {
        //Add the Content Type to the Library as an applicable Content Type
        ContentTypeCollection siteContentTypes = web.AvailableContentTypes;

        client.Load(siteContentTypes);
        client.ExecuteQuery();

        if (siteContentTypes.Count > 0)
        {
            bool setContentTypes = false;

            foreach (string contentTypeName in listContentTypes)
            {
                foreach (ContentType ct in siteContentTypes)
                {
                    if (ct.Name == contentTypeName)
                    {
                        docLibrary.ContentTypes.AddExistingContentType(ct);
                        setContentTypes = true;
                    }
                }
            }

            if (setContentTypes == true)
            {
                docLibrary.ContentTypesEnabled = true;
                docLibrary.Update();
                client.ExecuteQuery();
             }
        }
    }

    This keeps the management of Content Types to the Site Level and so following the rules we have outlined above for easier management – again aimed at avoiding undue duplication.

    From this, in subsequent article, we can then look at how we can use a tool like DocMan to manage our Content Types within CRM and then publish into SharePoint as a another way of manging this complexity in larger scale Document Management.

    Prefer to go old-school?

    Write to us using the below addresses.

    Head Office
    CRM Consultancy
    61 Oxford Street
    Manchester
    M1 6EQ

    London Office
    CRM Consultancy London
    Grosvenor Avenue
    London

    Content © CRM Consultancy.