Monday, April 12, 2010

SharePoint 2010 Content Type Features

Today I decided to create a Content Type for SharePoint 2010. As far as I can tell, while there has been a lot of effort in building in taxonomy improvements, such as tagging, the Content Type is still alive and well and works the same.

The easiest way to create a Content Type feature in MOSS 2007 was to create it in the UI first and then extract it. Normally I use a tool for that, but decided this time I'd give it a shot and write code to do it myself. In the process I could see if the API had changed in this area. It appears to work the same, so experience in MOSS 2007 will apply directly.

Here is the code if you want to try it yourself. The last line will be the contents of your Elements.xml file.

class Program
    {
        static void Main(string[] args)
        {
            GetContentType();
        }

        private static void GetContentType()
        {
            //we'd pull from SPContext.Current.Site, so wouldn't need to do this
            using (SPSite site = new SPSite("http://sharepoint"))
            {
                string ctype = "0x0100420995776E88234093C72FC85E59E4A8"; //from querystring. you could also loop through the RootWeb.ContentTypes collection and find by name
                SPContentTypeId id = new SPContentTypeId(ctype);

                bool includeSiteColumns = true;

                XmlDocument xdElements = new XmlDocument();
                XmlElement xeElementRoot = xdElements.CreateElement("Elements");

                XmlAttribute xaNamespace = xdElements.CreateAttribute("xmlns");
                xaNamespace.Value = "http://schemas.microsoft.com/sharepoint/";
                xeElementRoot.Attributes.Append(xaNamespace);

                xdElements.AppendChild(xeElementRoot);

                SPWeb web = site.RootWeb;
                SPContentType ctMatch = web.ContentTypes[id];
                if (ctMatch != null)
                {
                    XmlDocument xdSchema = new XmlDocument();
                    xdSchema.LoadXml(ctMatch.SchemaXml);

                    //move the field nodes - otherwise we won't pass the validation of an Elements node for our feature
                    //these will become Site Columns
                    XmlNode xnFields = xdSchema.SelectSingleNode("//Fields");
                    if (xnFields != null)
                    {
                        xnFields.ParentNode.RemoveChild(xnFields);

                        if (includeSiteColumns)
                        {
                            XmlDocumentFragment xdfFields = xdElements.CreateDocumentFragment();
                            xdfFields.InnerXml = xnFields.InnerXml;
                            xeElementRoot.AppendChild(xdfFields);
                        }
                    }

                    XmlDocumentFragment xdfContentType = xdElements.CreateDocumentFragment();
                    xdfContentType.InnerXml = xdSchema.FirstChild.OuterXml;

                    //inject FeildRefs to refer to the fields above
                    XmlNode xnFieldRefs = xdElements.CreateElement("FieldRefs");

                    StringBuilder sbFieldRefs = new StringBuilder();
                    foreach (SPFieldLink fr in ctMatch.FieldLinks)
                    {
                        sbFieldRefs.Append(fr.SchemaXml);
                    }

                    XmlDocumentFragment xdfFieldReferences = xdElements.CreateDocumentFragment();
                    xdfFieldReferences.InnerXml = sbFieldRefs.ToString();
                    xnFieldRefs.AppendChild(xdfFieldReferences);

                    xdfContentType.FirstChild.AppendChild(xnFieldRefs);

                    xeElementRoot.AppendChild(xdfContentType);

                    string s = xeElementRoot.OuterXml;
                }
            }
        }
    }

No comments:

Post a Comment