paint-brush
Data-Driven Automation for Content Designby@rohankshah
233 reads

Data-Driven Automation for Content Design

by Rohan ShahAugust 29th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In the context of modern content design's critical importance, this article addresses the challenge of quickly and effectively swapping design assets for previewing various outcomes. It introduces a solution involving unique IDs for asset boxes, a database storing assets with IDs, and a dynamic population mechanism. By implementing this solution using Quant UX, designers can efficiently preview diverse design options, saving time, enhancing creativity, and aiding informed decision-making. The process involves CSV file upload, associating assets with widgets, and cycling through iterations for distinct previews.
featured image - Data-Driven Automation for Content Design
Rohan Shah HackerNoon profile picture


In the modern world, content design holds immense significance. Design can make or break a business. It influences potential customers and whether they like a business or not. A well-designed piece of content can grab attention and communicate the intended message effectively.


Modern-day design tools provide a treasure trove of useful features. However, there are still a few challenges that designers face. This article focuses on one such challenge. Finding the ideal image(s) or text that works best for a design involves some amount of experimentation. This involves swapping out the images or text captions manually to see what fits. It is time-consuming to do so and there is a clear need for a faster way.


Data Driven automation involves finding suitable images and text, not through manual experimentation, but instead by cycling through different combinations of assets without manual intervention.


Problem

Quick and easy swapping of assets in a design template to preview multiple design outcomes in order to speed up decision-making.



A design template is composed of multiple asset boxes. Image by the author.


Solution

The asset boxes on the design template can be tagged with unique IDs. We can then use these IDs to map out the relevant assets. A database is used to store all the relevant assets, alongside their corresponding IDs. The designer can then dynamically populate the template with the stored assets, allowing him to preview multiple design outcomes efficiently.



A database stores the suitable assets that are used to populate the template dynamically. Image by the author.


Implementation

We shall use Quant UX, an open-source Vue JS repository, by Klaus Schaefer to build the solution. It’s a prototyping tool that provides a way to build multiple templates in parallel. The terminology used by Quant UX for asset boxes is ‘widgets’ whereas text captions are called ‘labels’.


For this implementation, the focus will lie solely on image and text assets. A CSV file will be used to store these assets. Text will be stored directly, while images will be uploaded and their URLs stored in the file. The initial row of the file will contain the unique IDs used for asset mapping, while the following rows will contain the variations of data we are interested in previewing.



The CSV file populated with data. Image by the author.



The RenderFactory module in the src/core folder is responsible for rendering both image and text assets. As part of our implementation, we will write two new functions — updateLabelCustom and updateImageCustom into this module. These will be used to render our uploaded assets.


Both functions are passed to the widget (asset box) and the corresponding asset as input parameters.


updateLabelCustom (widget, value) {
  let node = this.getLabelNodeById(widget);
  if (node) {
   this.setInnerHTML(node, value)
  }
 }

 updateImageCustom (widget, value) {
  let imgCntr = this._imageNodes[widget];
  this._set_customBackgroundImage(imgCntr, value)
 }

// setInnerHTML and _set_customBackgroundImage are factory methods 
// provided by Quant



The next step involves the upload of our CSV file. We will add Upload, Add, and iteration buttons to the toolbar. The iteration buttons are not important at this stage, but will will be required later to cycle through our uploaded assets.


These buttons are added to the Toolbar.vue file located in the src/canvas/toolbar folder.



<a class="MatcToolbarItem MatcToolbarIconNoSmooth" data-dojo-attach-point="uploadButton">
    <span class="MatcToolbarLabel">Upload</span>
</a>

<a class="MatcToolbarItem MatcToolbarIconNoSmooth" data-dojo-attach-point="addButton">
    <span class="MatcToolbarLabel">Add</span>
</a>

<a class="MatcToolbarItem MatcToolbarIconNoSmooth" data-dojo-attach-point="iteratePreviousButton">
    <span class="MatcToolbarLabel">⪻</span>
</a>

<a class="MatcToolbarItem MatcToolbarIconNoSmooth" data-dojo-attach-point="iterateNextButton">
    <span class="MatcToolbarLabel">⪼</span>
</a>


The new buttons on the toolbar. Image by the author.



Clicking on the Upload button triggers a popup. Once the CSV file is uploaded through this popup, it triggers the onCustomFileUpload function, which converts the CSV into a JavaScript object.



onCustomFileUpload: function (e) {
   const file = e.target.files[0];
   const reader = new FileReader();
   reader.readAsText(file);
   reader.onload = (e) => {
    let csv = e.target.result;
    const lines = csv.split('\n')
    let result = []
    const headers = lines[0].split(',');
    headers[headers.length - 1] = headers[headers.length - 1].slice(0, -1);

    lines.map(l => {
     const obj = {}
     const line = l.split(',')
     line[line.length - 1] = line[line.length - 1].slice(0, -1);
     headers.map((h, i) => {
      obj[h] = line[i]
     })
     result.push(obj)
    })
    result = result.slice(1);
    addNewData(result);
   };
  },



We shall use the Quant UX functionality that allows for widget naming, and use these names as unique IDs.


Next, the add button is clicked. This runs the addCustom() method. This method iterates over all the widgets on the screen. If the widget has the same name as the name given on the CSV file, then the image or text asset gets associated with it.



let widgets = this.model.widgets;
let widgetNames = Object.keys(widgets);

for (let i = 0; i < widgetNames.length; i++) {    // Iterating through the image, and assigning asset based on
    if (widgets[widgetNames[i]].type == "Image") {    // whether the widget is an image or text
        let imgObj = {
            url: newCustomData[this.iterateCount][widgets[widgetNames[i]].name],
            name: widgetNames[i] + "image",
        };
        this.model.widgets[widgetNames[i]].style.backgroundImage = imgObj;
        this.canvas.customSetting(
            widgetNames[i],
            newCustomData[this.iterateCount][widgets[widgetNames[i]].name],
            true
        );
    } else {
        this.model.widgets[widgetNames[i]].props.label =
            newCustomData[this.iterateCount][widgets[widgetNames[i]].name];
        this.canvas.customSetting(
            widgetNames[i],
            newCustomData[this.iterateCount][widgets[widgetNames[i]].name],
            false
        );
    }
}



Once the assets have been associated with the widgets on the template, all that’s left to do is preview. The iteration buttons are used to cycle through the assets. With each iteration, the subsequent row from the CSV file is dynamically populated onto the assigned widget, allowing a different preview for each iteration.



Iterating through our assets. GIF by the author.



And that’s how it’s implemented!


This solution can benefit designers in three ways.


  1. Time Efficiency: This approach significantly reduces the time spent on swapping and experimenting with assets.


  2. Enhanced Creativity: The ability to easily iterate through various assets, encourages the exploration of more creative options. It allows the designer to consider a broader range of design possibilities.


  3. Informed Decision-making: Previewing different asset combinations, helps the designer select the most effective design elements.


The forked Quant UX repository the implementation is built upon can be found here. Exact details on the implementation can be found in the Readme.