ITemplatablePlugin not allowing different templates?

I am trying to create an ITemplatablePlugin that has 6 different templates.  I have set them up, but when it renders in the plugin, it appears it only is allowing 4 different types of templates:

If I rename the keys or omit and only have one "DefaultTemplate" defined, I see this dropdown?  Is this a limitation of ITemplatablePlugin?

  • I'm not able to reproduce, can you share your code?

  •         public Telligent.Evolution.Extensibility.Version1.TokenizedTemplate[] DefaultTemplates
            {
                get
                {
                    var subjectTemplate = new TokenizedTemplate("email_subject")
                    {
                        Name = "Email - Subject",
                        Description = "This is the subject for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    subjectTemplate.Set("en-us", @"<template id=""email_subject"" name=""Email - Subject"" description=""This is the subject for the email"">
                                        <source>Badge Awarded Notification</source>
                                        <fragments />
                                    </template>");
    
                    var bodyTemplate = new TokenizedTemplate("email_body")
                    {
                        Name = "Email - Body",
                        Description = "Session Email Body",
                        ContextualDataTypeIds = new[]
                        {
                             Apis.Get<IUsers>().ContentTypeId,
                             Components.Courses.CONTENT_TYPE_ID,
                             Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    bodyTemplate.Set("en-us", @"<template id=""email_body"" name=""Email - Session 1 Body"" description=""This is the body for Session 1"">
                                        <source>Session content is available.</source>
                                        <fragments />
                                    </template>");
    
                    var headerTemplate = new TokenizedTemplate("email_header")
                    {
                        Name = "Email - Header",
                        Description = "This is the header for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    headerTemplate.Set("en-us", @"<template id=""email_header"" name=""Email - Header"" description=""This is the header for the email"">
                                                    <source>Header for MyNotificationType (not shown in the default email template wrapper)</source>
                                                    <fragments />
                                                </template>");
                    var footerTemplate = new TokenizedTemplate("email_footer")
                    {
                        Name = "Email - Footer",
                        Description = "This is the footer for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    footerTemplate.Set("en-us", @"<template id=""email_footer"" name=""Email - Footer"" description=""This is the footer for the email"">
                                            <source>Footer for MyNotificationType</source>
                                            <fragments />
                                        </template>");
                    return new[] { subjectTemplate, bodyTemplate, headerTemplate, footerTemplate };
                }
            }

  • So if I try add a template, or return like this:
    return new[] { subjectTemplate };

    I still see 4 options in the dropdown.

  • Here is the entire thing. 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Telligent.DynamicConfiguration.Components;
    using Telligent.Evolution.Extensibility;
    using Telligent.Evolution.Extensibility.Api.Entities.Version1;
    using Telligent.Evolution.Extensibility.Api.Version1;
    using Telligent.Evolution.Extensibility.Jobs.Version1;
    using Telligent.Evolution.Extensibility.Templating.Version1;
    using Telligent.Evolution.Extensibility.Version1;
    
    namespace HearingFirst.LearningExperience.Jobs
    {
        public class SessionContentReminderJob : IRecurringEvolutionJobPlugin, ITemplatablePlugin, IConfigurablePlugin
        {
            #region Private Members
            private ITemplatablePluginController _templatablePluginController;
            private IPluginConfiguration _config;
            #endregion
            #region IPlugin Members
            public string Name => "Hearing First - Session 1 Content Reminder Job";
    
            public string Description => "Sends email reminders the day before session 1 pre-learning content opens.";
    
            public void Initialize(){ }
            #endregion
            #region IRecurringEvolutionJobPlugin Members
            public Guid JobTypeId => Guid.Parse("BBBD2ADB-E4FD-4363-8A9F-B99B75D8767B");
    
            public JobSchedule DefaultSchedule => JobSchedule.Daily();
    
            public JobContext SupportedContext => JobContext.InProcess;
    
            public void Execute(JobData jobData)
            {
                var omittedGroupIds = this.GetOmittedGroupIds();
    
                var sessions = Components.Sessions.ListActivatedSessions();
                foreach (var session in sessions)
                {
                    if (session.SortOrder.Equals(1))
                    {
                        var course = Components.Courses.Get(session.CourseId);
    
                        if (!omittedGroupIds.Contains(course.GroupId))
                        {
                            var liveSessions = Components.Sessions.GetLiveSessions(session.Id);
                            if (liveSessions.Count() > 0)
                            {
                                var date = liveSessions.First();
                                course.NextLiveSessionDateDynamic = date.ExperienceDateTime;
                            }
    
                            // Loop through all group members and send the reminder email
                            List<int> userIds = new List<int>();
                            var members = Apis.Get<IGroupUserMembers>().List(new GroupUserMembersListOptions { GroupId = course.GroupId, PageIndex = 0, PageSize = 1, MembershipType = "Member" });
                            int memberPages = (members.TotalCount / 100) + 1;
                            for (int x = 0; x < memberPages; x++)
                            {
                                var memberQuery = Apis.Get<IGroupUserMembers>().List(new GroupUserMembersListOptions { GroupId = course.GroupId, PageIndex = x, PageSize = 100, MembershipType = "Member" });
                                var ids = (from m in memberQuery select m.User.Id.Value).ToList();
                                userIds.AddRange(ids);
                            }
    
                            // Now loop through the userIds and queue an email
                            foreach (var uid in userIds)
                            {
                                var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Id = uid });
                                this.SendSessionNotification(user, course, session);
    
                                // If we're in debug mode, only send one.
                                if (this.IsDebug()) break;
                            }
                        }
                    }
                }
            }
            #endregion
            #region ITemplatablePlugin Members
    
            public Telligent.Evolution.Extensibility.Version1.TokenizedTemplate[] DefaultTemplates
            {
                get
                {
                    var subjectTemplate = new TokenizedTemplate("email_subject")
                    {
                        Name = "Email - Subject",
                        Description = "This is the subject for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    subjectTemplate.Set("en-us", @"<template id=""email_subject"" name=""Email - Subject"" description=""This is the subject for the email"">
                                        <source>Badge Awarded Notification</source>
                                        <fragments />
                                    </template>");
    
                    var bodyTemplate = new TokenizedTemplate("email_body")
                    {
                        Name = "Email - Body",
                        Description = "Session Email Body",
                        ContextualDataTypeIds = new[]
                        {
                             Apis.Get<IUsers>().ContentTypeId,
                             Components.Courses.CONTENT_TYPE_ID,
                             Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    bodyTemplate.Set("en-us", @"<template id=""email_body"" name=""Email - Session 1 Body"" description=""This is the body for Session 1"">
                                        <source>Session content is available.</source>
                                        <fragments />
                                    </template>");
    
                    var headerTemplate = new TokenizedTemplate("email_header")
                    {
                        Name = "Email - Header",
                        Description = "This is the header for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    headerTemplate.Set("en-us", @"<template id=""email_header"" name=""Email - Header"" description=""This is the header for the email"">
                                                    <source>Header for MyNotificationType (not shown in the default email template wrapper)</source>
                                                    <fragments />
                                                </template>");
                    var footerTemplate = new TokenizedTemplate("email_footer")
                    {
                        Name = "Email - Footer",
                        Description = "This is the footer for the email",
                        ContextualDataTypeIds = new[]
                        {
                            Apis.Get<IUsers>().ContentTypeId,
                            Components.Courses.CONTENT_TYPE_ID,
                            Components.Sessions.CONTENT_TYPE_ID
                        },
                    };
                    footerTemplate.Set("en-us", @"<template id=""email_footer"" name=""Email - Footer"" description=""This is the footer for the email"">
                                            <source>Footer for MyNotificationType</source>
                                            <fragments />
                                        </template>");
                    return new[] { subjectTemplate, bodyTemplate, headerTemplate, footerTemplate };
                }
            }
    
            public void SetController(ITemplatablePluginController controller)
            {
                _templatablePluginController = controller;
            }
    
            public void SendSessionNotification(User user, Entities.Course course, Entities.Session session)
            {
                if (this.IsDebug())
                {
                    var debugUsername = this.GetDebugUsername();
    
                    if (!String.IsNullOrEmpty(debugUsername))
                    {
                        user = Apis.Get<IUsers>().Get(new UsersGetOptions { Username = debugUsername });
    
                    }
                }
                if (user != null)
                {
                    // Create the Template Context and add the user and group to it
                    var templateContext = new TemplateContext();
                    templateContext.AddItem(Apis.Get<IUsers>().ContentTypeId, user);
                    templateContext.AddItem(Components.Courses.CONTENT_TYPE_ID, course);
                    templateContext.AddItem(Components.Sessions.CONTENT_TYPE_ID, session);
    
                    // Send the email with the details specified. If run from the web process, this will schedule a job to send the email,
                    //  meaning the Job Service must be running for the email to actually go out.
    
                    if (this.SendConversationMessages())
                    {
    
                        string subject = _templatablePluginController.RenderTokenString("email_subject", templateContext);
                        var body = _templatablePluginController.RenderTokenString("email_body", templateContext);
    
                        Apis.Get<IConversations>().Create(subject, subject + body, this.GetConversationFromUsername() + "," + user.Username);
                    }
                    else
                    {
                        var sendOptions = new SendEmailOptions
                        {
                            ToUserId = user.Id.Value,
                            Subject = _templatablePluginController.RenderTokenString("email_subject", templateContext),
                            Body = _templatablePluginController.RenderTokenString("email_body", templateContext),
                            Header = _templatablePluginController.RenderTokenString("email_header", templateContext),
                            Footer = _templatablePluginController.RenderTokenString("email_footer", templateContext)
                        };
                        Apis.Get<ISendEmail>().Send(sendOptions);
                    }
                }
            }
            
            #endregion
            #region IConfigurable Plugin Members
            public PropertyGroup[] ConfigurationOptions
            {
                get
                {
                    var options = new PropertyGroup("options", "Options", 0);
                    var sendConversations = new Property("SendConversations", "Send Conversations:", PropertyType.Bool, 1, "")
                    {
                        DescriptionText = "Sends conversations instead of emails.  Leaving un-checked will send emails only."
                    };
                    options.Properties.Add(sendConversations);
    
                    var sendConversationUsername = new Property("SendConversationUsername", "Send Conversation Username:", PropertyType.String, 1, "hearingfirst")
                    {
                        DescriptionText = "Username of the user sending the conversation reminders."
                    };
                    options.Properties.Add(sendConversationUsername);
    
                    var omitGroupIds = new Property("OmitGroupIds", "Omit Group Ids:", PropertyType.String, 1, "")
                    {
                        DescriptionText = "CSV list of group ids that will not get these communications."
                    };
                    options.Properties.Add(omitGroupIds);
    
                    var isDebug = new Property("IsDebugMode", "Debug Mode:", PropertyType.Bool, 1, "")
                    {
                        DescriptionText = "Run the job in debug mode."
                    };
                    options.Properties.Add(isDebug);
    
                    var debugUsername = new Property("DebugUsername", "Debug Username:", PropertyType.String, 1, "")
                    {
                        DescriptionText = "Username that will recieve all messages when in debug mode."
                    };
                    options.Properties.Add(debugUsername);
    
                    return new[] { options };
                }
            }
    
            public void Update(IPluginConfiguration configuration)
            {
                _config = configuration;
            }
            public string GetConfigurationString(string key)
            {
                return _config.GetString(key);
            }
            public int GetConfigurationInt(string key)
            {
                return _config.GetInt(key);
            }
            public bool SendConversationMessages()
            {
                return _config.GetBool("SendConversations");
            }
            public bool IsDebug()
            {
                return _config.GetBool("IsDebugMode");
            }
            public string GetDebugUsername()
            {
                return this.GetConfigurationString("DebugUsername");
            }
            public string GetConversationFromUsername()
            {
                return this.GetConfigurationString("SendConversationUsername");
            }
            public List<int> GetOmittedGroupIds()
            {
                string csvList = GetConfigurationString("OmitGroupIds");
                if (!String.IsNullOrEmpty(csvList))
                {
                    return csvList.Split(',').Select(int.Parse).ToList();
                }
                return new List<int>();
            }
    
            #endregion
        }
    }
    

  • It's working in 9.2, assuming you're running 9.0?

  • It just seems like the dropdown UX in the plugin configuration area in administration is looking for 4 hard-coded template IDs

  • Using your code, I'm still unable to reproduce the issue in 9.0.  I've taken your code and just updated it to work in my environment and stripped out anything not implemented by ITemplatablePlugin and changed the ContextualDataTypeIds so it would build locally.  

  • Could it be a license issue?  I"m running locally and says my installed license is expired.

  • No, I didn't have a license installed at all for this test.