Dynamics 365 Portals - Liquid Templates - Part 3 - Retrieve Data using FetchXML

In Part 1 of this series I discussed the basics of Liquid Templates and walked you through how to create a simple Web Template using Liquid Template Language.  In Part 2, I discussed how to retrieve data using Liquid.

Dynamics 365 Portals – Liquid Templates – Part 1 – Hello World!

Dynamics 365 Portals – Liquid Templates – Part 2 – Retrieve Data

In this article, I’ll discuss following topics.

  1. Retrieve a list of records using fetchxml tag
  2. Creating a service using Liquid and Web Templates

Retrieve a list of records using fetchxml tag

So far, we have used the entity list associated with the page to retrieve data. What if our requirement is quite complex? What if we don’t want to create 20-30 different views with different filter criteria? Luckily, we can use FetchXML with Liquid.

Let’s look at a simple example. Let’s say in my contact list, I have a bunch of superheroes. I want to create a custom web template to display the superheroes who are part of Avengers. For example, I don’t want to see Bruce Wayne on my list (Disclaimer: I have nothing against the Batman).

Contact list

Code Snippet

<div class="container">
  <div class="page-heading">
    {% include 'breadcrumbs' %}
  </div>
  {% include 'page_header' %}
  {% include 'page_copy' %}
  {% fetchxml my_query %}
    <fetch version="1.0" mapping="logical">
      <entity name="contact">
        <attribute name="fullname" />
        <attribute name="parentcustomerid" />
        <attribute name="contactid" />
        <attribute name="description" />
        <attribute name="websiteurl" />
        <order attribute="fullname" descending="false" />
        <filter type="and">
          <condition attribute="statecode" operator="eq" value="0" />
          <condition attribute="parentcustomerid" operator="eq" value="{{ request.params['id'] | xml_escape }}" />
        </filter>
      </entity>
    </fetch>
  {% endfetchxml %}
    
  {% for result in my_query.results.entities %}
      <div name="content" style="padding: 15px 30px 0 0; clear: both;">
        <h2> {{ result.fullname | escape }} </h2>
      	<div name="image" style="width: 300px; float: left; padding: 0 0 0 15px;">
      	  <img src={{ result.websiteurl | escape }} height="150" width="150"  >
      	</div>        		
      	<div name="main-content" style="margin-left: 300px; max-width: 800px;">
      		<p> {{ result.description | escape }} </p>
      		<br />        			
      	</div>        		
      	<div class="clear"></div>
      </div> 
  {% endfor %}
</div>

Using the fetchxml tag, we can create a dynamic FetchXML query.  In this example, we are saying bring all the contact records where parentcustomerid is the value of the ID querystring.  The retrieved records are now in my_query object.

To learn more about how to create a fetchxml query, please refer to below official Microsoft MSDN article.

Build queries with FetchXML

But the easiest way is to use “Advanced Find” feature to build a query and then use the “Download FetchXML” button to generate the fetchxml query.  Then you can modify required sections.

Advanced Find to create fetchxml queries

Now that we have the data, similar to the previous examples in Part 2, we can structure the attributes which ever way we like.  The interesting thing is that when we use FetchXML queries, we don’t have to associate an entity list with the web page.

Below is the parent Web Page record.  Note that “Entity List” field is NOT populated.

Web Page - Display entity list - FetchXML Example

Below is the Web Page – Content Page.  Note that “Entity List” field is NOT populated.

Web Page - Content Page - Display entity list - FetchXML Example

In my example, the URL is https://mysitename.microsoftcrmportals.com/wp-module5/?id=04E6810D-B36B-E711-8177-E0071B7FD0F1 and the output looks like this.

Retrieve a list of records using fetchxml tag

Creating a service using Liquid and Web Templates

Now, let’s think of a scenario where you don’t have to display the Dynamics 365 data on the page but you want to send it off to another external system.  You want to use JavaScript to get the data in XML or JSON format.  In this last example, I am going to show you a way to use Liquid Web Templates to create your own web service.

Code Snippet

{% fetchxml my_query %}
  <fetch version="1.0" mapping="logical">
    <entity name="contact">
      <attribute name="fullname" />
      <attribute name="parentcustomerid" />
      <attribute name="contactid" />
      <attribute name="description" />
      <attribute name="websiteurl" />
      <order attribute="fullname" descending="false" />
      <filter type="and">
        <condition attribute="statecode" operator="eq" value="0" />
        <condition attribute="parentcustomerid" operator="eq" value="{{ request.params['id'] | xml_escape }}" />
      </filter>
    </entity>
  </fetch>
{% endfetchxml %}
  
{ "superheroes" : 
  [
    {% for result in my_query.results.entities %}
      {
        "fullname" : "{{ result.fullname }}",
        "websiteurl" : "{{ result.websiteurl }}",
        "description" : "{{ result.description }}"
      }
      {% unless forloop.last %},{% endunless %}
    {% endfor %}
  ] 
}

Similar to the previous example, let’s use FetchXML to retrieve some data.  Now, let’s format the data in JSON format. You can use Liquid statements inside not only HTML but also JSON. You may notice that I have added the unless tag to add the comma to all records except the last. If you don’t do this, you’ll get JSON formatting errors.  This statement will make sure to not include a ‘,’ (comma) after the last record.

The trick here is the MIME property. If you set this to application/json, the data is sent as a JSON payload.
Web Template - Web service - MIME Type

In my example, the URL is https://mysitename.microsoftcrmportals.com/wp-module6/?id=04E6810D-B36B-E711-8177-E0071B7FD0F1 and the output looks like this.

Summary

  • Use Liquid Template Language to create custom Web Templates
  • Use Tags for logic, Objects to access CRM data, and Filters to modify the output of data
  • Access parameters with request.param
  • Use include to include other Web Templates
  • Include ‘entity-list’ to get the data associated with Entity List of the page
  • Use entitylist and entityview tags to access data associated with the given entity list and view.
  • Use fetchxml to retrieve data Dynamically
  • Use Liquid Web Templates to create your own web services.
  • Change the MIME Type to change the payload type.

References

http://dyn365apps.com/2017/01/29/quick-reference-liquid-template-engine-reference-manual-for-dynamics-365-portals/

http://colinvermander.com/2017/04/17/dynamics-365-portals-use-liquid-to-return-json-or-xml/

https://community.adxstudio.com/products/adxstudio-portals/documentation/configuration-guide/liquid-templates/

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/portals/custom-templates-dynamic-content

The Avengers images are from http://avengers.marvelkids.com/characters

Thank you for visiting Dyn365Apps.com.

Follow me on Twitter to get the latest news, tips and tricks and more …

Until next time…

About the Author

Nadeeja Bomiriya is a Microsoft MVP, Chapter Lead – CRM Saturday – Australia, President – Melbourne Dynamics 365 User Group, Technical Architect, and Dynamics 365 Practice Lead who lives in Melbourne, Australia.