Templating with Visualforce. salesforce Visualforce Developer Guide
જાહેરાત
જાહેરાત
CHAPTER 18 Templating with Visualforce
Visualforce provides several strategies for reusing similar content across multiple Visualforce pages. The method you choose depends on how flexible you need your reused template to be. The more flexible a templating method is, the more any implementation of a template using that method can be modified. The following template methods are available, in order of most to least flexible:
Similar to the way you can encapsulate a piece of code in a method and then reuse that method several times in a program, you can encapsulate a common design pattern in a custom component and then reuse that component several times in one or more
Visualforce pages. Defining custom components is the most flexible templating method because they can contain any valid Visualforce tags and can be imported without restrictions into any Visualforce page. However custom components should not be used to define reusable Visualforce pages. If you want to reuse the content of an entire Visualforce page, choose one of the other two templating methods.
If you want to define a base template that allows portions of the template to change with each implementation, use the
<apex:composition >
component. This templating method is best for situations when you want to maintain an overall structure to a page, but need the content of individual pages to be different, such as a website for news articles where different articles should appear with the same page layout.
Through this technique, you can also define a template from a PageReference returned by a controller.
Referencing an Existing Page with
If you want the entire content of a Visualforce page inserted into another page, use the
<apex:include >
component. This templating method is best for situations when you want to replicate the same content in multiple areas, such as a feedback form that appears on every page of a website.
Templates made with
<apex:insert >
and
<apex:composition >
should only be used when you want to reference an already existing Visualforce page. If you require only a set of components to be duplicated, use custom components.
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.
First, create an empty page called
myFormComposition
that uses a controller called compositionExample
:
<apex:page controller= "compositionExample" >
</apex:page >
269
Templating with Visualforce Defining Templates with <apex:composition>
After saving the page, a prompt appears that asks you to create compositionExample
. Use the following code to define that custom controller: public class compositionExample{
String name;
Integer age;
String meal;
String color;
Boolean showGreeting = false ; public PageReference save() { showGreeting = true ; return null ;
} public void setNameField( String nameField) { name = nameField;
} public String getNameField() { return name;
} public void setAgeField( Integer ageField) { age= ageField;
} public Integer getAgeField() { return age;
} public void setMealField( String mealField) { meal= mealField;
} public String getMealField() { return meal;
} public void setColorField( String colorField) { color = colorField;
} public String getColorField() { return color;
} public Boolean getShowGreeting() { return showGreeting;
}
}
270
Templating with Visualforce Defining Templates with <apex:composition>
Next, return to myFormComposition
and create a skeleton template:
<apex:page controller= "compositionExample" >
<apex:form >
<apex:outputLabel value= "Enter your name: " for= "nameField" />
<apex:inputText id= "nameField" value= "{!nameField}" />
<br />
<apex:insert name= "age" />
<br />
<apex:insert name= "meal" />
<br />
<p >That 's everything, right?</p>
<apex:commandButton action= "{!save}" value= "Save" id= "saveButton" />
</apex:form >
</apex:page >
Notice the two
<apex:insert >
fields requiring the
age
and
meal
content. The markup for these fields is defined in whichever page calls this composition template.
Next, create a page called
myFullForm
, which defines the
<apex:insert >
tags in myFormComposition
:
<apex:page controller= "compositionExample" >
<apex:messages/ >
<apex:composition template= "myFormComposition" >
<apex:define name= "meal" >
<apex:outputLabel value= "Enter your favorite meal: " for= "mealField" />
<apex:inputText id= "mealField" value= "{!mealField}" />
</apex:define >
<apex:define name= "age" >
<apex:outputLabel value= "Enter your age: " for= "ageField" />
<apex:inputText id= "ageField" value= "{!ageField}" />
</apex:define >
<apex:outputLabel value= "Enter your favorite color: " for= "colorField" />
<apex:inputText id= "colorField" value= "{!colorField}" />
</apex:composition >
<apex:outputText id= "greeting" rendered= "{!showGreeting}" value= "Hello {!nameField}.
You look {!ageField} years old. Would you like some {!colorField} {!mealField}?
"/>
</apex:page >
Notice the following about the markup:
•
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
.
271
Templating with Visualforce Defining Templates with <apex:composition>
•
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.
To show how you can use any valid Visualforce in an
<apex:define >
tag, create a new Visualforce page called myAgelessForm and use the following markup:
<apex:page controller= "compositionExample" >
<apex:messages/ >
<apex:composition template= "myFormComposition" >
<apex:define name= "meal" >
<apex:outputLabel value= "Enter your favorite meal: " for= "mealField" />
<apex:inputText id= "mealField" value= "{!mealField}" />
</apex:define >
<apex:define name= "age" >
<p >You look great for your age!
</p >
</apex:define >
</apex:composition >
<apex:outputText id= "greeting" rendered= "{!showGreeting}" value= "Hello {!nameField}.
Would you like some delicious {!mealField}?
"/>
</apex:page >
Notice that the composition template only requires an
<apex:define >
tag to exist. In this example,
age
is defined as text.
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.
For example, create a page called
myAppliedTemplate
that defines the skeleton template:
<apex:page >
<apex:insert name= "name" />
</apex:page >
Next, create a controller called dynamicComposition
with a method that will return a reference to this page: public class dynamicComposition { public PageReference getmyTemplate() { return Page.myAppliedTemplate;
}
}
Last, create a page called myDynamicComposition
that implements this controller and the dynamic template:
<apex:page controller= "dynamicComposition" >
<apex:composition template= "{!myTemplate}" >
<apex:define name= "name" >
Hello {!$User.FirstName}, you look quite well.
</apex:define >
</apex:composition >
</apex:page >
272
Templating with Visualforce Referencing an Existing Page with <apex:include>
Referencing an Existing Page with
<apex:include >
Use the
<apex:include >
tag when you want to duplicate the entire content of another page without making any changes. You can use this technique to reference existing markup that will be used the same way in several locations.
Note: You should not use
<apex:include >
if you are only duplicating components. Custom components are better suited
for reusable segments of code.
For example, suppose you want to create a form that takes a user's name and displays it back to them. First, create a page called formTemplate
that represents a reusable form and uses a controller called templateExample
:
<apex:page controller= "templateExample" >
</apex:page >
After you receive the prompt about templateExample
not existing, use the following code to define that custom controller: public class templateExample{
String name;
Boolean showGreeting = false ; public PageReference save() { showGreeting = true ; return null ;
} public void setNameField( String nameField) { name = nameField;
} public String getNameField() { return name;
} public Boolean getShowGreeting() { return showGreeting;
}
}
Next, return to formTemplate
and add the following markup:
<apex:page controller= "templateExample" >
<apex:form >
<apex:outputLabel value= "Enter your name: " for= "nameField" />
<apex:inputText id= "nameField" value= "{!nameField}" />
<apex:commandButton action= "{!save}" value= "Save" id= "saveButton" />
</apex:form >
</apex:page >
Note that nothing should happen if you click Save. This is expected behavior.
Next, create a page called
displayName
, which includes formTemplate
:
<apex:page controller= "templateExample" >
<apex:include pageName= "formTemplate" />
273
Templating with Visualforce Referencing an Existing Page with <apex:include>
<apex:actionSupport event= "onClick" action= "{!save}" rerender= "greeting" />
<apex:outputText id= "greeting" rendered= "{!showGreeting}" value= "Hello {!nameField}" />
</apex:page >
When you save this page, the entire formTemplate
page is imported. When you enter a name and click Save the form passes a true
value to the showGreeting
field, which then renders the
<apex:outputText >
and displays the user's name.
You can create another Visualforce page that uses formTemplate
to display a different greeting. Create a page called displayBoldName
and use the following markup:
<apex:page controller= "templateExample" >
<style type= "text/css" >
.boldify { font-weight: bolder; }
</style >
<apex:include pageName= "formTemplate" />
<apex:actionSupport event= "onClick" action= "{!save}" rerender= "greeting" />
<apex:outputText id= "greeting" rendered= "{!showGreeting}" styleClass= "boldify" value= "I hope you are well, {!nameField}." />
</apex:page >
Notice that although the displayed text changes, the templateExample
logic remains the same.
274
ડાઉનલોડ કરો
જાહેરાત