Implementing the module class

The module class wraps the entire functionality created for the module. To create the module class, you must perform the following:

  1. From the context menu of the project ProductsModule, click Add » Class.
  2. Name the class file ProductsModule.cs and click Add.
  3. Open the file ProductsModule.cs.
  4. Add the following using statements:

    using ProductCatalogSample.Configuration;
    using ProductCatalogSample.Data;
    using ProductCatalogSample.Model;
    using ProductCatalogSample.Web.Services;
    using ProductCatalogSample.Web.UI;
    using ProductCatalogSample.Web.UI.Public;
    using Telerik.Sitefinity;
    using Telerik.Sitefinity.Abstractions;
    using Telerik.Sitefinity.Abstractions.VirtualPath;
    using Telerik.Sitefinity.Abstractions.VirtualPath.Configuration;
    using Telerik.Sitefinity.Configuration;
    using Telerik.Sitefinity.Data;
    using Telerik.Sitefinity.Data.ContentLinks;
    using Telerik.Sitefinity.Fluent.Modules;
    using Telerik.Sitefinity.Modules.GenericContent;
    using Telerik.Sitefinity.Modules.Pages;
    using Telerik.Sitefinity.Security;
    using Telerik.Sitefinity.Services;
    using Telerik.Sitefinity.Taxonomies.Model;
    using SecModel = Telerik.Sitefinity.Security.Model;

  5. Make the ProductsModule class inherit the ContentModuleBase class:

    public class ProductsModule : ContentModuleBase
    {
    }
  6. Define the following constants, static fields and properties:

    private static readonly string WorkflowEmbeddedPath = "ProductsModule.ProductsWorkflow.xamlx";
    private static readonly Type[] managerTypes = new Type[] { typeof(ProductsManager) };
     
    public static readonly Guid ColorsTaxonomyId = new Guid("47FC0316-0F9B-4D6D-A606-6CDC1977E10D");
    public static readonly string ProductsVirtualPath = "~/SFProducts/";
     
    public static readonly string WorkflowRelativeUrl = "~/Workflows/Products.xamlx";
    public static readonly Guid ProductsPageGroupId = new Guid("F0EB1F97-6E95-455C-B349-86F4A25C75EB");
    public static readonly Guid HomePageId = new Guid("21848245-6CB3-41F0-8A87-487B459914EB");
    public static readonly Guid CommentsPageId = new Guid("BB493061-3BF7-4920-AACA-44A35DF5742C");
    public static readonly string ResourceClassId = typeof(ProductsResources).Name;
     
    public const string ModuleName = "Products";
    public const string ProductsViewConfigKey = "ProductsView";
    public const string PublicProductsViewConfigKey = "PublicProductsView";
     
    public override Type[] Managers
    {
        get { return managerTypes; }
    }
     
    public override Guid LandingPageId
    {
        get
        {
            return ProductsModule.HomePageId;
        }
    }
  7. Override the Initialize method of the ContentModuleBase class.

    In it you must register the configuration class for the module and the backend service. Following is the code for the method.

    public override void Initialize(ModuleSettings settings)
           {
               base.Initialize(settings);
     
               App.WorkWith()
                   .Module(settings.Name)
                   .Initialize()
                       .Configuration<ProductsConfig>()
                       .Localization<ProductsResources>()
                       .WebService<ProductsBackendService>("Sitefinity/Services/Content/Products.svc")
                       .TemplatableControl<MasterListView, ProductItem>()
                       .TemplatableControl<ProductDetailsView, ProductItem>();
           }

  8. Override the Install method of the ContentModuleBase class.

    The method installs the module in Sitefinity system.

    public override void Install(SiteInitializer initializer)
            {
                base.Install(initializer);
     
                string resourceAssembly = this.GetType().Assembly.FullName;
                string customTemplatesArea = "Product catalog SDK sample";
                string friendlyWidgetName = "Products catalog sample widget";
                 
                initializer.RegisterControlTemplate(MasterListView.titlesOnlyLayoutTemplateName, typeof(MasterListView).FullName, ProductsDefinitions.FrontendTitlesOnlyListViewName, null, customTemplatesArea, Presentation.AspNetTemplate, friendlyControlName:friendlyWidgetName );
                initializer.RegisterControlTemplate(MasterListView.titlesDatesLayoutTemplateName, typeof(MasterListView).FullName, ProductsDefinitions.FrontendTitlesDatesListViewName, null, customTemplatesArea, Presentation.AspNetTemplate, friendlyControlName: friendlyWidgetName);
                initializer.RegisterControlTemplate(MasterListView.titlesDatesSummariesLayoutTemplateName, typeof(MasterListView).FullName, ProductsDefinitions.FrontendTitlesDatesSummariesListViewName, null, customTemplatesArea, Presentation.AspNetTemplate, friendlyControlName: friendlyWidgetName);
                initializer.RegisterControlTemplate(MasterListView.titlesDatesContentsLayoutTemplateName, typeof(MasterListView).FullName, ProductsDefinitions.FrontendTitlesDatesContentsListViewName, null, customTemplatesArea, Presentation.AspNetTemplate, friendlyControlName: friendlyWidgetName);
                initializer.RegisterControlTemplate(ProductDetailsView.layoutTemplateName, typeof(ProductDetailsView).FullName, ProductsDefinitions.FrontendFullProductItemDetailViewName, null, customTemplatesArea, Presentation.AspNetTemplate, resourceAssembly, friendlyWidgetName);
     
                this.InstallCustomVirtualPaths(initializer);
                this.InstallCustomTaxonomies(initializer);
            }
     
            private void InstallCustomVirtualPaths(SiteInitializer initializer)
            {
                var virtualPathConfig = initializer.Context.GetConfig<VirtualPathSettingsConfig>();
                ConfigManager.Executed += new EventHandler<ExecutedEventArgs>(ConfigManager_Executed);
                var productsModuleVirtualPathConfig = new VirtualPathElement(virtualPathConfig.VirtualPaths)
                {
                    VirtualPath = ProductsModule.ProductsVirtualPath + "*",
                    ResolverName = "EmbeddedResourceResolver",
                    ResourceLocation = "ProductCatalogSample"
                };
                if (!virtualPathConfig.VirtualPaths.ContainsKey(ProductsModule.ProductsVirtualPath + "*"))
                    virtualPathConfig.VirtualPaths.Add(productsModuleVirtualPathConfig);
            }
     
            private void ConfigManager_Executed(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs args)
            {
                if (args.CommandName == "SaveSection")
                {
                    var section = args.CommandArguments as VirtualPathSettingsConfig;
                    if (section != null)
                    {
                        // Reset the VirtualPathManager whenever we save the VirtualPathConfig section.
                        // This is needed so that our prefixes for the widget templates in the module assembly are taken into account.
                        VirtualPathManager.Reset();
                    }
                }
            }
     protected void InstallCustomTaxonomies(SiteInitializer initializer)
            {
                //installs the default Tags and Category taxonomies
                this.InstallTaxonomy(initializer, typeof(ProductItem));
     
     
                var metaMan = initializer.Context.MetadataManager;
                var taxMan = initializer.TaxonomyManager;
     
                var flatTaxonomy = this.CreateTaxonomy<FlatTaxonomy>(initializer, "Colors", ColorsTaxonomyId, "Color");
     
                var taxon1 = initializer.TaxonomyManager.CreateTaxon<FlatTaxon>();
                taxon1.Title = "Red";
                taxon1.Name = "Red";
                var taxon2 = initializer.TaxonomyManager.CreateTaxon<FlatTaxon>();
                taxon2.Title = "Blue";
                taxon2.Name = "Blue";
                flatTaxonomy.Taxa.Add(taxon1);
                flatTaxonomy.Taxa.Add(taxon2);
     
                var type = metaMan.GetMetaType(typeof(ProductItem));
                if (type == null)
                {
                    type = metaMan.CreateMetaType(typeof(ProductItem));
                }
     
                if (!type.Fields.ToList().Any(fld => fld.FieldName == "Colors"))
                {
                    var field = metaMan.CreateMetafield("Colors");
                    field.TaxonomyProvider = taxMan.Provider.Name;
                    field.TaxonomyId = ColorsTaxonomyId;
                    field.IsSingleTaxon = false;
                    type.Fields.Add(field);
                }
     
                if (!type.Fields.ToList().Any(fld => fld.FieldName == "ProductImage"))
                {
                    type.Fields.Add(ContentLinksExtensions.CreateContentLinkField("ProductImage", "OpenAccessDataProvider", metaMan, RelationshipType.OneToOne));
                }
                 
     
            }
    private TTaxonomy CreateTaxonomy<TTaxonomy>(SiteInitializer initializer, string taxonomyName, Guid taxonomyId, string taxonName) where TTaxonomy : class, ITaxonomy
            {
     
                var taxMan = initializer.TaxonomyManager;
                var taxonomy = taxMan.GetTaxonomies<TTaxonomy>().FirstOrDefault(t => t.Name == taxonomyName);
                if (taxonomy == null)
                {
                    taxonomy = taxMan.CreateTaxonomy<TTaxonomy>(taxonomyId);
                    taxonomy.Name = taxonomyName;
                    taxonomy.Title = taxonomyName;
                    taxonomy.TaxonName = taxonName;
                    ((SecModel.ISecuredObject)taxonomy).CanInheritPermissions = true;
                    ((SecModel.ISecuredObject)taxonomy).InheritsPermissions = true;
                    ((SecModel.ISecuredObject)taxonomy).SupportedPermissionSets = new string[] { SecurityConstants.Sets.Taxonomies.SetName };
                }
                return taxonomy;
            }

    In the Install method you register custom permissions, workflows, virtual paths and taxonomies.

    NOTE: The workflow file used here, can be found in the ProductsCatalogSample project in the SDK samples.

  9. Implement the abstract members of the ContentModuleBase class in the following way:

    protected override void InstallPages(SiteInitializer initializer)
     {
         initializer.Installer
             .CreateModuleGroupPage(ProductsPageGroupId, "Products")
                 .PlaceUnder(CommonNode.TypesOfContent)
                 .LocalizeUsing<ProductsResources>()
                 .SetTitleLocalized("PageGroupNodeTitle")
                 .SetUrlNameLocalized("PageGroupNodeTitle")
                 .SetDescriptionLocalized("PageGroupNodeDescription")
                 .AddChildPage(ProductsModule.HomePageId, "Products")
                     .LocalizeUsing<ProductsResources>()
                     .SetTitleLocalized("ProductsLandingPageTitle")
                     .SetHtmlTitleLocalized("ProductsLandingPageHtmlTitle")
                     .SetUrlNameLocalized("ProductsLandingPageUrlName")
                     .SetDescriptionLocalized("ProductsLandingPageDescription")
                     .AddContentView(c =>
                     {
                         c.ControlDefinitionName = ProductsDefinitions.BackendDefinitionName;
                         c.ModuleName = ProductsModule.ModuleName;
                     })
                     .Done()
                 .AddChildPage(ProductsModule.CommentsPageId, "Comments")
                     .LocalizeUsing<ProductsResources>()
                     .SetTitleLocalized("ProductCommentsPageTitle")
                     .SetHtmlTitleLocalized("ProductCommentsPageHtmlTitle")
                     .SetUrlNameLocalized("ProductCommentsPageUrlName")
                     .SetDescriptionLocalized("ProductCommentsPageDescription")
                     .AddContentView(c =>
                     {
                         c.ControlDefinitionName = ProductsDefinitions.BackendCommentsDefinitionName;
                         c.ModuleName = ProductsModule.ModuleName;
                     })
                     .Done();
     }
     
    protected void InstallCustomTaxonomies(SiteInitializer initializer)
     {
         //installs the default Tags and Category taxonomies
         this.InstallTaxonomy(initializer, typeof(ProductItem));
     
     
         var metaMan = initializer.Context.MetadataManager;
         var taxMan = initializer.TaxonomyManager;
     
         var flatTaxonomy = this.CreateTaxonomy<FlatTaxonomy>(initializer, "Colors", ColorsTaxonomyId, "Color");
     
         var taxon1 = initializer.TaxonomyManager.CreateTaxon<FlatTaxon>();
         taxon1.Title = "Red";
         taxon1.Name = "Red";
         var taxon2 = initializer.TaxonomyManager.CreateTaxon<FlatTaxon>();
         taxon2.Title = "Blue";
         taxon2.Name = "Blue";
         flatTaxonomy.Taxa.Add(taxon1);
         flatTaxonomy.Taxa.Add(taxon2);
     
         var type = metaMan.GetMetaType(typeof(ProductItem));
         if (type == null)
         {
             type = metaMan.CreateMetaType(typeof(ProductItem));
         }
     
         if (!type.Fields.ToList().Any(fld => fld.FieldName == "Colors"))
         {
             var field = metaMan.CreateMetafield("Colors");
             field.TaxonomyProvider = taxMan.Provider.Name;
             field.TaxonomyId = ColorsTaxonomyId;
             field.IsSingleTaxon = false;
             type.Fields.Add(field);
         }
     
         if (!type.Fields.ToList().Any(fld => fld.FieldName == "ProductImage"))
         {
             type.Fields.Add(ContentLinksExtensions.CreateContentLinkField("ProductImage", "OpenAccessDataProvider", metaMan, RelationshipType.OneToOne));
         }
     }
     
    protected override ConfigSection GetModuleConfig()
     {
         return Config.Get<ProductsConfig>();
     }
     
    protected override void InstallConfiguration(SiteInitializer initializer)
     {
         // Module widget is installed on Bootstrapper_Initialized
         initializer.Installer
             .PageToolbox()
                 .ContentSection()
                     .LoadOrAddWidget<ProductsView>("ProductsView")
                         .SetTitle("WidgetTitle")
                         .SetDescription("WidgetDescription")
                         .LocalizeUsing<ProductsResources>()
                         .Done()
                     .Done()
                 .Done()
             .AddWorkflowType<ProductItem>()
                 .SetTitle("ProductsTitle")
                 .LocalizeUsing<ProductsResources>()
                 .Done();
     }
     
    public override void Upgrade(SiteInitializer initializer, Version upgradeFrom)
     {
     }
     
    protected override void InstallTaxonomies(SiteInitializer initializer)
     {
         return;
     }

Next steps

+1-888-365-2779
sales@sitefinity.com

Related topics:

Feedback

How useful is this article?

Tell us more

Submit
Your message was successfully sent.

We appreciate your feedback.

Your message could not be sent.

OK