Customize your Visualforce template

Prev Next

Vijay took his time to explain to Linda all the sections available in the Visualforce Page of the invoice that you can take from GitHub. Checking the PDF of the invoice at the same time as the Visualforce Code she was able to follow his explanations. Now she is looking forward to modify the template.

Vijay suggests to have a look at the procedures first and then to focus on the style changes. First, he gives her some general advice about the work with Visualforce Pages.

This article covers several procedures that permit you to display different type of information on the Visualforce Page.

Best practices for Visualforce Pages

  1. Even small changes should be applied in a sandbox first (not in your org in production). Especially if your colleagues or automatisms create invoices / offers at the same time.
  2. Save your changes regularly to avoid long debugging sessions if you receive an error message.
  3. Add comments for each part of code, make them as clear as possible, so that your colleagues understand it and find the different parts if they want to make changes.
  4. InstallSalesforce Inspectorthat allows you to get the correct writing of the API field names if you open the tool on a record of an invoice/ quotation or any other object. Here you find the versions for the most common browsers, but it exists also for other browsers (e.g. Internet Explorer) :

Create a custom label

Linda would like to change the footer, especially the part that concerns the legal mentions.
Instead of APE/NAF she wants to display “Business Main Activity N°”.




Vijay shows her the steps.

As already said in the last article, the best practice to display a label or "non variable" information is to use custom labels, instead of hard coding directly in the Visualforce Page.

Steps

1. Go to Setup > User Interface > Custom Labels or type label in the Quick Search field.
2. Click on the button New Custom Label.

3. Add a telling Short Description

4. Put an information like PDF or Invoice Template in the Category field, you can create a View List on the Custom Label overview page later based on this information

5. Fill in the Value field with the data that you want to display on your PDF. In our example we will put Business Main Activity N° for the footer.

6. Click on the button Save.

Note:
(1) In order to easily find your custom labels, create a view list on the Custom Labels page that filters the PDF category.

(2) We will anticipate the next step. Let's keep the custom label open in a tab, because we'll need it later. If you have the possibility, work with multiple screens, it will make your job easier. Indeed, using several tabs / windows allows you to quickly find information without leaving your main page.

Retrieve data you want to display on your template

Now we will learn how to display different type of information on your Visualforce page.

Display a custom label

Let's start with the custom label we just created, afterwards we will figure out how to add labels from Frisbii app.

Steps

  1. Go to Setup,  type Page in the search and click on Visualforce Page

  2. Then click on the packaged template (here: Modèle Facture 5).

  3. Copy the whole Visualforce Markup: Use the CTR + A shortcut, right mouse click > Copy.

  4. In a new tab of your browser, go to Visualforce Pages and click on the New button.

  5. Paste the Markup you copied and ensure the markup starts with “<apex:page standardController="sofactoapp__Factures_Client__c"…“

  6. Give a telling label, the name is filled out automatically (you might take out the empty spaces to save the page).

  7. Quick Save your page, to ensure the code you copied includes all the tags.

Reminder of the initial context
Linda would like to change the footer, in particular the part concerning the legal notices.
Instead of APE/NAF she wants to display “Business Main Activity N°”.

  1. Thanks to the comments in the Visualforce page, please find <!-- Pied de page/ Footer --> and inside this section <!--Mentions légales/ Legal notice-->.
    Vijay finds the <!--Seulement si pays RS = France/ Only if country of corporate name = France--> section below.
    9. He replaces the outputText value {!$Label.sofactoapp__Text_APE} by {!$Label.BusinessMainActivity}. Let's go back to the tab that we kept open to access to our custom labels we just created.
    Note: In order to display the custom label, you have to use this naming: {!$Label.CustomLabelName}.

  1. Now we will insert these tags into our Visualforce page.

    11. Save the Visualforce Page.

Let's check out the result now.

Note :

In order to see the result, you have to create a test invoice. It is not necessary at the moment to issue the invoice, so you can delete it once you start billing. If you already started billing with Frisbii, please remember to do the tests in a sandbox (partial copy) on an existing invoice.

Linda is satisfied with the result.

Display the content of a field on the PDF

Linda would like to display the CloudKicks contact on the invoice PDF. As a small exercise, she already created the custom label she wants to put next to this information.
Vijay takes the time to explain to Linda how she can proceed :

