Newer Version Available
Defining Templates with <apex:composition>
All templates defined using <apex:composition> must have one or more child <apex:insert> tags. An <apex:insert> tag indicates to pages that import the template that a section needs a definition. 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.
You can create a skeleton template that allows subsequent Visualforce pages to implement different content within the same standard structure. To do so, create a template page with the <apex:composition> tag.
The following example shows how you can use <apex:composition>, <apex:insert>, and <apex:define> to implement a skeleton template.
1<apex:page controller="compositionExample">
2
3</apex:page>1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class compositionExample{
18
19 String name;
20 Integer age;
21 String meal;
22 String color;
23
24 Boolean showGreeting = false;
25
26 public PageReference save() {
27 showGreeting = true;
28 return null;
29 }
30
31 public void setNameField(String nameField) {
32 name = nameField;
33 }
34
35 public String getNameField() {
36 return name;
37 }
38
39 public void setAgeField(Integer ageField) {
40 age= ageField;
41 }
42
43 public Integer getAgeField() {
44 return age;
45 }
46
47 public void setMealField(String mealField) {
48 meal= mealField;
49 }
50
51 public String getMealField() {
52 return meal;
53 }
54
55 public void setColorField(String colorField) {
56 color = colorField;
57 }
58
59 public String getColorField() {
60 return color;
61 }
62
63 public Boolean getShowGreeting() {
64 return showGreeting;
65 }
66}1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="compositionExample">
18 <apex:form >
19 <apex:outputLabel value="Enter your name: " for="nameField"/>
20 <apex:inputText id="nameField" value="{!nameField}"/>
21 <br />
22 <apex:insert name="age" />
23 <br />
24 <apex:insert name="meal" />
25 <br />
26 <p>That's everything, right?</p>
27 <apex:commandButton action="{!save}" value="Save" id="saveButton"/>
28 </apex:form>
29</apex:page>1swfobject.registerObject("clippy.codeblock-3", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="compositionExample">
18 <apex:messages/>
19 <apex:composition template="myFormComposition">
20
21 <apex:define name="meal">
22 <apex:outputLabel value="Enter your favorite meal: " for="mealField"/>
23 <apex:inputText id="mealField" value="{!mealField}"/>
24 </apex:define>
25
26 <apex:define name="age">
27 <apex:outputLabel value="Enter your age: " for="ageField"/>
28 <apex:inputText id="ageField" value="{!ageField}"/>
29 </apex:define>
30
31 <apex:outputLabel value="Enter your favorite color: " for="colorField"/>
32 <apex:inputText id="colorField" value="{!colorField}"/>
33
34 </apex:composition>
35
36 <apex:outputText id="greeting" rendered="{!showGreeting}" value="Hello {!nameField}.
37 You look {!ageField} years old. Would you like some {!colorField} {!mealField}?"/>
38</apex:page>- When you save myFullForm, the previously defined <apex:inputText> tags and Save button appear.
- Since the composition page requires age and meal fields, myFullForm defines them as text input fields. The order in which they appear on the page does not matter; myFormComposition specifies that the age field is always displayed before the meal field.
- The name field is still imported, even without a matching <apex:define> field.
- The color field is disregarded, even though controller code exists for the field. This is because the composition template does not require any field named color.
- The age and meal fields do not need to be text inputs. The components within an <apex:define> tag can be any valid Visualforce tag.
1swfobject.registerObject("clippy.codeblock-4", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<apex:page controller="compositionExample">
18 <apex:messages/>
19 <apex:composition template="myFormComposition">
20
21 <apex:define name="meal">
22 <apex:outputLabel value="Enter your favorite meal: " for="mealField"/>
23 <apex:inputText id="mealField" value="{!mealField}"/>
24 </apex:define>
25
26 <apex:define name="age">
27 <p>You look great for your age!</p>
28 </apex:define>
29
30 </apex:composition>
31
32 <apex:outputText id="greeting" rendered="{!showGreeting}" value="Hello {!nameField}.
33 Would you like some delicious {!mealField}?"/>
34</apex:page>Dynamic Templates
A dynamic template allows you to assign a template through a PageReference. The template name is assigned to a controller method that returns a PageReference containing the template you want to use.
1<apex:page>
2 <apex:insert name="name" />
3</apex:page>1public class dynamicComposition {
2 public PageReference getmyTemplate() {
3 return Page.myAppliedTemplate;
4 }
5}1<apex:page controller="dynamicComposition">
2 <apex:composition template="{!myTemplate}">
3 <apex:define name="name">
4 Hello {!$User.FirstName}, you look quite well.
5 </apex:define>
6 </apex:composition>
7</apex:page>