Twig Templates
Twig templates give you a powerful tool to create a custom experience for your users.
With Twig, a flexible, fast, and secure template engine, implemented in Dynamics 365 Integration you can display CRM data in WordPress using CRM views, FetchXML queries, as well as sending data back to CRM via forms.
Twig syntax is explained in Twig documentation.
Features
- entity binding -- bind any entity to a page and display relevant record data
- user binding -- access record data of the the current CRM identity
- views -- render CRM views in WordPress, with customizable templates
- inline FetchXML queries -- query CRM data and render it in WordPress
- forms -- render CRM forms or custom HTML forms in WordPress, capture submissions and send data back to CRM
- access any record by ID
- access entity metadata
- extensibility -- add new tags, functions and filters to the engine with WordPress actions and filters
Global objects
entities
-- access to any entity record by ID. See Access to records by IDentities_list
-- map of all entities in the CRM (logical name -> display name)metadata
-- access to entity metadatacurrentrecord
-- access to the bound entity record. See Entity bindingnow
-- time in unixtime format (integer) when Twig was initializedrequest
-- stores request-related dataparams
-- map of cookies, POST and GET values. The latter values override the formerpath
-- raw path to the pagepath_and_query
-- raw URI of the pagequery
-- query string prepended with?
character or empty if no query stringurl
-- URL of the current pagereferer
-- URL of the page that linked to the current one
params
-- seerequest.params
crm
-- CRM-related parametersconnected
-- (boolean) tells whether the site is connected to CRM
Functions
entityUrl(entityName, entityId)
-- builds an URL leading to the page marked as "Default for views"attachmentUrl(attachmentId)
-- builds an URL leading to the attachment download page. File download is triggered and a "Save As" dialog is displayed after visiting the link
Filters
url|add_query(argName, argValue)
-- adds a query argument to the given URLcontent|wpautop
-- filters the given content through thewpautop()
WordPress function
Examples
Basic shortcode
All Twig templates must be enclosed into the special Twig shortcode -- [msdyncrm_twig]
.
[msdyncrm_twig]
Twig templates go here...
[/msdyncrm_twig]
Entity binding
Configure entity binding for the page as described in Entity binding. If the page is bound to an entity, and the respective entity record is found in the CRM, that record will be available as a global currentrecord
object in Twig templates.
{{ currentrecord.name }}
User binding
Premium feature! This feature is available in the premium extension.
Configure authentication for the site as described in Authentication. If the current user is an identity user, then the global user
object will be available in Twig templates.
{{ user.emailaddress1 }}
Views
The view
tag allows you to fetch structured data from CRM and display it as a table. You can customize the template or write your own one and create a unique experience.
The tag has a number of arguments:
entity
-- (required) logical name of the entity which the view belongs toname
-- (required) name of the entity viewcache
-- specifies expiration time for the fetched records. The format is based on the ISO 8601 duration specificationparameters
-- an array of values to substitute placeholders in the view FetchXMLlookups
-- a key-value map to substitute lookup conditions in the view FetchXMLcount
-- number of items per page. If specified, pagination is enabled
Inside the template the tag exposes entityview
object with a collection of fields:
columns
-- collection of fetched columns (key: logical name, value: field label)entity_logical_name
-- logical name of the entityfirst_page
-- page number of the first page. Set to1
if the result is not empty,null
otherwiselast_page
-- page number of the last page.null
if the result is empty)name
-- name of the fetched CRM viewnext_page
-- page number of the next page.null
if pagination is not enabled or the last page has been reachedpage
-- the current page numberpages
-- array of all available page numberspage_size
-- number of items per pageprevious_page
-- page number of the previous page.null
if pagination is not enabled or the first page is reachedprimary_key_logical_name
-- logical name of the primary fieldrecords
-- collection of retrieved records, accessible by record IDrows
-- collection of retrieved records with prepared values, accessible by record ID. Individual item fields are:head
-- label of the current columnformatted_value
-- formatted value of the current column. May be a HTML link referring to a data-bound page if the column field is a lookupvalue
-- raw value of the field as reported by the CRMproperties
-- field metadata
total_pages
-- total number of pages in the viewtotal_records
-- total record count as reported by the CRM
Please note that personal views must be shared with the user you use to connect WordPress to Dynamics 365 before you start surfacing them with Twig. The user must have read access to that view in order to surface it in WordPress.
![Dynamics 365 Share Personal View window.]
Parameters substitution
In order to use parameters
attribute, you need to create a view with placeholders. A placeholder is an integer value (0, 1, 2...) enclosed in the curly braces: {0}
. When you construct a view, enter these placeholders into field values you want to filter. See the example below.
![Dynamics 365 Advanced Find window.]
parameters
receives a Twig array: [ "value 0", "value 1", "value 2" ]
.
Alternatively, you can specify a placeholder label in the view instead of a number, e.g. {email}
. To substitute that placeholder later, please use a map as parameters
value: { "email": "contoso.com" }
.
Lookups substitution
You can substitute lookup conditions in the view. Please use a map { attribute => GUID }
for that. For example, { "parentcustomerid": params.account "}
or { "ownerid": user.id }
.
Simple view
The following snippet will insert a Contact view "Active Contacts" with pagination enabled with 10 records per page. The result of the view query will be fetched for 30 minutes. It will substitute placeholder {0}
with raw value contoso.com
and substitute parentcustomerid
lookup with account
query argument (i.e. ?account=GUID
in the URL).
{% view entity="contact" name="Active Contacts" parameters=[ "contoso.com" ] lookups={ "parentcustomerid": params.account } count="10" cache="PT30M" %}{% endview %}
FetchXML queries
The fetchxml
tag allows you to query the CRM using the powerful FetchXML query language. Please refer to MSDN documentation regarding the technology.
The tag supports the following attributes:
collection
-- the name of the variable that would contain query results objectcache
-- specifies expiration time for the fetched records. The format is based on the ISO 8601 duration specification
The FetchXML query is contained between the fetchxml
and endfetchxml
tags.
{% fetchxml collection="contacts" cache="PT30M" %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="contact">
<attribute name="fullname" />
<attribute name="emailaddress1" />
<attribute name="contactid" />
<order attribute="lastname" descending="false" />
</entity>
</fetch>
{% endfetchxml %}
Variable contacts
would contain an object with the following fields:
xml
- the original FetchXML queryresults
entities
- collection of fetched entity recordstotal_record_count
- the total record count in case pagination is enabled. Addreturntotalrecordcount="true"
to thefetchxml
element in order to access this valuemore_records
- (boolean) tells whether more records are available if pagination is enabledpaging_cookie
- paging cookie value
error
- contains an error message if there's any
<ul>
{% for contact in contacts.results.entities %}
<li><a href="{{ entityUrl( "contact", contact.id ) }}">{{contact.fullname ?? "[noname]" }}</a> <{{contact.emailaddress1}}></li>
{% endfor %}
</ul>
Forms
form
tag allows you to display CRM forms and custom forms on your WordPress site.
This tag supports the following attributes:
entity
(required) -- entity name of the form (contact, account, lead, etc.)name
-- name of the form. If specified, a CRM form will be renderedmode
-- mode of operation.create
,edit
andupsert
are supported. Use therecord
attribute inedit
/upsert
modes to specify the edited recordoptional
-- array of optional entity attributes (i.e. override CRM constraints)required
-- array of required entity attributes. If the submitted field is empty, the form will emit an error messagedefault
-- map of attribute names and their default values. For lookup fields, the default value format is as follows:{ "LookupAttributeName": { "LogicalName": "contact", "Id": user.id, "DisplayName": user.fullname } }
lookupviews
-- map of lookups that need to be displayed as a dropdown list of existing records per specified view. The value is as follows:{ "LookupAttributeName": [ "ViewEntityName", "ViewName" ] }
redirect
-- URL to redirect to after a successful form submissionmessages
-- a map with messages for the form.success
anderror
keys are supported by default:{ "success": "Form submitted.", "error": "Submission failed." }
key
-- an identifier that helps to distinguish one form from another if two or more forms are present on one page. The key is calculated automatically based on attributes listed above. If there are two identical forms present on one page, please specify a custom keyrecord
-- entity record object to fill form fields from, can be retrieved viacurrentrecord
orentities
objects, or a GUID
To specify a default lookup value, please adhere to the following format: { "LogicalName": "contact", "Id": "00000000-0000-0000-0000-000000000000", "DisplayName": "CRM record" }
.
If the name
attribute is specified, the plugin will render a CRM form, and expose a form
object to the inner template. This object has the following structure:
id
-- unique one-time form IDkey
-- an automatically generated identifier used to distinguish submissions from different forms on one page. May be overridden with thekey
attributename
-- form nametabs
-- FormXML representation of the form. Each CRM form is comprised of a number of tabsexpanded
-- (boolean) whether the tab is not collapsed by defaultshowLabel
-- (boolean) whether to display the tab labellabel
-- label valuecolumns
-- collection of columns inside a tab. Tabs are comprised of a number of columns in Dynamics 365width
-- column width in percentage, with the percent sign appendedsections
-- collection of sections inside a column. Columns are comprised of a number of sections in Dynamics 365showLabel
-- (boolean) whether to display the section labellabel
-- label valuecellLabelAlignment
-- control label alignment (left/center/right)cellLabelPosition
-- control label position relative to the input control (top/left)rows
-- collection of rows. Each section in CRM is comprised of a number of rows. Each row in its turn is a collection of cells, the latter each containing a single control (label + input)showLabel
-- (boolean) whether to display the control labellabel
-- control label valuecolspan
-- number of cell columns in the row used to display the controlrowspan
-- number of rows used to display the controlisSpacer
-- (boolean) whether the cell contains a spacercontrol
-- control settingsid
-- control IDclassId
-- control class ID (see MSDN)disabled
-- (boolean) whether the control is disabledrequired
-- (boolean) whether the control is required, defined by entity attribute metadata, form settings andoptional
/required
attributes for the Twig tag (the latter values take priority)parameters
-- map of control parameters (see MSDN)options
-- map of entity records. Available if the entity attribute is specified in thelookupviews
attribute for the Twig tag
options
dateformat
-- date format to use with thedate
Twig filterdatetimeformat
-- date/time format to use with the `date Twig filter
metadata
-- metadata of the form entity (attributes, relationships, etc.)entities
-- (deprecated, use the globalentities_list
object) map of all entities in the CRM (logical name -> display name)parameters
-- map of attributes supplied to the form tagrecord
-- record object
The default form template is located in templates/twig/form.twig
. If you need to create a new form template, please refer to it.
Displaying custom forms
You don't need a form defined in CRM to capture data from WordPress. You can design your own form, and data received from it will be sent to Dynamics 365 the same way if you had a CRM form.
To capture data this way, you need to define a custom template inside the {% form %}{% endform %}
tags. You need to specify the entity name, and you must not include the name
attribute. In the template, a POST form must be present, and input names (name
attribute) must correspond to respective CRM entity attribute names. You can enforce required fields on your custom form with the required
attribute.
If you have more than one Twig form on the page, you need to add the hidden _key
input and specify form.key
as its value. This will help to distinguish submissions from different forms. If you omit the key, every form present on the page will try to process the submission which is likely undesired.
{% form entity="lead" mode="create" required=["lastname", "emailaddress1", "description"] %}
<form method="POST">
<input name="firstname" required placeholder="First Name">
<input name="lastname" required placeholder="Last Name">
<input name="mobilephone" type="tel" placeholder="Phone Number">
<textarea name="description" rows="4" placeholder="Share Your Story"></textarea>
<button type="submit">Submit</button>
<input type="hidden" name="_key" value="{{form.key}}">
</form>
{% endform %}
Access to records by ID
You can access any entity record by its ID.
{% set fooContact = entities.contact["36049e71-8132-e711-8102-5065f38b2601"] %}
{% set barAccount = entities.account["ce039e71-8132-e711-8102-5065f38b2601"] %}