Creating placeholders for EPiServer Forms

EPiServer Form's EmailActor comes with a "summary" placeholder that allows you to list all form fields and their values. If you're using EPiServer Forms 4.3 or higher, you can create additional placeholders using Placeholder API.

Code behind the "summary" placeholder can be found in DefaultPlaceHolderProvider class, inside EPiServer.Forms.Core.Internal namespace.

We will create a new placeholder provider with the following placeholders:

  • Page name
  • Page ID
  • Page URL
  • Language branch
  • Username of the form submitter
  • Browser UserAgent

To register a new placeholder provider, we have to create a class that implements IPlaceHolderProvider interface.

public class PageInfoPlaceholderProvider : IPlaceHolderProvider
    private readonly IContentLoader _contentLoader;

    public PageInfoPlaceholderProvider()
        _contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

    public const string PageName = "page_name";
    public const string PageId = "page_id";
    public const string PageUrl = "page_url";
    public const string LanguageBranch = "language_branch";
    public const string User = "user";
    public const string BrowserUserAgent = "browser_user_agent";

    public int Order
        // place above "summary" placeholder (Order = 1000)
        get { return 900; }
        set { }

    public IEnumerable<PlaceHolder> ExtraPlaceHolders => new[]
        new PlaceHolder(PageName, string.Empty),
        new PlaceHolder(PageId, string.Empty),
        new PlaceHolder(LanguageBranch, string.Empty),
        new PlaceHolder(User, string.Empty),
        new PlaceHolder(PageUrl, string.Empty),
        new PlaceHolder(BrowserUserAgent, string.Empty)

    public IEnumerable<PlaceHolder> ProcessPlaceHolders(
        IEnumerable<PlaceHolder> availablePlaceHolders,
        FormIdentity formIden,
        HttpRequestBase requestBase = null,
        Submission submissionData = null,
        bool performHtmlEncode = true)
        Validator.ThrowIfNull("formIden", formIden);
        Validator.ThrowIfNull("submissionData", submissionData);
        Validator.ThrowIfNull("availablePlaceHolders", availablePlaceHolders);

        string languageBranch = submissionData

        string user = submissionData

        int pageId = int.Parse(submissionData

        var placeHolders = availablePlaceHolders as PlaceHolder[]
                            ?? availablePlaceHolders.ToArray();

        foreach (var placeholder in placeHolders)
            if (placeholder.Key == PageName)
                IContent hostedPage;
                if (_contentLoader.TryGet(
                    new ContentReference(pageId),
                    new CultureInfo(languageBranch),
                    out hostedPage))
                    placeholder.Value = hostedPage.Name;
            if (placeholder.Key == PageId)
                placeholder.Value = pageId.ToString();
            if (placeholder.Key == LanguageBranch)
                placeholder.Value = languageBranch;
            if (placeholder.Key == User)
                placeholder.Value = user;
            if (placeholder.Key == PageUrl && requestBase?.UrlReferrer != null)
                placeholder.Value = requestBase.UrlReferrer.AbsoluteUri;
            if (placeholder.Key == BrowserUserAgent && requestBase?.UserAgent != null)
                placeholder.Value = requestBase.UserAgent;

        return placeHolders;

Please note that placeholder providers don't support constructor injection, so we have to resolve dependencies using ServiceLocator.

If you now create a Form and navigate to the Settings tab in All Properties views, you should be able to insert our new placeholders when creating email templates.

Episerver forms placeholders

Email template:

Episerver forms - email actor


Episerver forms - email actor - email

comments powered by Disqus