Dynamics 365 portals: Customize Knowledge Articles

One of the more popular features of the Dynamics 365 portals is its ability to expose the knowledge articles from your internal CRM on the public portal or to select audiences. With how the knowledge article functionality is currently implemented in the portal there is not an easy way to customize the article display or enhance it with more functionality like attachments. However with the customization capability of liquid we can create our own display of an article that includes whatever other data is accessible through liquid. In this post we will look at an example and the other elements like search results that need to be modified to properly support this approach.

Firstly let’s start out by creating our custom article liquid template. To do so create a new Web Template and we are going to assume that an ID parameter will always be passed in the query string so we know what article to surface.

{% assign article = entities.knowledgearticle[request.params.id] %}
<div class="container">
  <div class="page-heading">
      {% include 'Breadcrumbs' title: article.title %}
  <div class="page-header">
     {% if article %}{{article.title}}{% else %}No article found{% endif %}
     <div class="pull-right">
	    <div role="toolbar" class="btn-toolbar">
		    <div class="btn-group">
			    <a href="javascript:window.print()" class="btn btn-default btn-sm"><span class="fa fa-print"></span>&nbsp;{{ snippets['Knowledge Management - Print Button Label'] }}</a>
 <div class="row">
  <div class="col-md-12">
   <div class="page-copy">
     {% if article %}
       {{ article.content }}
     {% endif %}

This template simply takes the ID parameter, gets the knowledgearticle entity record and then uses the object to display the breadcrumbs using the title parameter in that template. Then displays the page title using the article title and displays a print button just like the default article template. Finally we display the article content attribute which is where the HTML blob is stored if the article is found.

A common enhancement is to add a display of the associated note attachments to the article. With liquid we can easily access the notes and display them in a fashion to provide a list of downloads. You can see the liquid note documentation here. Below is a simple liquid code that will output the notes that are associated to the article displaying the title linked (manually as note.url seems broken or disabled or changed and not documented in v8.x) as well with the note text as the description.

{% assign notes = article.knowledgearticle_annotations %}
{% if notes.size > 0 %}
 <h3>Associated Documents</h3>
   {% for note in notes %}
     <li><p><a href="/_entity/annotation/{{note.id}}">{{note.subject}}</a><br/>{{note.notetext}}</p></li>
   {% endfor %}
{% endif %}

This can be added where you want the list of attachments to display, for this example it is inserted right after the {{article.content}}. This could be further enhanced to conditionally include only this notes that have documents using the attributes of the annotation entity and condition liquid tags. With your web template completed, you should now create a page template and a web page that uses that page template. Once the web page is created, also create a site marker that references the web page as we will use this later to help us link to the new article page.

There are a lot more things you can add to your articles using liquid. You just need to parse through the relationships associated to the article and then present the data appropriately. I may look at some further enhancements in future posts.

With building a custom article template we need to deal with the fact we no longer want the links navigating to the old MVC based article routing. To do so we need to try to replace all the locations that this routing is in place. The largest one is probably the search. With the search being built off handlebars and liquid as we explored in a preview post – Extend Search Results with Handlebars, you can change the default URL for knowledge article results.

First we need to add a handlebars helper in JavaScript to the search results page so we can put in some conditional logic to change the URL when the result is for a knowledgearticle entity record. This is just a simple addition that allows you to do an if equals in handlebars.

