Quantcast
Channel: Sitefinity – Falafel Software Blog
Viewing all articles
Browse latest Browse all 73

Programmatically add fields to Pages module in Sitefinity 6.3 and 7

$
0
0

Sitefinity 7 comes with a very cool new feature that enables us to add custom fields to Pages module through UI. Although this feature was previously not available in version 6.3, but its effect could be achieved by using Page Attributes. Also, in version 7, its called Custom Fields. Following is the helper class.

ModuleHelper.cs

public class ModuleHelper
{
    public static void RegisterGuidArrayFieldSelectorForPages<C>(string fieldName) where C : FieldControlDefinitionElement
    {
        RegisterPageNodeDynamicData();

        string itemType = typeof(PageNode).FullName;
        var fieldExists = GetMetaFieldsForType(itemType).Where(f => f.FieldName == fieldName).SingleOrDefault() != null;

        if (!fieldExists)
        {
            var metaManager = MetadataManager.GetManager(); 
            var field = metaManager.CreateMetafield(fieldName); 
            field.FieldName = fieldName; 
            field.Title = fieldName; field.Hidden = false;
            field.ClrType = typeof(System.Guid[]).FullName; 
            var metaType2 = metaManager.GetMetaType(typeof(PageNode));
            metaType2.Fields.Add(field); 
            metaManager.SaveChanges();

            var manager = ConfigManager.GetManager(); 
            manager.Provider.SuppressSecurityChecks = true;

            var section = manager.GetSection<ContentViewConfig>();
            var backendSection = section.ContentViewControls[PagesDefinitions.BackendPagesDefinitionName];
            var views = backendSection.ViewsConfig.Values.Where(v => v.ViewType == typeof(DetailFormView));
            foreach (DetailFormViewElement view in views)
            {
                var sectionToInsert = CustomFieldsContext.GetSection(view, CustomFieldsContext.customFieldsSectionName, itemType);

                var fieldConfigElementType = TypeResolutionService.ResolveType(typeof(C).FullName);
                C newElement;
                newElement = Activator.CreateInstance(fieldConfigElementType, new object[] { sectionToInsert.Fields }) as C;

                newElement.DataFieldName = "CustomFields." + fieldName;
                newElement.FieldName = fieldName;
                newElement.Title = fieldName;
                newElement.DisplayMode = FieldDisplayMode.Write;
                newElement.Hidden = false;

                sectionToInsert.Fields.Add(newElement);
            }

            var frontendSection = section.ContentViewControls[PagesDefinitions.FrontendPagesDefinitionName];
            views = frontendSection.ViewsConfig.Values.Where(v => v.ViewType == typeof(DetailFormView));
            foreach (DetailFormViewElement view in views)
            {
                var sectionToInsert = CustomFieldsContext.GetSection(view, CustomFieldsContext.customFieldsSectionName, itemType);
                var fieldConfigElementType = TypeResolutionService.ResolveType(typeof(C).FullName);
                C newElement;
                newElement = Activator.CreateInstance(fieldConfigElementType, new object[] { sectionToInsert.Fields }) as C;

                newElement.DataFieldName = "CustomFields." + fieldName;
                newElement.FieldName = fieldName;
                newElement.Title = fieldName;
                newElement.DisplayMode = FieldDisplayMode.Write;
                newElement.Hidden = false;

                sectionToInsert.Fields.Add(newElement);
            }

            manager.SaveSection(section);
            manager.Provider.SuppressSecurityChecks = false;

            RestartApplication();
        }
    }

    private static void RegisterPageNodeDynamicData()
    {
        var pageNodeType = App.WorkWith().DynamicData().Types().Where(s => s.ClassName == "PageNode").Get().FirstOrDefault();
        if (pageNodeType != null) 
            return;

        App.WorkWith()
            .DynamicData()
            .Type()
            .CreateNew("PageNode", "Telerik.Sitefinity.Pages.Model")
            .Do(dt => dt.DatabaseInheritance = DatabaseInheritanceType.vertical)
            .SaveChanges(true);
    }

    private static IList<MetaField> GetMetaFieldsForType(string type)
    {
        var existingType = TypeResolutionService.ResolveType(type); 
        var existingClassName = existingType.Name;
        var existingNamespace = existingType.Namespace; 
        var mgr = MetadataManager.GetManager();

        var types = mgr.GetMetaTypes().FirstOrDefault(dt => dt.ClassName == existingClassName && dt.Namespace == existingNamespace);
        var fields = types != null ? types.Fields : new List<MetaField>();
            
        return fields;
    }

    private static void RestartApplication()
    {
        if (SystemManager.Initializing) 
            return;

        SystemManager.RestartApplication(true, true);
    }
}

 

Usage

Add new field on Bootstrapped event.

protected static void OnBootstrapperInitialized(object sender, ExecutedEventArgs e)
{
    if (e.CommandName == "Bootstrapped")
    {
        ModuleHelper.RegisterGuidArrayFieldSelectorForPages<ControlToUse>("YOUR_FIELD");
    }
}

 

Where ControlToUse is a Field Control which inherits FieldControlDefinitionElement and implements IRolesFieldSelectorDefinition. Happy Coding! And want to learn more? Register now for FalafelCon 2014 and perfect your skills, expand your horizons, and get inspired.

The post Programmatically add fields to Pages module in Sitefinity 6.3 and 7 appeared first on Falafel Software Blog.


Viewing all articles
Browse latest Browse all 73

Trending Articles