/ Development  

Master the art of the low-code config entity; Unleash the astonishing power of Base64 JSON

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

The input for this blogpost is derived from my own blogpost…The one about crafting a tiled landing-page some weeks ago. I was searching for a way to configure my panels properly, and found an amazing way to do it nicely! Why? Well, I always try to avoid hard-coded elements in my solutions, and it’s time to show you how to make this work. You can introduce a ‘Config’ kind of entity doing the trick as well, but a solution can also have a (in my opinion) underrated ‘Configuration’ entity. I played with this entity before during my feature toggles post, but this time I use it to inject my custom page with a JSON configuration.


Let get right into it…

Do you remember that custom landing page?

base64_json_001

If you look at the repetition of data, it’s an interesting thought to make it configurable with a JSON dataset like this (the ... will contain additional cards!):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"cards":[
{
"background_color":"#055e78",
"font_awsome_icon":"fa-regular fa-bell",
"header":"Featured",
"title":"Solution 1",
"subtitle":"Card subtitle",
"content":"Some quick example text to build on the card title and make up the bulk of the card's content.",
"homepage_reference":"#"
},
...
]
}

The only question here would sound like this: How on earth do we get this data injected into the custom tiled landing-page!?!?


The solution

My approach (keep reading for other untested approaches at the end!) would be to make this JSON-part configurable data for you administrators! This way they can add new cards (if needed), without creating a new CAP package. How? Well, via the configuration entity on your project.
Have yourself a right-click on your project and select ‘Application configuration’. This will just create a single instanced entity (I name it cm_generic) with its own building blocks. I simply add one property cfg_landingpage (of type ‘Long text’) which will contain my JSON data. You can generate all the other BBs and add your ‘Security’ BB (if needed). After deployment, you can open the configuration entity layout from the administration portal (‘/app/admin’), and you can paste your JSON data into the field.

The next step is to get a grip on the JSON data! How? Well, open your homepage document and in there we’ve created a ‘Content’ panel with a link to ../../../html/landingpage.htm…Remember? Have a double-check here! What if we extend this with something like this: ../../../html/landingpage.htm?input={config.cm_generic.Properties.cfg_landingpage}

Interesting! It works, but not ideal!! Why not? Well, the browser will start to encode the URL parameters; So, our well-defined JSON data is a mess with % characters. What would be a better solution? After some Googling, I conclude that Base64 is my way to solve it. How?…

  1. Grab your well formatted JSON
  2. Minify your JSON data here
  3. Copy the minified JSON, and encode it to Base64 here
  4. Copy the Base64 generated string, and paste it in your cfg_landingpage property as value in ‘/app/admin’! So, it replaces the JSON data with that Base64 string!

So, now our landingpage.htm gets injected with a Base64 string on the input URL parameter! GREAT…Now what? Well, read it with JavaScript magic and convert it to an object again (via jQuery as third-party library):

1
2
3
4
5
6
7
8
9
10
$(document).ready(function() {
console.log('Hello world...');

const url = new URL(window.location.href);
const base64String = url.searchParams.get('input');
const binaryString = atob(base64String); //https://www.geeksforgeeks.org/html-window-atob-method/

const cards = JSON.parse(binaryString);
console.log("cards:", cards);
});

This is working GREATLY…It’s a party! 🎉 🎉 Now what? Yes, my friend…That’s the implementation to make your cards dynamic, but I leave that part with you as that’s JavaScript/HTML magic not directly in scope with AppWorks. I just show you the pathway for that head start to be creative in your implementations…


EXTRA TIP: A colleague of mine mentioned that you can add extra links to your homepage document; This link can have a URL location pointing to your ‘/app/admin’ configuration entity layout…NICEEEE! 🤗

Comment me if you touch in the darkness for such feature request… 😵

Extra notes on retrieving data (which I did not try!):

  • With the new JS API it should also be possible to read the config data via the call: window.parent.publicAPIProvider.getItemData(...)
  • With the HTML5 SDK it should also be possible to read the config data via a webservice call: $.cordys.ajax(...); You also need the ‘Web service’ BB on the configuration entity available which is only available in later versions of the platform (At least after AWP 21.4)!

Just a final thought…You have always multiple paths to get to the city of Rome; Another less configurable solution would be like this…
>> This part is only useful if your configuration isn’t changing, and you just need to get input from some JSON data.
…After your JSON data is ready, upload it to your project; I did it in a data sub-folder under my assets folder. I know, you can’t create a JSON type of document in your project, but you can for sure upload such a document! That’s the same for .property files…HINT, HINT!!
So, when you publish that JSON file (mine is called cards.json) under the assets folder (containing the ‘Web Library Definition’), you can simply read the JSON data from a URL like this: http://192.168.56.107:8080/home/CM/data/cards.json. With jQuery, it will be something like this:

1
2
3
4
5
6
7
8
9
10
11
//You can even make this dynamic adding it as extra URL parameter 
//in the 'Content' panel: &baseUrl={system.baseURL}
const organizationUrl = 'http://192.168.56.107:8080/home/CM';
$.getJSON(organizationUrl + '/data/cards.json', function(data) {
// Process the JSON data
console.log(data);
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Handle any errors
console.error('Error:', errorThrown);
});

What I say…This works also for .property files, but I use those in conjunction with Java code published with a ‘Java Archive Definition’ type of document…See here for an example as well!


I’m “DONE” (plugging all my old blogposts! 😁), we greatly explained how to consume JSON data, and injecting it in an interesting way into our custom HTML panel! This explains again the importance of making a solution configurable; In the long-run you admin-people will start to love you for it, and you save yourself a lot of time building a new package when a new solution arrives. Just handover the manual to manipulate the JSON data configuration to the administrator, and the rest is off your plate…That should always be your end-goal to get rid of things “hanging” on your plate! Detach yourself from the solution and make others responsible doing the work…A highly valued skill to do, but most of the time forgotten during short-term thinking and time pressure. That will not be the case in your next feature after reading this post…Have a great configuration weekend, and we’ll meet again, next week in the new AppWorks Tips topic.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?