Skip to content

Instantly share code, notes, and snippets.

@PaulGruffyddAmaze
Last active August 9, 2019 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PaulGruffyddAmaze/6ce76f3c6ffb78f0b568c3a2f0998c06 to your computer and use it in GitHub Desktop.
Save PaulGruffyddAmaze/6ce76f3c6ffb78f0b568c3a2f0998c06 to your computer and use it in GitHub Desktop.
Templating emails from Episerver Forms
public class CustomSendEmailAfterSubmissionActor : SendEmailAfterSubmissionActor
{
private Injected<IContentLoader> _contentLoader;
private string _contentPlaceholder = "#CONTENT#";
public override Type PropertyType => typeof(PropertyTemplatableEmailActor);
public override object Run(object input)
{
var emailList = Model as IEnumerable<TemplatableEmailTemplateActorModel>;
foreach (var email in emailList)
{
// Load the template in the correct language, allowing for fallbacks
var languageLoaderOptions = new LoaderOptions();
languageLoaderOptions.Add(new LanguageLoaderOption { FallbackBehaviour = LanguageBehaviour.FallbackWithMaster, Language = new System.Globalization.CultureInfo((input as EPiServer.Forms.Core.Models.FormIdentity).Language) });
if (email.EmailTemplateId > 0 && _contentLoader.Service.TryGet(new ContentReference(email.EmailTemplateId), languageLoaderOptions, out EmailTemplateBlock emailTemplateBlock) && email.Body != null)
{
email.Body = new XhtmlString(emailTemplateBlock.Content.Replace(_contentPlaceholder, email.Body.ToHtmlString()));
}
}
return base.Run(input);
}
}
/// <summary>
/// Property definition for the Actor
/// </summary>
[EditorHint("TemplatableEmailActorPropertyHint")]
[PropertyDefinitionTypePlugIn(DisplayName = "TemplatableEmail")]
public class PropertyTemplatableEmailActor : PropertyGenericList<TemplatableEmailTemplateActorModel> { }
/// <summary>
/// Editor descriptor class, for using Dojo widget CollectionEditor to render.
/// Inherit from <see cref="CollectionEditorDescriptor"/>, it will be rendered as a grid UI.
/// </summary>
[EditorDescriptorRegistration(TargetType = typeof(IEnumerable<TemplatableEmailTemplateActorModel>), UIHint = "TemplatableEmailActorPropertyHint")]
public class ConfigurableActorEditorDescriptor : CollectionEditorDescriptor<TemplatableEmailTemplateActorModel>
{
public ConfigurableActorEditorDescriptor()
{
// N.B. This is a special ClientEditingClass just for the EmailTemplateActorModel.
// Using the expected value of "epi-forms/contentediting/editors/CollectionEditor" will display incorrectly
ClientEditingClass = "epi-forms/contentediting/editors/EmailTemplateActorEditor";
}
}
[ContentType(DisplayName = "Email Template", GUID = "03daf669-5884-47f2-840f-04056afc9536", Description = "Content type for adding email templates")]
public class EmailTemplateBlock : BlockData
{
[CultureSpecific]
[Display(
Name = "Content",
Description = "The HTML/Text content of the email, use #CONTENT# to represent the editable section of the email",
GroupName = SystemTabNames.Content,
Order = 20)]
[UIHint(UIHint.Textarea)]
public virtual string Content { get; set; }
}
[TemplateDescriptor(
Inherited = true,
TemplateTypeCategory = TemplateTypeCategories.MvcController, //Required as controllers for blocks are registered as MvcPartialController by default
Tags = new[] { RenderingTags.Preview, RenderingTags.Edit },
AvailableWithoutTag = false)]
[VisitorGroupImpersonation]
[RequireClientResources]
public class EmailTemplatePreviewController : ActionControllerBase, IRenderTemplate<EmailTemplateBlock>
{
public EmailTemplatePreviewController()
{
}
public ActionResult Index(EmailTemplateBlock currentContent)
{
// Display the template with some dummy content
return Content((currentContent.Content ?? string.Empty).Replace("#CONTENT#", "<p><strong>Lorem ipsum dolor sit amet</strong>,<br/> consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>"));
}
}
public class EmailTemplateSelectionFactory : ISelectionFactory
{
public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
yield return new SelectItem { Text = "None", Value = 0 };
var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();
var contentTypeRepo = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
var templateType = contentTypeRepo.Load("EmailTemplateBlock");
var content = contentModelUsage.ListContentOfContentType(templateType) //Get all instances of EmailTemplateBlock
.GroupBy(x => x.ContentLink.ID).Select(x => x.First()) //Remove duplicates
.OrderBy(x => x.Name); //Order alphabetically by name
foreach (var item in content)
{
yield return new SelectItem { Text = item.Name, Value = item.ContentLink.ID };
}
}
}
[EditorDescriptorRegistration(
TargetType = typeof(IEnumerable<EmailTemplateActorModel>),
UIHint = "EmailTemplateActorEditor",
EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault)]
public class EmailTemplateActorEditorDescriptor : CollectionEditorDescriptor<EmailTemplateActorModel>
{
public EmailTemplateActorEditorDescriptor()
{
}
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
{
metadata.ShowForEdit = false;
}
}
public class TemplatableEmailTemplateActorModel : EmailTemplateActorModel
{
[Display(
Name = "Template",
Order = 9999)]
[SelectOne(SelectionFactoryType = typeof(EmailTemplateSelectionFactory))]
public virtual int EmailTemplateId { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment