function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
paul-lmipaul-lmi 

using merge fields in a visualforce email template

i understand that it's possible to pull the related object info into the body of the email, but is it possible to pull related object info into the subject line.

 

Here's an example which works, because it's a non-dynamic subject line:

 

<messaging:emailTemplate subject="A non-dynamic subject" recipientType="Contact" relatedToType="Case"> <messaging:plainTextEmailBody > Congratulations! This is your new Visualforce Email Template. </messaging:plainTextEmailBody> </messaging:emailTemplate>

 This is what i'd like to do

 

<messaging:emailTemplate subject="{!case.product__c} Case: {!case.casenumber} - {!case.subject}" recipientType="Contact" relatedToType="Case"> <messaging:plainTextEmailBody > Congratulations! This is your new Visualforce Email Template. </messaging:plainTextEmailBody> </messaging:emailTemplate>

 

 but when saving, salesforce complains about the Case controller.

 

Best Answer chosen by Admin (Salesforce Developers) 
gtuerkgtuerk

<messaging:emailTemplate recipientType="User"
relatedToType="Capital_Subproject__c"
subject="Capital Subproject: {!relatedTo.Name} requires approval">

 

use the !relatedTo syntax

 

<messaging:emailTemplate subject="{!relatedTo.product__c} Case: {!relatedTo.casenumber} - {!relatedTo.subject}" recipientType="Contact" relatedToType="Case">
<messaging:plainTextEmailBody >
Congratulations!
This is your new Visualforce Email Template.
</messaging:plainTextEmailBody>
</messaging:emailTemplate>

 

Message Edited by gtuerk on 05-06-2009 03:40 PM

All Answers

gtuerkgtuerk

<messaging:emailTemplate recipientType="User"
relatedToType="Capital_Subproject__c"
subject="Capital Subproject: {!relatedTo.Name} requires approval">

 

use the !relatedTo syntax

 

<messaging:emailTemplate subject="{!relatedTo.product__c} Case: {!relatedTo.casenumber} - {!relatedTo.subject}" recipientType="Contact" relatedToType="Case">
<messaging:plainTextEmailBody >
Congratulations!
This is your new Visualforce Email Template.
</messaging:plainTextEmailBody>
</messaging:emailTemplate>

 

Message Edited by gtuerk on 05-06-2009 03:40 PM
This was selected as the best answer
paul-lmipaul-lmi

thanks.  i was too trigger happy to post.

 

so i hit another issue though.  i can't seem to pull {!relatedto.solution_description} , which is technically a standard case merge field.

 

I'm essentially trying to create an email template that can have custom HTML styling, not just the crappy letterhead logo nonsense that almost every email client blocks the images on by default, and also have the user sending it be able to customize the text of.

 

to add on even more, i need for the user to be able to send solutions from cases with this, so it's not just generic merge data.

paul-lmipaul-lmi

argh, every way i try this there's a caveat.

 

using "custom" email template type, the sender can't edit the message at all

 

using "HTML" email template type, it's not actually HTML but rich text, and uses the letterhead, which is really just an image.

 

using "visualforce" email template type, i can stylize it any way i want, but again, the user can't customize anything in the template before they send it.

 

i give up.  i guess the "html" type, even though it's neither real HTML nor very flexible, is the only option i have here that isn't plain text.

gtuerkgtuerk

Sounds like you need a custom class to get the related data.  I built one of these for a nicely styled (albeit inline) VF Email template a couple of months back.  I just tried to find the code for that in one of my previous posts but no luck.  This won't help you with preview/send, but should help with getting other data related to the case.  So here it is:

 

public class CapitalProjectController {

private List<Opportunity> relatedOpportunity;
//I can't get these controllers to work in email templates without making lists of the objects
private List<Capital_Project__c> myCapitalProject;
public Id ProjectID{get;set;}
private List<Capital_Subproject__c> mySubProjects;

public List<Opportunity> getRelatedOpportunity(){
relatedOpportunity = [select id, name, AccountId, Amount,NRR__c, Term_In_Months__c, A_end_state__c, Z_end_state__c
from Opportunity where id in
(select Opportunity__c from Capital_Project__c where id = :ProjectID)];
return relatedOpportunity;
}

public List<Capital_Project__c> getMyCapitalProject(){
myCapitalProject = [select id, name, opportunity__c, status__c, notes__c, project_class__c, project_Name__c,
Amount_Approved__c, ICB_Approved_Amount__c, Original_Budget__c, Revised_budget__c from Capital_Project__c
where id = :ProjectID];
return myCapitalProject;
}
public List<Capital_Subproject__c> getMySubProjects(){
mySubProjects = [select id, name, icb_approved_amount__c, capital_project__c, project_code__c, amount_approved__c, current_budget__c, original_budget__c, type__c, status__c
from Capital_Subproject__c where Capital_Project__c = :ProjectID];
return mySubProjects;
}
}

 