1) To display the content of a field from the invoice object
2) To display the content of a field coming from another Frisbii object on the invoice
3) To display the content of a field coming from another Salesforce object on the invoice

The aim is to build the access path for the field we are interested in.

In the header of the Visualforce page, we defined the invoice object as starting point for the construction of the page (standardController="sofactoapp__Factures_Client__c").


Retrieve a field from the invoice object

Steps

1. First, we have to define the starting point :

> sofactoapp__Factures_Client__c

> sofactoapp : API name of the package

> Even if the object is packaged, Salesforce considers the object as "custom", this is why the API name ends with __c


2. Then we have to add the API name of the field we want to add :

> sofactoapp__Factures_Client__c.sofactoapp__Date_de_facture__c

3. In order to integrate this information into the Visualforce Page, we have to put it into an Apex tag :

<apex:outputText value="{!sofactoapp__Factures_Client__c.sofactoapp__Date_de_facture__c}" />


Reminder: Visualforce Components
In this example, we are using mostly these components :

  • apex:outputPanel: Allows to group Apex tags and/or custom labels, in order to apply a condition, styles or repeats to the group of tags.

  • apex:outputText: Displays the text on the Visualforce page. You can add styles and conditions.

  • apex:outputField: Displays rich text and keeps the style applied on the field.

Please find here a complete list of these components: Standard Component Reference.

Retrieve a field from the another Frisbii object (eg. Corporate Names)

Steps

1. We define again the starting object (as defined on the Visualforce page header - see above).

> sofactoapp__Factures_Client__c

2. Then we add the "relation" object, in our example the Corporate name (API name Emetteur facture = Invoice issuer on the invoice object)

> sofactoapp__Factures_Client__c.sofactoapp__emetteur_facture__r > __r for Relation 

3. Afterwards, we have to add the API name of the field that we would like to display:

>sofactoapp__Factures_Client__c.sofactoapp__emetteur_facture__r.sofactoapp__Enseigne__c

4. As a last step, we have to integrate our combination into an Apex tag:

<apex:outputText value="{!sofactoapp__Factures_Client__c.sofactoapp__emetteur_facture__r.sofactoapp__Enseigne__c}"/>

Linda asks Vijay where she can find the API names and the relation between objects.
Vijay installs Salesforce Inspector into her browser to enable her to search the API names herself.
Here you can find more information about this browser extension, that is available for the common browsers.

Retrieve a field from another Salesforce object (eg. User)

Linda returns to her original request. She wants to set up the Cloud Kicks contact on the invoice.
This contact is the Salesforce user who owns the account related to the invoice.
Vijay shows her how to use Salesforce Inspector to retrieve this information.

Step

1. Go to the Invoice tab
2. Click on an Invoice record
3. Open Salesforce Inspector by clicking ont the small arrow of the browser extension (at the right side of your screen)

You see already the API name of the object


4. Click on the button Show all data
5. Type Account into the research


6. Click on Account to access to this Salesforce object
7. In this object search for owner

We found out that the owner of an account is a user - most of you knew that probably already

8. Click on User to access to this Salesforce object

9. Search for name in that object

10. Now we can combine our path to access to the field :

> sofactoapp__Factures_Client__c.sofactoapp__Compte__r.Owner.name
  • sofactoapp__Factures_Client__c = Root object

  • sofactoapp__Compte__r = Link to access to Account from Invoice

  • Owner = Target object

  • name = Target field


Note: We have to consider these two important points:

1) This path can be composed of three steps in total:

  • Root object

  • Relation object

  • Target object

If you want to access an information by passing by several relation objects, you have to put a lookup field on an object that is a) directly linked to the root object or b) linked by a relation object.

2) You might wonder how we knew that we have to choose Owner and not User? To be able to access Salesforce objects, you need to have some "contextual" knowledge.

We recommend

  • to follow trailhead modules related to the subject,

  • to read the Salesforce forums and/or

  • to search for tips and shortcuts.


Linda and Vijay add the custom label created by Linda and the owner of the account, here you can see the complete code:

Retrieve a Frisbii app label or a Salesforce label

Owing to complete this section, we will show you how to display Frisbii app labels or Salesforce labels on your PDF.

Thanks to the ObjectType, you can access to labels without passing by the "path" we just constructed to access field information.

Please apply this structure:

 {!$ObjectType.TargetObject.Fields.TargetField.Label}

Here are some examples :

