Using Web Templates as Components in Microsoft Power Pages


Microsoft Power Pages provides an intuitive, low-code approach to building external-facing websites that integrate seamlessly with your data stored in Microsoft Dataverse. One of the most powerful features is the ability to use web templates as reusable components that can render dynamic content on your site. In this post, we'll explore how you can use a web template in Power Pages to display article information from a Dataverse table called Post. Specifically, we'll walk through an example of a Card Component that retrieves article's details using a FetchXML query.
What are Web Templates in Power Pages?
Web templates in Power Pages are HTML files embedded with Liquid code that enables dynamic content generation. Liquid is a templating language that allows you to integrate data from Dataverse, enabling you to build highly customizable web pages. A web template can contain reusable components like headers, footers, and more complex blocks, like a card or a list of articles, that can interact with your database.
Setting up the Example: A Card Component for Article Information
Let's say we have a Post table in Dataverse where articles are stored. Each post contains several fields, including a cover image, the title and content. We want to create a Card component that pulls this information and displays it on a page.
Step 1: Create the Card Component in the Web Template
The first step is to define the Card component in the web template. This is where the HTML and Liquid code come together. Below is an example of how we might structure the code in our template:
<div class="cardwithimage-container"> <a href="#"> <img class="cardwithimage-image" src={ { imgUrl } } alt="" /> </a> <div class="p-5"> <a href="#"> <h5 class="cardwithimage-title"> { { title } } </h5> </a> <p class="cardwithimage-subtitle"> { { subtitle } } </p> <a href="#" class="cardwithimage-button"> { { buttonText } } <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"> <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"></path> </svg> </a> </div> </div> <style> .cardwithimage-container{border-radius:0.5rem;border-width: 1px;border-color: #E5E7EB;max-width: 24rem; background-color: #ffffff;box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);} .cardwithimage-container a:hover{text-decoration: none !important;} .cardwithimage-image{border-top-left-radius: 0.5rem;border-top-right-radius: 0.5rem;} .cardwithimage-title{margin-bottom:0.5rem;font-size:1.5rem; line-height:2rem;font-weight:700; letter-spacing:-0.025em;color:#111827;} .cardwithimage-subtitle{margin-bottom:0.75rem;font-weight:400;color: #374151;} .cardwithimage-button{display:inline-flex;padding-top:0.5rem;padding-bottom:0.5rem; padding-left:0.75rem;padding-right:0.75rem;align-items:center; border-radius:0.5rem;font-size:0.875rem; line-height:1.25rem;font-weight:500;text-align:center;color:#ffffff !important;background-color:#1D4ED8;} .cardwithimage-button:hover{background-color:#1E40AF;} .cardwithimage-button:focus{box-shadow:0 0 0 3px rgba(66,153,225,0.5);outline-style:none;} .cardwithimage-button svg{width:0.875rem;height:0.875rem;} </style> { % manifest % } { "type": "Functional", "displayName": "CardWithImage", "description": "This component displays data using a cards layout", "tables": [], "params": [ { "id": "title", "displayName": "Title", "description": "Card title" }, { "id": "subtitle", "displayName": "Subtitle", "description": "Card subtitle" }, { "id": "buttonText", "displayName": "Button text", "description": "Button text" }, { "id": "imgUrl", "displayName": "Image url", "description": "Card image url" } ] } { % endmanifest % }
Step 2: Get data for specific article
To get the data for a specific article, we can run a FetchXML query that retrieves the Post record details. FetchXML is a proprietary query language used in Microsoft Dataverse to fetch data from tables. Below is a simple example of a FetchXML query that retrieves the most recent post from the Post table:
<fetch top="1"> <entity name="pwp_post"> <attribute name="pwp_title" /> <attribute name="pwp_content" /> <attribute name="pwp_coverimage" /> <order attribute="createdon" descending="true"/> </entity> </fetch>
Step 3: Use the Card Component in the Web Page
When the web template is created and the component is defined, you can add this web template to any Power Page. To do this, go to the Power Pages Studio, open the page where you want to add the Card component, and then reference the web template using the {% include 'template_name' %} syntax. This will render the Card component you created in the web template and display the article information on the page.
{% include 'CardWithImage' %}
or
{% include 'CardWithImage' title:"Title" subtitle:"This is a card with an Image, a Title, a Subtitle and an action Button" buttonText:"Read more" imgUrl:"/forest_image.jpg" %}
As you can see, the card dynamically pulls in the article's cover image, title and content, creating a clean and organized display for the user.
Why Use Web Templates and Components in Power Pages?
Templates are a powerful feature in Microsoft Power Pages that allow you to build dynamic, data-driven websites without extensive coding. By leveraging Liquid and FetchXML, you can create reusable components, such as the Card component in our example, that pull content directly from Dataverse. Using web templates as components in Microsoft Power Pages provides several advantages:
- Reusability: Once you create a web template, you can reuse it across different pages, making your site more consistent.
- Maintainability: If you need to update the design or functionality of the Card component, you can simply edit the template without needing to modify
- Flexibility makes it easy to build sophisticated websites that integrate seamlessly with your backend data. Whether you're displaying a list of articles, user profiles, or other data, web templates and FetchXML queries can help you bring your content to life.