Flow - lightweight fast template engine using Split twice

Technique 2 β€” Building a Lightweight Template Engine (Using Split Twice)

Take this example (using a handle-bar stil syntax)

ABC {{def}} GHI {{jkl}} MN

Using a dictionary (Compose)

{
  "def": "fish 🐟",
  "jkl": "chips 🍟"
}

We want to build a mini-template engine.
Now you might think - ah ok, let’s get some variables in here.

But John really dislikes variables in fact most of these flow hacks are how to not use variables. So how do you do this without variables?

1. Split on {{

split(outputs('Compose'), '{{')

result

[ 
  "ABC ",
  "def}} GHI ",
  "jkl}} MN"
]

2. Split each on }}

inside each item, split again

split(item(),'}}')

So now our original string becomes either:
["ABC "]

or

["def"," GHI "]

Recap, combine step 1 and 2

Select:
  from: split(outputs('Compose'), '{{')
  item: split(item(), '}}')

3. Conditional replacement using dictionary lookup

if(
  equals(length(item()),2),
  concat(
    outputs('Dictionary')?[item()?[0]],
    item()?[1]
  ),
  item()?[0]
)

Hidden insight

So the trick is this. If the row has 2 elements, that means the first element is a token, the rest is the remainder. If the row has only 1 element - then just return that.

[
  item()[0],
  dictionary[item()[0]] item()[1],
  dictionary[item()[0]] item()[1]
]
==>
[
  "ABC",
  "fish 🐟 GHI",
  "chips 🍟 MN"
]

If you want your dictionary lookup to be case insensitive, you can add toLower() to wrap around item()?[0]

4. Join it all together

join(body('Select'),'')

Result

ABC fish 🐟 GHI chips 🍟 MN

No loops.
No apply-to-each.
No regex.
No variables.
Super fast zero-second action.

This technique lets you:

  • Build dynamic email templates

  • Create server-side HTML rendering logic

  • Replace merge fields safely

  • Do token replacement in Dataverse text

  • Build dynamic document generators

All using standard Power Automate expressions.


About: The old trigger URL will stop working on November 30, 2025

Starting in August 2025, we’ve begun to see this warning a lot in our Power Automate flows that uses HTTP Request (or Team Webhook) triggers.

β€œThe old trigger URL will stop working on November 30, 2025. Your tools that use this flow WILL break unless you update them with the new URL.”

The old url uses the logic app domain:

https://*.logic.azure.com/workflows/{flow-name}/triggers/manual/paths/invoke

The new URL uses a largely undocumented api.powerplatform.com domain.

https://{environment-name}.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/{flow-name}/triggers/manual/paths/invoke

Why New URL?

The NEW URL looks to be more future proof and ties the invoke URL to the environment and flow name within Power Platform, rather than the underlying logic apps infrastructure.

Microsoft’s documentation is here: Changes to HTTP or Teams Webhook trigger flows

Flow Studio new feature: Flow (Request) Report

To help with updating these URLs, we decide to put in a special View and Report for this in Flow Studio. Here, we are doing 4 things:

  • This report shows flows that use the "When an HTTP request is received" trigger. These flows can be triggered externally via HTTP requests, making them suitable for integration scenarios.

  • First we do a scan of all the environments and find all your flows that use this trigger. This may take a few minutes depending on the number of environments and flows.

  • Then for each flow we will need to check the flow definition to extract the old and new request URL and method.

  • We also need to check the flow's run history to see if it has been triggered recently. This will help us identify active flows.

We present this in a quick table for you to browse, but also provide an Export to Excel functionality so you can decide how you want to tackle the list.

Permissions

Because of the API access we need to read definition and trigger callback URL, this is not a scan we can do at the admin level - it has to be the owner of the flows.

You can find this new feature in our dev build:
https://dev.flowstudio.app

Where to find John presenting in May 2020

We are living right now in a strange time. At home, and virtual events are replacing the traditional physical events.

I’ve agreed to several events and will be presenting all new (or freshly updated) topics for 2020. So while we remain physically distant, if you wanted to see one of my presentations - I’m actually a lot more visible.

May 01 - DC Power Apps & Power Automate usergroup - Why and How to implement Governance of the Power Platform

May 06 - Sydney Serverless meetup - Power Automate - Microsoft’s insane low-code serverless platform

