Vulnerability in EPiServer.Forms
One of our client sites is an EPiServer 7.19 site using Webforms, with a (non-EPiServer) login system which was developed by a third party. As part if this, there are emails for activation, resetting passwords, new passwords etc. These are static HTML files with various placeholders for username etc. which are filled out by MailDefinition properties before being sent.
Our clients have asked if it's possible for these mails to be editable via CMS, and I'm struggling to find a way to do this. I'm guessing the best approach would be to somehow do the following:
However, I'm stuck trying to find a solution for #1, particularly one which works with WebForms rather than Razor/MVC. I know that if I have a Control object, then I can easily render this to string, but can't find a way to get from PageReference/URL to Control. Is it even possible to get a Control object, outside of the page currently being rendered?
The afforementioned third-party code does use a CMS page as an email source in one instance, but do this by opening a new tab, rendering the email as a page, then emailing it via code behind and closing the tab, which is a poor user experience, particularly on mobile.
I would create a new pagetype for email template containing properties for subject, body, from etc. Then add property like you are thinking to the page which needs the template.
Then I would simply get the properties in code behind (event handler for button.Click event) and construct the email.
var emailTemplate =contentRepo.Get<EmailTemplate>( currentPage.EmailLink);
...Handle replacement of custom tags for user name etc
Hmm, a variation on that might work, but the use case is a bit more complicated. We can't just use tinyMCE output for the body, as a) the emails are quite structured, and b) in order to cope with the godawful HTML rendering of Outlook 2010 and 2013 (they use Microsoft Word to render - really), the code needs to be slathered with inline CSS.
My plan was to have an EPiServer template based on the current static HTML, and just make select fields editable (e.g. Title, Lead, LinkButtonText, LinkButtonTarget). That would give a nice preview for edit mode, then could just be rendered to HTML for mailing out.
I guess as a fallback I could persist with the static .html templates but add additional placeholders for the CMS editable items, then just inject these directly from the Page Properties. This would certainly work from a back-end perspective, but getting a nice edit preview might be trickier (but not impossible).
Ok. Then maybe let editors have a few simple fields to change heading etc that are editor friendly but save the overall html in a separate property in an another tab...maybe just a text area with placeholders both for editor inserted texts like heading and links etc and for generated fields like current user email etc. Then you use a more or less empty masterpage and just dump out the html in an asp literal to render a preview to editors?
You could mix in some MVC for your email templates. They will have a completely different layout (masterpage) than the rest of the site, so it shouldn't matter.
Then use Postal (http://aboutcode.net/postal/) to help you render a view for a page as an email. Use Premailer.Net (https://github.com/milkshakesoftware/PreMailer.Net) to handle the css / attribute (inlining) nightmare for you. To make your life even easier, go for an existing email template system like Foundation for Emails (http://foundation.zurb.com/emails/email-templates.html) to help you craft the layout.
The rest is about parsing the XHtml for placeholders (if needed, the view would render the other properties from the page just as for a regular page). You might want to have several email page types and templates for the different types of email to keep it clean and tidy.
Note! Episerver will insist on relative urls in the markup, so you need to do a search and replace on href and src attributes, and prepend the host url to the links and image sources.
This is how it is done on the Epic Photo site (https://github.com/bvnetwork/CommerceStarterKit). Search for .html.cshtml (Postal) views and use of Premailer in code.
Imo the eaisiest way would be to just do a WebClient-request to the page. Something like (code not tested):
var page = _contentLoader.Get<EmailTemplate>(pageRefToForgotPasswordPage);
var client = new WebClient();
var emailStr = client.DownloadString(page.LinkUrl);
emailStr = emailStr.ReplacePlaceholdersWithData();
Maybe not the prettiest solution, but it should work.. :)
Erik, that also works, and you should run Premailer.Net on the result to inline the styles.
The open source Newsletter module does exactly that, with some workarounds for the host url generation from a scheduled job.