Power Apps Portals

Custom URL Query Parameters for your Power Apps Portals

This post is dedicated to the amazing Megan V Walker – the selfless MVW MVP whose epic content got me started on my portal customisation journey. Be sure to checkout her YouTube channel and/or blog

If you’ve spent any time navigating a Power Apps Portal, you may have noticed that you tend to see GUIDs in the URL (a GUID is a record’s globally unique identifier) e.g. here’s the URL for a specific album (Definitely Maybe, if you wondered) on my portal:

https://songify.powerappsportals.com/album-gallery/?id=e8a2beda-dc34-eb11-bf68-002248006c8d

The GUID is passed in a URL query string parameter called id. This is the default parameter used throughout the portal e.g. when navigating from an entity list to an entity form.

With liquid, we can access query string parameters using the request.params object and the name of the parameter, like so:
{{ request.params.anyparametername }}

For the id parameter that stores the GUID, it’s:
{{ request.params.id }}

We can then use that GUID in liquid e.g. to retrieve the record using the entities object, like so:
{% assign album = entities[‘musdyn_album’][request.params.id] %}

It took me a while to realise but we can create any number of query string parameters and leverage them in liquid. Surprisingly (to me at least!), it doesn’t even require any configuration or site settings to enable… just include whatever you want in the URL and then retrieve it in liquid using request.params.anything

Note – maybe not quite “anything”… be sure not to include any spaces or special characters other than hyphens and underscores.

You can also chain together multiple query string parameters. To do so, just place an & between them

Example use cases

Style a page differently depending on the source… or conditionally show/hide sections of the page depending on the source. I used this on the Songify portal to show record label admins a particular message only if they’d arrived from the wizard screen (a multi-step web form)

https://myportalurl.com/track/?source=wizrard

Screenshot of a custom web template conditionally showing content based on source equals wizard

…and here’s the liquid that drives that:

{% if request.params.source == 'wizard' %}
<h2>Here's how your track will look to our listeners, {{ user.firstname }}.</h2>
{% endif %}

Dynamically filter a list – I use this method on my inbox template. My case review clients could have 100s or even 1000s of messages in their inbox. So when they navigate from a specific case, I filter the inbox to only show messages regarding that particular case. I assume humans don’t find GUIDs very memorable or even legible so I use an autonumber field e.g.

https://myportalurl.com/inbox/?case=CAS-2702-MUSSO

I could even take it a step further and only show unread messages or messages received in the last 30 days, like so:
https://myportalurl.com/inbox/?case=CAS-2702-MUSSO&age=30&status=unread

I then conditionally include those in the filter for my fetch XML query like so…

{% fetchxml open_informationrequest_query %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="sbg_informationrequest">
    <attribute name="sbg_subject" />
    <attribute name="createdon" />
    <attribute name="statuscode" />
    <attribute name="sbg_rfrticket" />
    <attribute name="sbg_duedate" />
    <attribute name="sbg_case" />
    <attribute name="sbg_lastresponsedate" />
    <attribute name="sbg_informationrequestid" />
    <attribute name="ownerid" />
    <attribute name="sbg_informationdocumentationrequested" />
    <attribute name="sbg_approvalrejectioncomments" />
    <order attribute="createdon" descending="false" />
    <filter type="and">
{% if request.params.status == 'unread' %}
      <condition attribute="statuscode" operator="eq" value="858680000" />
{% endif %}
{% if request.params.age %}
      <condition attribute="createdon" operator="last-x-days" value="{{ request.params.age }}" />
{% endif %}
    </filter>
      {% if request.params.case %}
      <link-entity name="sbg_rfrticket" from="sbg_rfrticketid" to="sbg_rfrticket" link-type="inner" alias="ad">
      <filter type="and">
        <condition attribute="sbg_ticketnumber" operator="eq" value="{{ request.params.case }}" />
      </filter>
    </link-entity>
    {% endif %}
  </entity>
</fetch>
{% endfetchxml %}

So in conclusion, custom URL query string parameters provide lots of flexibility and styling possibilities for very little effort. The only catch is we can only really leverage them using liquid and within hyperlinks that you’ve manually crafted (they won’t apply to entity lists, sub-grids, search, etc.).

I’d like the a global option to hide GUIDs from the user and only show customer-friendly URLs.

Franco Musso

You may also like

Leave a reply

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