The component code:

 

<apex:component controller="CapitalProjectController" access="global">
<apex:attribute name="ProjectID" description="This is the Capital Project ID from which we glean the opportunity"
type="Id" assignTo="{!ProjectID}"/>
<apex:stylesheet value="{!$Resource.Print}" />
<h3>Opportunity Information</h3>
<apex:datatable cellpadding="5" var="opp" value="{!relatedOpportunity}"
style="text-align:center" rendered="{!NOT(ISNULL(relatedOpportunity))}">
<apex:column value="{!opp.AccountId}" headerValue="Account Name" />
<apex:column value="{!opp.Name}" headerValue="Opportunity Name" />
<apex:column value="{!opp.Amount}" headerValue="MRR"/>
<apex:column value="{!opp.NRR__c}" headerValue="NRR"/>
<apex:column value="{!opp.Term_in_Months__c}" headerValue="Term (Months)" />
<apex:column value="{!opp.A_end_state__c}" headerValue="A End State" />
<apex:column value="{!opp.Z_end_state__c}" headerValue="Z End State" />
</apex:datatable>
<p style="{border-bottom-style: groove}"/>
<h3>Capital Project Information</h3>
<apex:datatable cellpadding="5" var="project" value="{!myCapitalProject}"
style="text-align:center">
<apex:column value="{!project.Name}" headerValue="Project ID" />
<apex:column value="{!project.Project_Name__c}" headerValue="Project Name" />
<apex:column value="{!project.Project_Class__c}" headerValue="Project Class" />
<apex:column value="{!project.Status__c}" headerValue="Status" />
<apex:column value="{!project.ICB_Approved_Amount__c}" headerValue="ICB Approved Amount" />
<apex:column value="{!project.Revised_Budget__c}" headerValue="Current Budget" />
<apex:column value="{!project.Original_Budget__c}" headerValue="Original Budget" />
<apex:column value="{!project.Notes__c}" headerValue="Notes" />
</apex:datatable>
<p style="{border-bottom-style: groove}"/>
<h3>Capital Subproject Information</h3>
<apex:datatable cellpadding="5" var="subproj" value="{!mySubProjects}"
style="text-align:center">
<apex:column value="{!subproj.Project_Code__c}" headerValue="Project Code" />
<apex:column value="{!subproj.Type__c}" headerValue="Type" />
<apex:column value="{!subproj.Status__c}" headerValue="Status" />
<apex:column value="{!subproj.ICB_Approved_Amount__c}" headerValue="ICB Approved Amount" />
<apex:column value="{!subproj.Current_Budget__c}" headerValue="Current Budget" />
<apex:column value="{!subproj.Original_Budget__c}" headerValue="Original Budget" />
<apex:column value="{!subproj.Amount_Approved__c}" headerValue="Approved Amount" />
</apex:datatable>
</apex:component>

 