Handlebars.registerHelper('if_eq', function(a, b, opts) {
    if(a == b) // Or === depending on your needs
        return opts.fn(this);
        return opts.inverse(this);

Now we can make use of this new helper in the Faceted Search – Results Template Web Template. Within the {{#each items}} we are going to modify the contents of the h3 tag to have some conditional logic to change the default link it uses to be our site marker we previously created.

{{#if_eq entityLogicalName "knowledgearticle"}}
  <a title="{{title}}" href="{%endraw%}{{articleSiteMarker.url}}{%raw%}?id={{entityID}}">{{title}}</a>
  <a title="{{title}}" href="{{url}}">{{title}}</a>

Basically all we have added is a condition that when the result is from a knowledgearticle entity then use our site marker URL passing the entityID as the id as the href of the anchor tag.

Make sure you also at the very top of this web template include a reference to your site marker.

{% assign openTag = '{{' %}
{% assign closingTag = '}}' %}
{% assign articleSiteMarker = sitemarkers["Article"] %}

With the chance of their being some routing that still is hard coded somewhere in the portal we can put some logic on the out of box article default page that will cause it to route to our new page as well. The easiest way to modify this is to login to the portal with an administrative account so you can use the front-side editor to make your changes. Navigate to an existing article you know by using the following route format https://{portal_url}/knowledgebase/article/ka-01000, and replace the ka-01000 with an article code you know exists.

Once on the page then edit using the front-side editor and go to the Options tab. Within the Custom JavaScript section add the following:

var pathArray = window.location.pathname.split( '/' );
var articleCode = pathArray[pathArray.length - 1];
{% assign articleSiteMarker = sitemarkers["Article"] %}
document.location = "{{articleSiteMarker.url}}?code=" + articleCode;

And within the Custom CSS add the following:

body {
  display: none;

This will cause a redirect to your new page while hiding the old one during the redirect. We now also need to enhance our custom web template for the article to take the code parameter as well. Replace the assign liquid at the top of the existing template with the following:

{% if request.params.id %}
  {% assign article = entities.knowledgearticle[request.params.id] %}
{% endif %}
{% if request.params.code %}
  {% 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="{{request.params.code}}" />
  {% endfetchxml %}
  {% assign article = articlefetch.results.entities[0] %}
{% endif %}

With all our changes we should now have a custom article page that takes either the entityId or the article code as a parameter, search results routing directly to the new article and a catch for hard coded links to also redirect to the new page template. The same code here will have produced an article with the following format. You of course with liquid templating functionality can continue to customize and enhance this for your requirements.

Note with all these changes we have removed the content access level functionality. You can add this back by developing the appropriate liquid code to make the necessary checks.

Update 6/23/2017: Just announced at the July 2017 Update Executive Briefings, knowledge articles on the portal will be getting an enhancement to expose notes and attachments. This method in this post will still be of interest to those that find that the display is too limiting or there are other components in which they want to include in their knowledge article display.

12 thoughts on “Dynamics 365 portals: Customize Knowledge Articles

  1. Hi,

    Thank for this. I done it and it’s great. But … how i can add the star for the rating like in MS template for knowledge articles ?

    Tank for your help


    1. I am not aware of an out of box liquid template that adds the rating control so this is not something you could implement in a custom template as it needs to write back to the CRM with the rating. Alternatively you could make a read/display only rating. The latest version of portals 8.3.x does include attachments now so if that is why you were customizing this template you might want to consider using the out of box template now.


  2. Hi Colin,
    Thank you for the detailed guide. We are looking to replace the default article template but would like to keep SEO friendly URLs rather than something like /article/?id=xxx. We have enhanced the numbering for KB articles so that they currently produce urls like this: /knowledgebase/article/KA-01004-this-is-the-article-title/en-us
    We want to implement a structure that will be like /knowledgebase/productname/KA-01004-this-is-the-article-title/en-us and use our own template. Is this something that is possible to do? i.e. extract the KB number out of the URL and use it in the liquid template to render the appropriate article content.


  3. I’m not sure I follow. What I’m looking for is a way to use an entity list for knowledge articles that I can click on to go to that detail form. KA’s for some reason do not allow the OOB functionality of passing a GUID. Does the above code do any of this?


    1. Hi David, yes that is possible. If you see in the liquid code I read the knowledge article GUID from the URL and then use liquid to return the entity with that ID. You can configure an entity list to show a list of articles and the details link to pass the ID as a parameter. Then just read that parameter with your liquid template that displays the article.


  4. Hi there,

    Thanks for this article~! Great stuff. Although the web page does not seem to be using my custom page template > web template but is continuing to use the “Full Page” page template configuration somehow. This is after clearing both the server & client side caches.


  5. Hi Colin,

    Sorry but not sure I’m following. You start by creating a new page template – if I want to edit slightly the current (out of the box) KBA template, do I still need to create a new page template or is there a way to find it and amend?

    Also, if I create a new template, you never specify how now you’re assigning the newly created page template to use instead of the out of the box template?

    Thanks for your help.


  6. Thanks Colin,

    Awesome article. Quick question. Is liquid the only way to expose other KB article fields on the article or is there another way? Say if we want to display a custom field we’ve created on the KB article entity and want to display it somewhere in the content or on the page somewhere.


    1. Hi Mike, sorry the KB article page is still an ASPX template we don’t have access to so the rendering can’t be modified using the normal form controls.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s