Sunday, 22 February 2015

Defining Templates with apex:composition , apex:define and apex:insert



<apex:composition> 

An area of a page that includes content from a second template page. Template pages are Visualforce pages that include one or more <apex:insert> components. The <apex:composition> component names the associated template, and provides body for the template's <apex:insert> components with matching <apex:define> components. Any content outside of an <apex:composition> component is not rendered.

<apex:define> 

A template component that provides content for an <apex:insert> component defined in a Visualforce template page.

<apex:insert> 

A template component that declares a named area that must be defined by an <apex:define > component in another Visualforce page. Use this component with the <apex:composition > and  <apex:define > components to share data between multiple pages.


NOTE:-  
1) All templates defined using <apex:composition> must have one or more child <apex:insert> tags. 
2) An <apex:insert> tag indicates to pages that import the template that a section needs a definition. 
3) Any Visualforce page that imports a template using <apex:composition> must use <apex:define> to specify the content of each <apex:insert> section of the template.

The <apex:composition> component fetches the Visualforce template page you created earlier, and the <apex:define> component fills the named holes in that template. You can create multiple pages that use the same component, and just vary the placeholder text

Example 1 :- simple example 

   Composition page

<apex:page>
    <apex:outputText value="(template) This is before the header"/><br/>
    <apex:insert name="header"/><br/>
    <apex:outputText value="(template) This is between the header and body"/><br/>
    <apex:insert name="body"/>
</apex:page>

   Main Page

<apex:page>
    <apex:composition template="composition">
        <apex:define name="header">(page) This is the header of mypage</apex:define>
        <apex:define name="body">(page) This is the body of mypage</apex:define>
    </apex:composition>
</apex:page>

HTML Output

(template) This is before the header<br/>
(page) This is the header of mypage<br/>
(template) This is between the header and body<br/>
(page) This is the body of mypage


Example 2 :- With controller 

Template VF page
<apex:page controller="compositionExample">
    <h1 style="color:Red"><apex:insert name="Title" /></h1>
    <BR> </BR>
    <BR> </BR>
<apex:form >
    <apex:outputLabel value="First Name: " for="nameField"/>
    <apex:inputText id="nameField" value="{!FirstName}"/>
    <br/>        <br/>

    <apex:insert name="LastNameSection" />
    <br/>        <br/>

    <apex:insert name="AgeSection" />
    <br/>        <br/>

    <apex:commandButton action="{!save}" value="Save" id="saveButton"/>
</apex:form>
</apex:page>

Controller class
public class compositionExample{
    public String FirstName{get;set;}
    public String LastName{get;set;}
    public String Age{get;set;}
    public String colorField {get;set;}
    
    public compositionExample()
    {
    }
    
    public PageReference save() {
        return null;
    }
    
}

Import Template in VF page
<apex:page controller="compositionExample">
 <apex:messages />

  <apex:composition template="myCompositionForm">
     <apex:define name="Title">How to write templates In Visual Force page
     </apex:define>
     
    <apex:define name="LastNameSection">
        <apex:outputLabel value="Last Name: " for="LastName"/>
        <apex:inputText id="mealField" value="{!LastName}"/>
    </apex:define>
    
    <apex:define name="AgeSection">
        <apex:outputLabel value="Age: " for="Age"/>
        <apex:inputText id="ageField" value="{!Age}"/>
    </apex:define>
    
       <apex:outputLabel value=" Color: " for="colorField"/>
       <apex:inputText id="colorField" value="{!colorField}"/>
  </apex:composition>

</apex:page>

Example 3 :- Dynamic Template

Template VF page
<apex:page>
    <apex:insert name="name" />
</apex:page>

Controller class with pageReference which will return template Name
public class dynamicComposition {
    public PageReference getmyTemplate() {
        return Page.myTemplatePage;
    }
}

Import Template in Vf page dynamic y.
<apex:page controller="dynamicComposition">
    <apex:composition template="{!myTemplate}">
    <apex:define name="name">
        Hello {!$User.FirstName}
    </apex:define>
    </apex:composition>
</apex:page>


Thanks,

Amit Chaudhary