May 11 - M365 May - Deep dive into Approvals in SharePoint and Teams with Power Automate

May 11 - USYD Cloud Society Azure/Power Up! - Intro Power Apps and Power Automate

May 15 - Sydney Power Apps and Flow usergroup - What’s new in Power Virtual Agents with Charles Sterling

May 16 - D365 Automation Saturday - Flow JAM Stack - how to build a complete low-code public website in 40 minutes

May 25 - UNSW Cloud Society - Azure/Power Up! - Intro Power Apps and Power Automate

May 26 - M365 May - Why and How to implement Governance of the Power Platform

May 27-28 - M365 Virtual Marathon - 5 Design Keys to make Flows run insanely fast

May 27-28 - M365 Virtual Marathon - Flow JAM Stack - how to build a complete low-code public website backed by M365

I’m still working on my YouTube series: How to build a public website with a Flow JAM Stack

Because of the events next week, I couldn’t work on an episode this week. But next Saturday’s Flow JAM Stack talk during the Automation Saturday will be a 40 minutes compressed teaser. Hope to catch you at one or many of these upcoming events.

Implementing a fast sort with Microsoft Flow using Parallel Compute

This is #FlowNinja hack 112. Parallel Compute Sort.

I had written about how to sort with a variable (this is insertion sort) back in 2018 How to implement sort with Microsoft Flow-in-3-actions-within-a-loop

But in this previous method, the use of variable means we can’t run apply to each in parallel, so this method was always slow when array is large. Today, while chatting with Hiro - I had a sudden idea to revisit the pattern and see if I can make this quicker.

Photo by Amy Shamblen on Unsplash

Photo by Amy Shamblen on Unsplash


The problem

To create a sort, using parallel apply to each, and get a sorted array at the end.



In 2018, I didn’t have many of the patterns I need to make this new 2020 sort method. Firstly, to get results from parallel apply to each, we need Pieter’s Method (Compose apply to each inner output) to fan-in after parallel fan-in.

Second, we need to sort the actual array, and I came up with a pretty interesting method.



How this works

Consider array [ β€œd”, β€œe”, β€œc”, β€œb”, β€œa” ]
If we say for each character, filter array for items that are < than the current item, we’d get:

3:d, 4:e, 2:c, 1:b, 0:a

Then, if we consider, hey, we have 5 items

[0, 1, 2, 3, 4] => map to this dictionary, we’d get [ β€œa”, β€œb”, β€œc”, β€œd”, β€œe” ]



Side Story

I actually was thinking about this pattern while driving home, once it clicked I had to pull over the side, park the car, take out my laptop and write this Flow, and after I saw it work I drove home.



Steps

Some additional considerations


If the original array has duplicates

[ β€œa”, β€œb”, β€œb”, β€œc” ]
0:a, 1:b, 3:c

We’ll see 2 is missing. This is not end of the world, but when we do the final map of

[0,1,2,3] => [ β€œa”, β€œb”, null, β€œc” ]

Observation

I was worried that JSON('{ "0": "a", "0":"a" }') would give an error, but it seems like the duplicate key is ignored. This could be an interesting way to detect duplicates in the future by building a dictionary.





Flow - Format Number advanced tips and tricks

I put together a video to celebrate the new update in Microsoft Flow (Power Automate) and Logic Apps - formatNumber()

The video explains 3 tips and 2 gotchas.

  • Tip 1: Use action in prod right now

  • Tip 2: Use ### and 000 patterns in formatNumber() expressions

  • Gotcha 2.1: May be don't use of $### - use $##0

  • Gotcha 2.2: May be don't use $ - use C or C2

  • Tip 3: Use formatNumber in collections with Select/Create HTML

If you want the clipboard paste of the Format Number action to use, use this.

{
    "id": "c1fa8a84-e2c0-4be0-823e-3a45-1e6834aa",
    "brandColor": "#a098e6",
    "connectionReferences": {},
    "icon": "https://psuxaustralia.azureedge.net/Content/Images/DesignerOperations/numberfunctions.png",
    "isTrigger": false,
    "operationName": "Format_number",
    "operationDefinition": {
        "type": "Expression",
        "kind": "FormatNumber",
        "inputs": {
            "number": 12345,
            "format": "C4"
        },
        "runAfter": {
            "Compose": [
                "Succeeded"
            ]
        }
    }
}