ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

PowerApps Portals: Knowledge Articles and Liquid

There are some areas of PowerApps Portals that are still implemented using either ASP.NET MVC or ASPX, instead of via Web Templates, which means the configurability options are limited – one of those is the Knowledge Base (which exposes Knowledge Article entities). Often we can use Liquid and JavaScript to customize some of these areas, but there is one thing in particular that makes doing this for the Knowledge Base challenging – in this post I’ll explain what that is, and how to get around it.

The Challenge

First of all, I was inspired by this question on the community forums. The original poster was looking to display custom fields that already exist on the Knowledge Article entity on the Portal (to make things slightly more complicated, he wanted the display to be conditional on the value of another field).

The Knowledge Base is implemented using ASP.NET MVC, which means we don’t have access to customize the part of the code responsible for displaying a Knowledge Article. However, knowing that we can access data from Liquid, and use JavaScript to insert content onto the page (pretty much anywhere we want), means we should be able to accomplish this requirement. Remember, Liquid is a great tool when you want to read/display data.

However, the challenge is getting access to the Knowledge Article that is currently being displayed.

In Liquid, we have access to the global page variable, which tells us which Web Page we are currently viewing. However, because of the way the Knowledge Base is implemented, the page variable will point to the same Web Page, regardless of the Knowledge Article you are looking at (it’s a Web Page called Knowledge Base – Article Details). As far as I know, there is no global variable that will tell you which article you are currently on, similar to how page works.

Now, if we knew the ID of the Knowledge Article, we could get it from the entities global variable. Often you’ll find the ID of the record being viewed in the query string, however for the Knowledge Base, the URL looks something like /knowledgebase/article/KA-01000/en-us. Instead of the ID, the Knowledge Base implementation uses the “article public number” as the unique key in the URL. That won’t help us if we’re trying to use the entities collection.

So what other options do we have?

The Solve

Of course, we have at our disposal what might be the most powerful Liquid tag of all: fetchxml.

Using a FetchXML query, we can look for the article with a particular “article public number”, thus achieving our goal of getting a reference to the article. Once we have that reference, we’ll have access to all of its properties, including any custom attributes.

We first have to do a bit of string parsing, to extract the “article public number” from the URL. Then we can perform our query (we also add a filter on islatestversion, as each version of a Knowledge Article ends up being a separate record in the database). The resulting Liquid looks like:

{% assign urlSplit  = request.path | split: '/' %}
{% assign urlSplitLength  = urlSplit | size %}
{% assign kaCodeIndex = urlSplitLength | minus: 2 %}
{% assign kaCode = urlSplit[kaCodeIndex] %}

{% fetchxml articlefetch %}
    <fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
      <entity name="knowledgearticle">
        <all-attributes /> 
        <filter type="and">
          <condition attribute="islatestversion" operator="eq" value="1" />
          <condition attribute="articlepublicnumber" operator="eq" value="{{kaCode}}" />
        </filter>
      </entity>
    </fetch>
{% endfetchxml %}

{% assign article = articlefetch.results.entities[0] %}

If you read the forum post that inspired this, and may have seen a link to this blog post from Colin Vermander about a technique to customize the entire Knowledge Article display. Part of his solution looks very similar to what I’m describing here (in fact, once I noticed the similarity, I copied his FetchXML statement rather than crafting my own). One difference is that I’m parsing the “article public number” using Liquid, whereas he does his in JavaScript.

The result of this code is you now have the article as a Liquid object, and access to all of its properties.

Displaying the Custom Attribute

The next question, now that we have the Liquid object, how do we display a custom attribute somewhere on the page?

The code that displays the Knowledge Article doesn’t include the “content” of the Knowledge Base – Article Details Web Page anywhere. So anything you put in the Copy attribute won’t be rendered.

The original poster had mentioned perhaps modifying the breadcrumbs Web Template, however the code doesn’t actually use that Web Template – it includes its own custom rendering of the breadcrumbs.

In theory you could put the code in the header or footer, and only display it if the Web Page is Knowledge Base – Article Details. However, most likely that isn’t going to be where you want it.

I think the simplest approach is to add the required markup using JavaScript. While the Copy field of Knowledge Base – Article Details is not rendered, the Custom JavaScript field is. So you can use a combination of JavaScript and Liquid to add your desired markup to the page. Something like:

$(document).ready(function() {
    $('#content').append($('<div>').html('Custom Field: {{article.new_customfield}}'));
});

If you want to conditionally display the field based on some other field on the article, simply wrap that JavaScript in a Liquid if statement. The full code becomes:

{% assign urlSplit  = request.path | split: '/' %}
{% assign urlSplitLength  = urlSplit | size %}
{% assign kaCodeIndex = urlSplitLength | minus: 2 %}
{% assign kaCode = urlSplit[kaCodeIndex] %}

{% fetchxml articlefetch %}
    <fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
      <entity name="knowledgearticle">
        <all-attributes /> 
        <filter type="and">
          <condition attribute="islatestversion" operator="eq" value="1" />
          <condition attribute="articlepublicnumber" operator="eq" value="{{kaCode}}" />
        </filter>
      </entity>
    </fetch>
{% endfetchxml %}

