Blog

Trees4Travel system - benefits and use cases of JSON Editor

6
min read
Down arrow button

Blog >

Trees4Travel system - benefits and use cases of JSON Editor
TechInsights

Web applications frequently rely on storing and processing data entered through forms. These are typically used in predefined scenarios, where the backend application expects specific data from specific API requests. Predefined forms fulfill the needs of the majority of their use cases, because the data structure, such as database models, doesn't change on the fly.

Client introduction

Trees4Travel works with travel brands around the world in the business and leisure sectors to provide carbon management technology. The company's systems help calculate and reduce emissions impacts. Trees4Travel makes it simple to positively impact the climate through direct integration with booking systems, API connectivity or simple file transfer. The company educates travelers and provides the necessary transition tools to move us from where we are today to our net zero goals in the future - making travel and events more ethical and sustainable.

The problem

But what if there was a need to process data, whose structure cannot be predicted and is too complex to keep it in a simple key-value list? Trees4Travel system encountered such an issue.

Assume a marketing system, with a list of contacts and email templates. The goal is to define the content of an email message and a list of recipients to receive it. The email templates use Handlebars - a templating language used to define how a template should parse input data into output message. Most frequently it consists of defining variables in a "moustache" format such as "Dear {{firstName}}". However, There are more advanced features such as conditional content, looping over arrays, formatting variables, and even custom user-defined parsers. As result, each email template will have its unique set of input parameters, often consisting of arrays and nested objects.

Now, back to our problem - We need to fill in the content of such email templates, store it in the system and have it sent (periodically) to selected contacts. How can we achieve this?

Introduction to JSONEditor

Instead of reinventing the wheel, we can get assistance from external packages and modules. In this example we will be taking a look at a javascript tool called JSONEditor. The premise is simple: The user provides a json schema which defines the structure of the form and the input/output data. This tool provides all the features we need to define our form: Text-based fields, dropdown lists, conditional fields, arrays, nested fields, support for rich text editors, file upload and so on. The diagram below demonstrates how it works.

Initializing JSONEditor inside your div element is really simple as shown below. Among various configuration fields we can choose a CSS theme from several existing ones, or we can use a barebones theme and manually style the look of the form.

Now, we simply need to provide a JSON schema for each email template to define each editable field, then use the dynamically generated form to fill in the data, store the result in JSON format (so that we can save it in the database to use or edit it later) and then use Handlebars to fill in the email template with our form values. How does this look in practice? Let’s look at an example from Trees4Travel marketing system.

First, our system loads a list of email templates directly from SendGrid, meaning that at any point in time we can edit these templates and have them immediately updated in the system.

Once we’ve made our choice, let’s look at the raw template. This is a simple example, but we can see several handlebars variables, such as {{firstName}} and {{buttonText}}.

Let’s write a schema to generate a form for editing this template. We can do it directly in the system, which saves the schema in the database.

This schema defines the form that will generate a JSON result used to fill in the contents of our marketing email. Each field has a name, a type and optionally a title and format.
Here, we are using 3 types of fields: A simple text field, an “xhtml” text field which will be displayed as a rich text editor in the form, and a boolean true/false field.


Finally, here is a working example of the form with a live preview of how the email will look like when parsed.

Our system goes a step further and detects some variables such as first name and replaces them with the name of the actual recipient. We can send this email to many contacts at once and each one will have their own name on it.

We also use a similar system for defining the contents of a personalized forest page. Let’s look at an example that generates a more interesting form which defines an array where each entry is a monthly reforestation update consisting of: a time period, a rich text entry, a photo and optionally a video.

First, the schema:

Here, we have a simple header text and an array type. The “items” field defines the format of each array entry. Nested inside are fields per each entry. The interesting one is certainly the photo field, as it uses a file upload control. In order for this to work we need to set up a couple things beforehand. First, you can see we are using an “upload_handler”. We need to define the way it actually uploads the file:

The code above defines our “defaultUploadHandler” which uses a FileReader to read the contents of the file in Base64 format and then uses a post request to send the file to our server:

How exactly a file is stored on the server is up to implementation, but we chose to store them in an Azure blob storage. The above request returns the url from our API pointing to the newly stored file which is then passed back to our form. This is important because it means we never actually store the whole file in the form’s JSON result - instead we only save the resulting url to where the file is stored on our blob storage.

First, we can see the file upload control which works exactly as we would expect - we pick a file, we upload it and that’s it - the resulting image URL is already stored in the form.

We can also see the array management in action. In the left column we see a list of entries. Using the buttons on the top and bottom we can add, delete, rename and reorder entries any way we want - it’s very flexible. In order to actually iterate over the resulting JSON array we need to use the #each keyword of handlebars.

This let’s us easily keep our reforestation page up to date

Workflow efficiency with JSONEditor: advantages and limitations

To summarize, let’s see how dynamic forms, specifically using JSONEditor can aid us in our work, but also when it is not advised to use them. There are obviously many advantages. Thanks to this tool and the way it was implemented in the system we can:

  • Set up our forms on the fly
  • Instantly generate the result of a form and use it to display parsed content
  • Add support for new message templates without having to rebuild or republish the whole project
  • Easily add or remove fields while maintaining compatibility with already existing JSON data generated by those forms

However, it is important to note that JSON results, while easy to store in the database and use within this editor, are rather difficult to work with outside of those use cases for manual modifications. And while this tool is quite flexible with what we can achieve, using it solely for the purpose of writing blog-post style updates where each one uses the same form layout would almost certainly be considered style over substance, especially when most CMS systems would prove much better for this task.

That having said, the above example of marketing emails is the perfect candidate for this tool as it relies heavily on frequent editing of the forms, the need to see results immediately, flexibility of the input/output data and the ability to store the results in JSON format in the database in order to set up cyclic marketing content.

About The Author
Mateusz Sacha

Comments

There are no comments yet. Be the first to leave one...

Write a comment:

Oops! Something went wrong while submitting the form.