RSS feed for blog Linkin Skype Mail Me Twitter


Editable salesforce templates

Editing an email that is generated via an Saleforce email template BEFORE it is sent is something that I have had a few clients grumble over, the feature is baked into the Quote object which makes sense, but you try telling clients they cant have it for Order objects….

So this is a basic solution that gets round this problem and is the basic set-up for expanding it to solve all the issues, in this case I am solving the most common issue I have come access, in that you are generating a order recept or delivery note pdf using the ‘renderAs=”PDF”’ option in an email template and want to send the email with a custom message to one or more people that you decide at the time of sending.

To do that we are going to create a new visual force page that resembles a normal email and use it to fill in the details before we generate the email template


1) Create a new email custom object

This is just a basic object with the fields we need for the email, and a lookup field to the parent Order

New Custom Email Object

Note: For brevity I’m leaving out the creation of the layout for the custom object and the adding of the related list to the Order Layout

2) Add some extra Fields to your Order object

These are the temporary fields that we are using to actually send the template email, resist the urge to set the To/CC/BCC as email fields as that will stop you having multiple recipients.

Extra Fields

Obviously these fields have to be editable to all but not part of the order layouts so they don’t show up.

3) Create a new “Template Editor” Visualforce Page

This page is as simple or complex as you can want it, my one here takes email address separated by a comma but yours can be a really posh contact lookup

<apex:page controller="sendOrderPDFEmail">
    <apex:messages />
    <apex:pageBlock title="Email for Order: {!order.Name}">
    <p>Fill out the fields below and click "Send email"</p>
    <apex:form ><br/><br/>

        <apex:outputLabel value="Template To Attach" for="chooseTemplate"/>: <br/>
        <apex:selectList id="chooseTemplate" value="{!template}" size="1">
            <apex:selectOption itemValue="Template1" itemLabel="Template1"/>
            <apex:selectOption itemValue="Template2" itemLabel="Template2"/>
            <apex:selectOption itemValue="Template3" itemLabel="Template3"/>
        <apex:outputLabel value="To" for="To"/>: <br/>
        <apex:inputText value="{!to}" id="To" maxlength="255" style="width: 300px;"/>
        <apex:outputLabel value="CC" for="CC"/>: <br/>
        <apex:inputText value="{!cc}" id="CC" maxlength="255" style="width: 300px;"/>
        <apex:outputLabel value="BCC" for="BCC"/>: <br/>
        <apex:inputText value="{!bcc}" id="BCC" maxlength="255" style="width: 300px;"/>
        <apex:outputLabel value="Subject" for="Subject"/>: <br/>
        <apex:inputText value="{!subject}" id="Subject" maxlength="255" style="width: 500px;"/>
        <apex:outputLabel value="Body" for="Body"/>: <br/>        
        <apex:inputTextarea value="{!body}" id="Body" richText="true" rows="20"/>
        <apex:commandButton value="Send Email" action="{!send}"/>

4) Create the “Send” code (don’t forget to create your test code).

I have just put comments on the code, as its not complex and follows the flow chart at the top of the blog.

public class sendOrderPDFEmail {

    public String template { get; set; }
    public String cc { get; set; }
    public String bcc { get; set; }
    public String to { get; set; }
    public String subject { get; set; }
    public String body { get; set; }
    public Account contactLookup { get; set; }
    private final Order order;