{% assign article = articlefetch.results.entities[0] %}

{% if article.new_customfield2 == 'somevalue' %}

$(document).ready(function() {
    $('#content').append($('<div>').html('Custom Field: {{article.new_customfield}}'));
});

{% endif %}

One drawback to using JavaScript to accomplish this sort of thing is that if you happen to expose your Knowledge Base publicly, the custom field won’t be indexed by search engines. That should be a relatively small concern in most projects.

7 responses to “PowerApps Portals: Knowledge Articles and Liquid”

  1. Adam Piercy says:

    On a previous project we built a custom web template for the Knowledge article using a combination of fetch, Liquid and JS. We rebuilt the URL and used a similar method as you posted here to build the URL dynamically. It gave us far more control and allowed us to build web pages for the categories so that end users could follow a path for each different service.

    It would be nice for Microsoft to give access to the template (they may have, I haven’t looked recently).

    Great post.

    • Nicholas Hayduk says:

      Thanks Adam!

      Unfortunately there haven’t been any changes to the rendering of knowledge articles, so we still need to use techniques like this.

  2. […] post PowerApps Portals: Knowledge Articles and Liquid appeared first on Engineered […]

  3. […] ๐Ÿ’ฅ – ๐˜ฝ๐™ก๐™ค๐™œ ๐™›๐™ง๐™ค๐™ข ๐™€๐™ก๐™–๐™ž๐™ฏ๐™– ๐˜ฝ๐™š๐™ฃ๐™ž๐™ฉ๐™š๐™ฏ ๐™ค๐™ฃ ๐™๐™š๐™ง๐™ข๐™จ & ๐˜พ๐™ค๐™ฃ๐™™๐™ž๐™ฉ๐™ž๐™ค๐™ฃ๐™จ – http://benitezhere.blogspot.com/2018/07/terms-and-conditions-for-gdpr-in-dynamics-portals.html ๐Ÿ’ฅ – ๐˜ฝ๐™ก๐™ค๐™œ ๐™›๐™ง๐™ค๐™ข ๐™‰๐™ž๐™˜๐™๐™ค๐™ก๐™–๐™จ ๐™ƒ๐™–๐™ฎ๐™™๐™ช๐™  ๐™ค๐™ฃ ๐™†๐™ฃ๐™ค๐™ฌ๐™ก๐™š๐™™๐™œ๐™š ๐˜ผ๐™ง๐™ฉ๐™ž๐™˜๐™ก๐™š๐™จ – https://www.engineeredcode.com/blog/powerapps-portals-knowledge-articles-and-liquid […]

  4. […] ๐Ÿ’ฅ – ๐˜ฝ๐™ก๐™ค๐™œ ๐™›๐™ง๐™ค๐™ข ๐™€๐™ก๐™–๐™ž๐™ฏ๐™– ๐˜ฝ๐™š๐™ฃ๐™ž๐™ฉ๐™š๐™ฏ ๐™ค๐™ฃ ๐™๐™š๐™ง๐™ข๐™จ & ๐˜พ๐™ค๐™ฃ๐™™๐™ž๐™ฉ๐™ž๐™ค๐™ฃ๐™จ – http://benitezhere.blogspot.com/2018/07/terms-and-conditions-for-gdpr-in-dynamics-portals.html ๐Ÿ’ฅ – ๐˜ฝ๐™ก๐™ค๐™œ ๐™›๐™ง๐™ค๐™ข ๐™‰๐™ž๐™˜๐™๐™ค๐™ก๐™–๐™จ ๐™ƒ๐™–๐™ฎ๐™™๐™ช๐™  ๐™ค๐™ฃ ๐™†๐™ฃ๐™ค๐™ฌ๐™ก๐™š๐™™๐™œ๐™š ๐˜ผ๐™ง๐™ฉ๐™ž๐™˜๐™ก๐™š๐™จ – https://www.engineeredcode.com/blog/powerapps-portals-knowledge-articles-and-liquid […]

  5. Michaela says:

    Hello,

    I have an issue with breadcrumb from a category and an KB article.
    I have a list of articles in a page, and the list is added with fetch xml.
    When I open an aticle from the list the breadcrumb is not the right one.

    This is the breadcrumb from categories page
    Home > Getting Started > eSIM
    And the breadcrumb when I open an article from that page is:
    Home > Knowledge Base – Home > KB-01132

    I want to be like this :
    Home > Getting Started > eSIM > KB-01132

    If you can help me with this?
    Thanks

    • Nicholas Hayduk says:

      To do that would require some JavaScript.

      Breadcrumbs show you the location of the page in the site hierarchy. KB articles live under the Knowledge Base – Home page. So the breadcrumb is correct. There are lots of different ways of getting to the article page (via search, direct link, categories page, etc), and the page doesn’t know which one it came from.

      To achieve what you’re looking for, you’d either need to access the referrer in JS or you’d need to set something in cache/cookie when the user visits the category page so that when you visit the article you know where it came from.

      Nick

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.