I tried to complete your code to achieve what you describe and found a little problem: sending the email will create a Task object, which conflicts with saving an EmailTemplate (you get a MIXED_DML_OPERATION).
What I ended up doing is creating separate buttons for the save and the email. I used a TemporalTemplate to store the modified version so I can reuse it.
You may be able to avoid the MIXED_DML_OPERATION by using a @Future method to send the email after the save.
Here's my code:
<apex:page controller="EmailTemplateController">
<apex:form >
<apex:pageBlock >
<apex:pageBlockButtons >
<apex:commandButton action="{!sendMail}" value="Send Email"/>
<apex:commandButton action="{!saveTemplate}" value="Save Template"/>
</apex:pageBlockButtons>
<apex:pageBlockSection columns="1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="Target Contact" />
<apex:inputField value="{!targetContact.ReportsToId}"/>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Edit Template" />
<apex:inputTextarea id="editTemplate" value="{!editedTemplate}" richText="true" cols="100" rows="15"/>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
And the controller:
public with sharing class EmailTemplateController {
public Contact targetContact {get;set;}
public String editedTemplate {get;set;}
private String templateId = null;
public EmailTemplateController() {
targetContact = new Contact();
if (ApexPages.currentPage().getParameters().containsKey('template')) {
templateId = ApexPages.currentPage().getParameters().get('template');
this.editedTemplate = [select HtmlValue from EmailTemplate where Id = :templateId].HtmlValue;
}
}
public PageReference saveTemplate() {
EmailTemplate template = [select Id, HtmlValue from EmailTemplate where Name = 'TemporalTemplate'];
template.HtmlValue = editedTemplate;
update template;
return null;
}
public PageReference sendMail() {
EmailTemplate template = [select Id, HtmlValue from EmailTemplate where Name = 'TemporalTemplate'];
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setSenderDisplayName('Tester');
email.setTemplateId(template.Id);
email.setTargetObjectId(targetContact.ReportsToId);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
return null;
}
}
Alright, I finished the extension and it works. Thanks to Jason Hardy for suggesting the extension! Here it is:
public class CreateAdditionalPayeeExtension {
Payee__c payee {get;set;}
//constructor
public CreateAdditionalPayeeExtension(ApexPages.StandardController stdController){
payee = (Payee__c)stdController.getRecord();
payee.Order__c = ApexPages.currentPage().getParameters().get('ordId');
}
public PageReference save(){
insert payee;
return null;
}
}
(You can ignore the save function in the extension; I'm just trying to now make a save button that overrides the standard one on my VF page so that it can redirect to a specific page.) So after I made this, I used it to auto-fill the "Order" lookup field on the VF page (I decided to leave the rest blank). Here's the VF page:
<apex:page standardController="Payee__c" extensions="CreateAdditionalPayeeExtension">
<apex:form >
<apex:pageBlock title="Add Additional Payee Information" mode="save">
<apex:pageBlockButtons >
<apex:commandButton action="{!save}" value="Save"/>
<apex:commandButton action="{!cancel}" value="Cancel"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Additional Payee" columns="1">
<apex:inputField value="{!Payee__c.Order__c}"/>
<apex:inputField value="{!Payee__c.Payee_Type__c}"/>
<apex:inputField value="{!Payee__c.Agency__c}"/>
<apex:inputField value="{!Payee__c.Agent__c}"/>
<apex:inputField value="{!Payee__c.Additional_Agency_Rate__c}"/>
<apex:inputField value="{!Payee__c.Rate_Based_On__c}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
So, as you can see, nothing changed on the VF page from before besides the extension at the top, BUT along with the button URL that is on the Order object that links to the page (/apex/Create_Additional_Payee?ordId={!Order.Id}), the extension works to override the
<apex:inputField value="{!Payee__c.Order__c}"/>
line and when the button is clicked on the Order object, the lookup field is successfully pre-populated, but still able to be changed to something else if the user so desires.
Sorry for the long and convoluted explanation, but that's pretty much the order in which I figured it out so I don't know a better way to explain it. I hope this helps anyone that has the same problem!
Best Answer
In your email template how are you generating the sites page link ?
I would have thought you could use a merge field to populate the record ID. Then in the controller for the Sites page link, you could use to get the record ID and then query to retrieve all the info required for the page.
ApexPages.currentPage().getParameters().get('Id');
In a nutshell, set a query parameter in the email template and then have an action on the controller that checks for that parameter and queries the database for the required info. The link below might also be of help
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_system_pagereference.htm