
Overview: Liquid is an open-source template language created by Shopify and adopted by Microsoft in Power Pages (formerly Power Apps Portals) to dynamically render content on web pages. It enables developers and site makers to embed logic, display data, and interact with Dynamics 365 / Dataverse within a Power Pages site.
In Power Pages, Liquid templates are used extensively within Web Templates, Content Snippets, Web Pages, Entity Lists, and Entity Forms to dynamically generate HTML and insert data.
This guide walks you through a deep, structured explanation of how to use Liquid in Power Pages, including syntax, features, data binding, and use cases.
1. What is Liquid?
Liquid is a declarative, logic-aware template language that is safe and fast. In Power Pages, it provides a bridge between HTML layout and Dataverse data.
Key Capabilities:
- Insert dynamic data from Dataverse.
- Apply conditions (if,unless) and loops (for,cycle).
- Use filters for formatting data.
- Render reusable templates using include,block,extends.
2. Where You Can Use Liquid in Power Pages
- Web Templates – Define layouts using Liquid.
- Content Snippets – Add reusable content blocks.
- Web Pages – Add custom Liquid in the copy field or source code.
- Entity Lists – Modify list rendering with Liquid.
- Entity Forms – Inject logic before/after form rendering.
3. Basic Liquid Syntax
3.1 Output
{{ user.name }}
Outputs the value of the user.name variable.
3.2 Logic
{% if user.is_admin %}
  <p>Welcome, admin!</p>
{% endif %}
3.3 Loops
{% for account in entities.accounts %}
  <p>{{ account.name }}</p>
{% endfor %}
4. Liquid Tags and Filters in Power Pages
Tags (Control Flow)
- {% if condition %}– conditional branching.
- {% for item in collection %}– loop over collections.
- {% assign variable = value %}– define new variables.
- {% include 'template' %}– include other templates.
- {% capture var %} ... {% endcapture %}– store block output.
Filters (Formatting)
Filters are applied with a pipe | symbol:
{{ now | date: "%B %d, %Y" }}
- date: formats date.
- capitalize: makes first letter uppercase.
- downcase: lowercase text.
- upcase: uppercase text.
- truncate: shortens strings.
5. Accessing Dataverse Data with Liquid
Power Pages expose entity records via the entities object.
Example: Displaying Account Names
{% assign accounts = entities.account | where: "statecode", 0 %}
{% for account in accounts %}
  <p>{{ account.name }}</p>
{% endfor %}
Retrieve a single entity by ID:
{% assign contact = entities.contact[params.id] %}
<p>{{ contact.firstname }} {{ contact.lastname }}</p>
6. Using Liquid in Web Templates
Web Templates allow reusable HTML + Liquid structures.
Sample Web Template:
<h2>Featured Products</h2>
<ul>
  {% for product in entities.product %}
    <li>{{ product.name }} - {{ product.price | money }}</li>
  {% endfor %}
</ul>
Then in your Web Page, refer to this template using a Page Template of type Web Template.
7. Using Parameters in Liquid
Parameters allow passing query string data to your template.
URL: https://yoursite.powerappsportals.com/products/?type=electronics
Liquid:
{% assign type = request.params['type'] %}
<h2>Showing products for: {{ type }}</h2>
8. Security and Liquid
Liquid templates are sandboxed. You cannot execute server-side scripts or access restricted data unless permitted via permissions.
To access entity data:
- Entity permissions must be configured.
- The user accessing the page must have the required roles.
9. Advanced Concepts
9.1 Using Includes
{% include 'header' %}
<p>Main content</p>
{% include 'footer' %}
9.2 Using Blocks and Extends
Power Pages supports template inheritance:
Layout Web Template (layout.html):
<html>
  <head><title>{% block title %}{% endblock %}</title></head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>
Child Template:
{% extends 'layout' %}
{% block title %}Home{% endblock %}
{% block content %}
  <p>Welcome to the home page!</p>
{% endblock %}
10. Using Liquid in Content Snippets
Content snippets can store small Liquid-based blocks for reuse.
Content Snippet:
<p>{{ user.fullname }} logged in at {{ now | date: "%H:%M" }}</p>
Can be placed anywhere in your layout or page.
11. Best Practices
- Keep Liquid logic simple and delegate complex logic to JavaScript or Power Automate when possible.
- Use captureto build complex strings or HTML fragments.
- Always test entity permissions to ensure data renders correctly to users.
- Organize reusable templates in structured Web Templates.
- Use filters like escapeto prevent XSS vulnerabilities.
12. Common Use Cases
- Display logged-in user info ({{ user.fullname }}).
- Dynamically list Dataverse records.
- Show/hide sections based on roles or permissions.
- Inject meta tags, Open Graph tags, or structured data.
- Build email or print views with dynamic Liquid rendering.
13. Limitations of Liquid in Power Pages
- Cannot perform real-time API calls or complex server-side logic.
- Limited looping and conditional logic compared to full scripting.
- No access to non-permitted entities unless explicitly configured.
- May require combining with JavaScript for full dynamic behavior.