And the Email Template (kudos to the author of the style sheet, it's pretty...)

 

<messaging:emailTemplate recipientType="User"
relatedToType="Capital_Subproject__c"
subject="Capital Subproject: {!relatedTo.Name} requires approval">
<messaging:htmlEmailBody >
<style>


h3 {
   font-family: "Trebuchet MS", Arial, sans-serif;
}
table, th, td {
    border: 1px solid #D4E0EE;
    border-collapse: collapse;
    font-family: "Trebuchet MS", Arial, sans-serif;
    color: #555;
}

caption {
    font-size: 150%;
    font-weight: bold;
    margin: 5px;
}

td, th {
    padding: 4px;
}

thead th {
    text-align: center;
    background: #E6EDF5;
    color: #4F76A3;
    font-size: 100% !important;
}

tbody th {
    font-weight: bold;
}

tbody tr { background: #FCFDFE; }

tbody tr.odd { background: #F7F9FC; }

table a:link {
    color: #718ABE;
    text-decoration: none;
}

table a:visited {
    color: #718ABE;
    text-decoration: none;
}

table a:hover {
    color: #718ABE;
    text-decoration: underline !important;
}

tfoot th, tfoot td {
    font-size: 85%;
}
</style>
<html>
    <body>
        <a href="https://na4.salesforce.com/{!relatedTo.Id}">Click to review project and approve/reject</a>
        <c:CapitalApprovalEmail ProjectID="{!relatedTo.Capital_Project__c}" />
    </body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>

 

 

paul-lmipaul-lmi
this is excellent info.  i'll be able to use it once SF lifts the "read only" force requirement on any "generated" email template.  one of the core reuqirements of our agents sending email is that they can add on to what's being sent, and the only two options that allow that are plain text and HTML with letterhead, unless you count a third option of completely building a custom emailer, which is insanity IMO.
khanWebgurukhanWebguru
blank_page

Dear All,

 

 I have an email template which is given below:

 

Evaluation Request from {!Lead.LastName} {!Lead.FirstName} for {!Lead.SupportProduct__c}, is pending and requires manual approval. <br/>

Click <a href="{!ApprovalRequest.Internal_URL}">here</a> to approve or reject this request.<br/><br/>

Thanks.

 

Whenever I use this template through "Approval Processes" it works fine. But I have different situation in which I cannot use "Approval Processes". For example I need that when a Lead create then email should be generate for Lead Approval and send to those receptionist that are belongs to selected region. If a lead belongs to ASIA then email should be send on asia@abc.com or if region is USA then it should be for usa@abc.com I successfully completd this task with static or just text base template. But whenever I use Customise template its not filling merge values. Following is TRIGER code:

 

trigger TestEmail on Lead (after insert)
{       
            MailerUtils.sendMail(Trigger.new[0].Region__c, String.valueOf(Trigger.new[0].Id), Trigger.new  [0].IsEmbargoe__c);


 

 

Now, following is MailerUtils class having sendMail method

 

public class MailerUtils
{
 
    public static void sendMail(string location, string leadId, Boolean IsEmbargoe)
    {
        string message;
        string temp = 'ApproveLeadTemplate';
        String[] toAddresses;
        List<Id> idsList = getEmailAddresses(location);
       
        if(IsEmbargoe == False)
        {
            temp = 'ApproveEmbargoeTemplate';
        }
        EmailTemplate e = [select Id,Name,Subject,body from EmailTemplate where name like :temp+'%'];
                                                  
        if(e != null || idsList==null)
        {
            Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
            mail.saveAsActivity = false;
   
            mail.setTargetObjectIds(idsList);
            mail.setTemplateId(e.Id);
           
            mail.setUseSignature(false);
            mail.setSaveAsActivity(false);


            // Send the email
            Messaging.sendEmail(new Messaging.MassEmailMessage[] { mail });
          
        }
        else
        {
            Messaging.SingleEmailMessage mail1 = new Messaging.SingleEmailMessage();
            toAddresses = new String[] {'khan@abc.com'};
            mail1.setToAddresses(toAddresses);
            message = 'This email will recieve by you only if Template Not Found!!!';
            mail1.setHtmlBody(message);
        }
                
            }  
   
     public static List<Id> getEmailAddresses(string groupName)
     {

        List<String> idList = new List<String>();
       
        List<Id> mailToIds = new List<Id>();
       
        Group g = [SELECT (select userOrGroupId from groupMembers) FROM group WHERE name = :groupName];
       
        for (GroupMember gm : g.groupMembers) {
       
        idList.add(gm.userOrGroupId);
       
        }
       
        User[] usr = [SELECT Id, email FROM user WHERE id IN :idList];
       
        for(User u : usr) {
       
        mailToIds.add(u.Id);
       
        }
       
        return mailToIds;
       
    }
   

 

 

I have some public group having same name like ASIA, USA and Austrailia so that this help me to pull autmatic all user from selected group on the bases of Region.

 

But In all this I am having problem that the dynamic fields or u can say merge fields are not filling please help me in this context. Thanking in advance for you help.

 

Regards,

 

Asif Ahmed Khan

Sr. Software Eng.

Palmchip :)