/// <summary> /// This method is called when the Content Type declared in the attribute hasn't been found in Umbraco /// </summary> /// <param name="contentTypeService"></param> /// <param name="fileService"></param> /// <param name="attribute"></param> /// <param name="type"></param> /// <param name="dataTypeService"></param> private static void CreateContentType(IContentTypeService contentTypeService, IFileService fileService, UmbracoContentTypeAttribute attribute, Type type, IDataTypeService dataTypeService) { IContentType newContentType; Type parentType = type.BaseType; if (parentType != null && parentType != typeof(UmbracoGeneratedBase) && parentType.GetBaseTypes(false).Any(x => x == typeof(UmbracoGeneratedBase))) { UmbracoContentTypeAttribute parentAttribute = parentType.GetCustomAttribute<UmbracoContentTypeAttribute>(); if (parentAttribute != null) { string parentAlias = parentAttribute.ContentTypeAlias; IContentType parentContentType = contentTypeService.GetContentType(parentAlias); newContentType = new ContentType(parentContentType); } else { throw new Exception("The given base class has no UmbracoContentTypeAttribute"); } } else { newContentType = new ContentType(-1); } newContentType.Name = attribute.ContentTypeName; newContentType.Alias = attribute.ContentTypeAlias; newContentType.Icon = attribute.Icon; newContentType.Description = attribute.Description; if (attribute.CreateMatchingView) { SetDefaultTemplateAndCreateIfNotExists(fileService, attribute.MasterTemplate, attribute.TemplateLocation, type, newContentType); } CreateAdditionalTemplates(newContentType, type, fileService, attribute.MasterTemplate, attribute.TemplateLocation); newContentType.AllowedAsRoot = attribute.AllowedAtRoot; newContentType.IsContainer = attribute.EnableListView; newContentType.AllowedContentTypes = FetchAllowedContentTypes(attribute.AllowedChildren, contentTypeService); //create tabs CreateTabs(newContentType, type, dataTypeService); //create properties on the generic tab var propertiesOfRoot = type.GetProperties().Where(x => x.GetCustomAttribute<UmbracoPropertyAttribute>() != null); foreach (var item in propertiesOfRoot) { CreateProperty(newContentType, null, dataTypeService, true, item); } //Save and persist the content Type contentTypeService.Save(newContentType, 0); }
/// <summary> /// Update the existing content Type based on the data in the attributes /// </summary> /// <param name="contentTypeService"></param> /// <param name="fileService"></param> /// <param name="attribute"></param> /// <param name="contentType"></param> /// <param name="type"></param> /// <param name="dataTypeService"></param> private static void UpdateContentType(IContentTypeService contentTypeService, IFileService fileService, UmbracoContentTypeAttribute attribute, IContentType contentType, Type type, IDataTypeService dataTypeService) { contentType.Name = attribute.ContentTypeName; contentType.Alias = attribute.ContentTypeAlias; contentType.Icon = attribute.Icon; contentType.IsContainer = attribute.EnableListView; contentType.AllowedContentTypes = FetchAllowedContentTypes(attribute.AllowedChildren, contentTypeService); contentType.AllowedAsRoot = attribute.AllowedAtRoot; Type parentType = type.BaseType; if (parentType != null && parentType != typeof(UmbracoGeneratedBase) && parentType.GetBaseTypes(false).Any(x => x == typeof(UmbracoGeneratedBase))) { UmbracoContentTypeAttribute parentAttribute = parentType.GetCustomAttribute<UmbracoContentTypeAttribute>(); if (parentAttribute != null) { string parentAlias = parentAttribute.ContentTypeAlias; IContentType parentContentType = contentTypeService.GetContentType(parentAlias); contentType.ParentId = parentContentType.Id; } else { throw new Exception("The given base class has no UmbracoContentTypeAttribute"); } } if (attribute.CreateMatchingView) { Template currentTemplate = fileService.GetTemplate(attribute.ContentTypeAlias) as Template; if (currentTemplate == null) { //there should be a template but there isn't so we create one currentTemplate = new Template("~/Views/" + attribute.ContentTypeAlias + ".cshtml", attribute.ContentTypeName, attribute.ContentTypeAlias); CreateViewFile(attribute.ContentTypeAlias, attribute.MasterTemplate, currentTemplate, type, fileService); fileService.SaveTemplate(currentTemplate, 0); } contentType.AllowedTemplates = new ITemplate[] { currentTemplate }; contentType.SetDefaultTemplate(currentTemplate); } VerifyProperties(contentType, type, dataTypeService); //verify if a tab has no properties, if so remove var propertyGroups = contentType.PropertyGroups.ToArray(); int length = propertyGroups.Length; for (int i = 0; i < length; i++) { if (propertyGroups[i].PropertyTypes.Count == 0) { //remove contentType.RemovePropertyGroup(propertyGroups[i].Name); } } //persist contentTypeService.Save(contentType, 0); }
/// <summary> /// Creates a View if specified in the attribute /// </summary> /// <param name="fileService"></param> /// <param name="attribute"></param> /// <param name="type"></param> /// <param name="newContentType"></param> private static void CreateMatchingView(IFileService fileService, UmbracoContentTypeAttribute attribute, Type type, IContentType newContentType) { Template currentTemplate = fileService.GetTemplate(attribute.ContentTypeAlias) as Template; if (currentTemplate == null) { currentTemplate = new Template("~/Views/" + attribute.ContentTypeAlias + ".cshtml", attribute.ContentTypeName, attribute.ContentTypeAlias); CreateViewFile(attribute.ContentTypeAlias, attribute.MasterTemplate, currentTemplate, type, fileService); } newContentType.AllowedTemplates = new ITemplate[] { currentTemplate }; newContentType.SetDefaultTemplate(currentTemplate); //TODO: in Umbraco 7.1 it will be possible to set the master template of the newly created template //https://github.com/umbraco/Umbraco-CMS/pull/294 }
/// <summary> /// Creates a View if specified in the attribute /// </summary> /// <param name="fileService"></param> /// <param name="attribute"></param> /// <param name="type"></param> /// <param name="newContentType"></param> private static void CreateMatchingView(IFileService fileService, UmbracoContentTypeAttribute attribute, Type type, IContentType newContentType) { var currentTemplate = fileService.GetTemplate(attribute.ContentTypeAlias) as Template; if (currentTemplate == null) { string templatePath; if (string.IsNullOrEmpty(attribute.TemplateLocation)) { templatePath = string.Format(CultureInfo.InvariantCulture, "~/Views/{0}.cshtml", attribute.ContentTypeAlias); } else { templatePath = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}.cshtml", attribute.TemplateLocation, // The template location attribute.TemplateLocation.EndsWith("/") ? string.Empty : "/", // Ensure the template location ends with a "/" attribute.ContentTypeAlias); // The alias } currentTemplate = new Template(templatePath, attribute.ContentTypeName, attribute.ContentTypeAlias); CreateViewFile(attribute.MasterTemplate, currentTemplate, type, fileService); } newContentType.AllowedTemplates = new ITemplate[] { currentTemplate }; newContentType.SetDefaultTemplate(currentTemplate); //TODO: in Umbraco 7.1 it will be possible to set the master template of the newly created template //https://github.com/umbraco/Umbraco-CMS/pull/294 }