    public sendOrderPDFEmail() {
        //Get the Id of the order that we are working on
        template = '';
        String OrderId = ApexPages.currentPage().getParameters().get('id');
        order = [SELECT Name, ID
        FROM Order
        WHERE Id = :OrderId];

    public Order getOrder() {
        return order;

    public PageReference send() {
    if( !String.isBlank(cc)) {
        cc = cc.trim();
    if( !String.isBlank(bcc)) {
        bcc = bcc.trim();
    if( !String.isBlank(to)) {
        to = to.trim();
    //Mail email Order object
    orderemail__c con = new orderemail__c(
    insert con;

    //Store the temp values in the Order
    update order;

    if ( String.isBlank(to) ) {
         to = '';
     // Construct the list of emails we want to send
     List<Messaging.SingleEmailMessage> lstMsgs = new List<Messaging.SingleEmailMessage>();
     Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
     //set the email tempalte from the name chossen on the email form
     EmailTemplate[] emailTemplate = [select id from EmailTemplate where Name=:template];
     if (emailTemplate.size() > 0) {
          msg.setTemplateId( emailTemplate[0].id );
     } else {
         msg.setPlainTextBody('No Template Provided');

     // Trim and convert the comma delimted string to a suitable recipiant list for the email.
     String[] trimmedtoarray;
     if (!String.isBlank(to)) {
        String[] toarray = to.split(',');
        trimmedtoarray = new String[toarray.size()];
        Integer k = 0;
        for (String singlEmail: toarray) {
           trimmedtoarray[k++] = singlEmail.trim();
     if (!String.isBlank(cc)) {
         String[] ccarray = cc.split(',');
         String[] trimmedccarray = new String[ccarray.size()];
         Integer i = 0;
         for (String singlEmail: ccarray) {
             trimmedccarray[i++] = singlEmail.trim();
     if (!String.isBlank(bcc)) {
         String[] bccarray = bcc.split(',');
         String[] trimmedbccarray = new String[bccarray.size()];
         Integer j = 0;
         for (String singlEmail: bccarray) {
            trimmedbccarray[j++] = singlEmail.trim();
     // Templates do need an object (Contact that he pdf will be used to generate against) for things like first name etc
     // So we are going to pick the first contact on the to list.
     Contact c = [select id, Email from Contact where email = :trimmedtoarray[0] limit 1];
     msg.setWhatId( );

     //Send the email

    // clear out the temp fields we used to generate the email.
    update order;
        //Send the user back to the Order
        PageReference backToQuotePage = new PageReference('/' +;
        return backToQuotePage;

5) Create a button in the Order object to launch your “Email” screen

End Email Button

6) Update your Email template

Now update your email templates to use the “le_Body__c” and “le_Subject__c” fields for their email contents,

<messaging:emailTemplate recipientType="Contact"
    <messaging:htmlEmailBody >

        <c:EmailStyle />
            <apex:outputText value="{!RelatedTo.le_Body__c}" escape="false"/>

    <messaging:plainTextEmailBody >
    <apex:outputText value="{!RelatedTo.le_Body__c}" escape="false"/>

<messaging:attachment renderAs="PDF" filename="GeneratedEmail.pdf">
      @page {
      size: A4 landscape;
      margin-top: 1.0cm;
      margin-left: 1.0cm;
      margin-right: 1.0cm;
      margin-bottom: 7cm;
        @bottom-center {
          content: element(footer);


        <c:EmailStyle />




So PDF’s generated by Email templates in Salesforce are not saved and you cant get hold of them, so we are not saving them in the custom email object, if you do need that, then you will need to convert your email templates to visual force pages then render as PDFs and save them in the custom objects.

Leave Your Comments

blog comments powered by Disqus

Related Entries

Missing A Conference

Salesforce: Same Code Different Triggers

Remote Desktop while away

MWLug 2016 Round-Up

To Find The Perfect Office

A Little Thing Done Right

SalesForce for Domino Dogs 3: Web Query Save Agents

Presenting at MWLUG

SalesForce for Domino Dogs 2: Scheduled Agents

SalesForce for Domino Dogs 1: Profile Documents

New Platform Type New Client Type

Engage 2016

LDCVia Webinar

Current Android Software 2015

Salesforce read mode hide-when hack

Classic Domino and multi country dates with Bootstrap

C3 charts on Saleforce Winter16

Updating Statamic on AWS

Icon UK 2015

Quiet Isnt it

Engage 2015

Conditional Checking in AngularJs using Restangular

IBM ConnectED2015 All work and no play

Learning A Lesson About Security from other People

2014 A Year In Review

IBM Connections Dev Update to V5

W.T.F. they made me an IBM Champion and a C-API tip

Bloody Android Kit-Kat and SD Cards

LDC Via Cross Post: Why oh why oh why (Part One)

Applet security: a blast from the past

UK ICON 2014

jQuery UK 2014 Day 2

jQuery UK 2014 Day 1

London Node.js User Group April 2014

Listen while you work

SQuirrel SQL For IBM Connections

Living Document: Connections Db Schema Versions

Connections Db Schema Tip2: Finding the UserID

Working from anywhere

Connections Db Tip1: getting the Connections db Schema version

CSC Event No.1

Engage 2014

IBM Connections Dev Links

Collaboration Stack Community Agenda and Stuff

Connections aide memoire 02: Backing Up Websphere Config

Inserting HTML into word documents

Connections aide memoire 01: Changing XML config

IBM Connect 2014 Slide Decks

IBM Connect 2014 Round up

Finding Me at IBM Connect 2014

Collaboration Stack Event

Commuting tip for Developers

My IBM Connect 2014 Sessions

IBM Connect 2014 session

Best USB Cable

The Perfect Consultant

First Tuesday Club November 2013

Latest Blogs