{!$ObjectType.sofactoapp__Factures_Client__c.Fields.sofactoapp__Amount_exVAT__c.Label}
{!$ObjectType.sofactoapp__Raison_Sociale__c.Fields.sofactoapp__TVA_intra__c.Label}



Display Terms and Conditions in the end of your PDF

Linda wants to add their terms and conditions to the invoice. Vijay shows her three option to add the terms&conditions on listing the pros and cons for each option:

MethodAdvantagesDisadvantages
Add the text directly into the Visualforce page
  • Copy/paste the text directly into the Visualforce page
  • Add retrieved field information (see above) e.g. if you use different corporate names
  • formatting is not that nice (text aligning is quiet limited)
  • modifying the text, means modifying the Visualforce Page
  • you have to be admin to apply changes
Display screenshots of your Terms and Conditions
  • Easy to manage (by changing the screenshots in the static ressources)
  • Since you use screenshots of your initial text, the formatting is the same
  • It is hard to get a good quality/ readable text
  • You have to test for a while to display the right amount of text in your screenshots (Visualforce adds page breaks where you do not expect it)
Adding several rich text fields on the Corporate name tab
  • A user can modify the text and the format
  • Could be an idea if you just want to display several paragraphs without any retrieved information from other fields
  • Using Apex:outputField tags on a Rich text field displays blank lines with a bigger space than expected
  • If the text is long, you have to maintain several fields, a lot of back and forth to between the amount of text in the field, the line breaks and the formatting, to get the wished result
  • The user can add a word that modifies the result, so testing is necessary and can get tricky with several fields
  • It needs a lot of testing to compose the Terms & Conditions if you want to use these fields + information you retrieve from Frisbii objects, the layout can get pretty messy
Adding several custom labels
  • Easier to mix with information you retrieve from other objects (e.g. Corporate names)
  • You can easily add a translation
  • Could be an idea, if the text is short and you are a master of documentation
  • A lot of work, since you compose the whole text with custom label bits
  • Not so easy to maintain, since you have to know which information is put in which label
  • Same formatting issues, e.g. aligning a text is limited



Here are the procedures for the first two options :

a) Add the text directly into the Visualforce page
Within the last three articles we told you, not to write information directly into the code, but to use custom labels. This is not very handy for displaying a long text. Thus - heavy hearted - we accept the exception to write hard coded text into the code when it comes to Terms & Conditions.

Steps

1) On the bottom of your Visualforce page, add a <table> using this style :

style="page-break-before:always"

Here a snippet you can copy :

<!--Terms and Conditions-->

<table style="width:100%; height:25cm; page-break-before : always; font-size:11px> 
 <!--Add your terms and conditions here-->
</table>

2) Now paste your Terms& Conditions by replacing <!--Add your terms and conditions here-->

3) Add the parts that you would like to keep variable as outputText/ outputField on following the procedures mentioned above.


b) Display screenshots of your Terms and Conditions

Steps

1) In the static resources add the screenshot of your Terms& Conditions and name the resource TermsAndConditions

Note: For taking the screenshots

  • Keep a very tiny margin around the text

  • Pay attention that the font size is big enough to be read easily

  • Cut your Terms & Conditions into several pages if necessary

2) On the bottom of your Visualforce page, add this code:

TermsAndConditions)}" style="left:0;top:0;width:98%"/>

Note:
(1) Please test several times in order to check the result of your test PDF. Maybe Visualforce adds unexpected page breaks. In this case, you have to adjust the amount of information displayed on the pages.

(2) If you want to add several pages, just repeat the code:

<apex:image value="{!URLFOR($Resource.TermsAndConditions)}" style="left:0;top:0;width:98%"/>

and change the name of the resource (attention! it has to be the real name of the static resource) :

TermsAndConditions1)}" style="left:0;top:0;width:98%"/> TermsAndConditions2)}" style="left:0;top:0;width:98%"/>


Note: If you prefer the option c) or d), just keep the code for the page break and compose then your page following the procedures you learned in this article.

Finally, Linda would like to a add a page number and repeat it on each page.

Vijay shows her the code :

 <div id="wrap" style="position:fixed;bottom:0;right:0;">
        Page <span class="pagenumber" />/
        <span class="pagecount" />
        </div>

No matter where you add the code on the Visualforce page, the page number will be displayed on the bottom/ right of your PDF, thanks to the CSS  position, bottom and right.
Please apply the style that fits to your needs.