Developer forum

Forum » Development » Dynamicweb 10 - Custom module

Dynamicweb 10 - Custom module

Rene Poulsen
Rene Poulsen
Reply

Hi,

I'm trying to create a simple dummy content module for DW 10. I've placed the dll in the Files > System > AddIns and installed it afterwards. I also registered it under the Settings > Developer > Modules and checked "Paragraph module". The problem is, that the module does not show up, when I want to attach it to a paragraph.

My App inherits from ContentModule and I override the GetModuleContent() and return a "ContentOutputResult" where I've set the Model to a TestModel just containing a Headline and a BodyText. I might be missing something obvious as it's been a very long time since I've developed custom AddIns/Modules for DW :-)

My code is as simple as this:

using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Frontend;
using Dynamicweb.Modules;
using Dynamicweb.Rendering;

namespace Addins.TestApp
{
    [AddInName("TestApp")]
    [AddInActive(true)]
    [AddInAuthor("Rene Poulsen")]
    [AddInDescription("Just an app for testing a custom developed app for Dynamicweb 10")]
    public class TestApp : ContentModule
    {
        public override OutputResult GetModuleContent()
        {
            ContentOutputResult<TestModel>? outputResult = base.GetModuleContent() as ContentOutputResult<TestModel>;

            var testModel = new TestModel();
            testModel.Header = "Headline test...";
            testModel.BodyText = "Body text test...";

            outputResult.Model = testModel;

            return outputResult;
        }
    }

    public class TestModel : ViewModelBase
    {
        public string? Header { get; set; }
        
        public string? BodyText { get; set; }
    }
}


Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

Hi Rene,

You also need to implement a class which inherits from Dynamicweb.Application.UI.ContentModules.ContentModuleBaseAddIn.
The ContentModuleSystemName used in ContentModuleBaseAddIn must match the AddInName used in ContentModule.
You also need to implement the GetContentModuleSettings and LoadContentModuleSettings methods and convert to/from Properties.
See example below.

Note:
If you are installing this through the "Apps" section then you might run into issues if you are using a custom view model for rendering.
This is due to limitations in resolving types in the third party functionality which we are currently using for rendering razor templates in frontend.
As a workaround you can place the assembly (dll) in the application bin folder instead and everything should work as expected.
You can also just use template tags instead of a custom view model.

using Dynamicweb.Application.UI.ContentModules;
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Extensibility.Editors;
using Dynamicweb.Frontend;
using Dynamicweb.Modules;
using Dynamicweb.Rendering;

namespace DW10Custom.Modules
{
    public sealed class TestModel : ViewModelBase
    {
        public string? Header { get; set; }

        public string? BodyText { get; set; }
    }

    [AddInName(nameof(TestApp))]
    public sealed class TestApp : ContentModule
    {
        public override OutputResult GetModuleContent()
        {
            string templatePath = TemplateHelper.GetTemplatePath(Properties.GetValue(nameof(TestAppAddIn.Template)), TestAppAddIn.TemplateFolder);
            if (string.IsNullOrEmpty(templatePath))
                return ContentOutputResult.Empty;

            var template = new Template(templatePath);

            string header = Properties.GetValue(nameof(TestAppAddIn.Header));
            string bodyText = Properties.GetValue(nameof(TestAppAddIn.BodyText));

            var model = new TestModel()
            {
                Header = header,
                BodyText = bodyText
            };

            template.SetViewModel(model);

            string content = template.Output();

            return new Dynamicweb.Frontend.ContentOutputResult() 
            { 
                Content = content 
            };
        }
    }

    [ContentModuleSystemName(nameof(TestApp))] // The name here should match the one used for AddInName in the ContentModule implementation.
    public sealed class TestAppAddIn : ContentModuleBaseAddIn
    {
        public const string TemplateFolder = $"{nameof(TestApp)}/{nameof(TestModel)}";

        [AddInParameter(nameof(Header)), AddInParameterEditor(typeof(TextParameterEditor), "")]
        public string Header { get; set; } = "";

        [AddInParameter(nameof(BodyText)), AddInParameterEditor(typeof(TextParameterEditor), "")]
        public string BodyText { get; set; } = "";

        [AddInParameter(nameof(Template)), AddInLabel("Template"), AddInParameterEditor(typeof(TemplateParameterEditor), $"Folder=/Templates/{TemplateFolder}")]
        public string Template { get; set; } = "";

        public override string GetContentModuleSettings()
        {
            var properties = new Properties();

            properties[nameof(Header)] = Header;
            properties[nameof(BodyText)] = BodyText;
            properties[nameof(Template)] = Template;

            return properties.ToString();
        }

        public override void LoadContentModuleSettings(string moduleSettings)
        {
            var properties = new Properties();
            properties.LoadProperty(moduleSettings);

            Header = properties.GetValue(nameof(Header));
            BodyText = properties.GetValue(nameof(BodyText));
            Template = properties.GetValue(nameof(Template));
        }
    }
}

 

You must be logged in to post in the forum