Efficient way to handle nested variables in templates with Nunjucks or alternative approaches

Recently I've been exploring the world of gulp and nunjucks templating, specifically for creating emails.

One challenge I'm facing is figuring out how to call a module/partial and assign different values to its attributes each time it's processed.

While my initial thought was to use a for loop, the modules won't always be called sequentially within the template.

Within these modules, there are attributes assigned to variables that I'd like to resolve differently based on the section where the module is used.

For example, in an index file:

{% block content %}


<!-- logo start -->

{% include genericMod %}

<!-- logo end -->


<!-- some other section start -->

{% include someOtherMod %}

<!-- some other section end -->


<!-- hero start -->

{% include genericMod %}

<!-- hero end -->


{% endblock %}

In the genericMod itself:

<tr>

 <td class="full-width-image" align="{{align}}" ><img src="{{src}}" alt="{{alt}}"/></td>

</tr>

I would like to introduce a functionality where I can define a "modKey" variable within each attribute of the module. For example:

{{modKey.align}}

{{modKey.src}}

{{modKey.alt}}

Then, somehow assign that key to the module each time it's called:

<!-- logo start —>

{% include genericMod "modKey": "logo" %}

<!-- logo end -->

So that when using JSON data, the respective values would be rendered for each attribute variable:

"logo": {
    "alt": "some logo alt text",
    "href": "http://www.someurl.com",
    "align": "left"
  },
 "hero": {
    "alt": "some hero alt text",
    "href": "http://www.someotherurl.com",
    "align": "centre"
  }

This is just a concept, but I'm wondering if there's a way to actually achieve something similar?

Answer №1

After some trial and error, I discovered a surprisingly simple solution to my issue. Instead of assigning the value of the context variable to a string, I needed to assign it to an actual variable name when using 'set'.

Just to clarify, this is the correct way to do it:

{% set data = logo %} 
{% include oneIncludeFile %} 
{% set data = hero %} 
{% include otherIncludeFile %}

In these include files, you would reference something like {{ data.alt }} or {{ data.href }}.

Although using a macro might be a more efficient approach:

{% macro foo(data) %} 
<a href="{{ data.href }}"><img src="{{ data.src }}" alt="{{ data.alt }}" /></a> 
{% endmacro %}

You could then call it with {{ foo(logo) }} and {{ foo(hero) }} to pass in different sets of data.

If you want more details, check out: https://github.com/mozilla/nunjucks/issues/779

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript - The onkeypress event continuously adds text to the end

In my Angular application, I have implemented an input field with the onkeypress event handler to automatically remove any commas entered by the user: <input name="option" ng-model="main.optionToAdd" onkeypress="this.value = this.value.replace(/,/g ...

Launching an Angular application from the local server

I have successfully deployed an Angular frontend on a server. It is functioning well, with three scripts: /runtime.0fad6a04e0afb2fa.js /polyfills.24f3ec2108a8e0ab.js /main.a9b28b9970fe807a.js My goal is to start this application in Firefox without ...

The Google Visualization chart fails to display properly once CSS is applied

Struggling with a graph display issue here. It's quite perplexing as it works fine on older laptops and Safari, but not on Chrome or older versions of Firefox. Works like a charm on my old laptop and Safari, but fails on Chrome and Firefox (haven&apo ...

Hey there, could you please set up the DateTimePicker in my expo project using React Native?

Hey everyone, I'm currently trying to set up DateTimePicker but encountered an error. Here's the issue: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: undefined@undefined npm ERR! Fou ...

Tips for displaying my libraries' function arguments while hovering in VSCode

As the creator of a JavaScript library, I am intrigued by how some libraries display function parameters and definitions when hovering over them in VSCode. Despite my efforts to add jsdoc style comments around the class definitions, I have not been able to ...

Creating a tool that produces numerous dynamic identifiers following a specific format

I am working on a function to create multiple dynamic IDs with a specific pattern. How can I achieve this? followup: Vue.js: How to generate multiple dynamic IDs with a defined pattern Details: I am developing an interactive school test application. Whe ...

When utilizing the JavaScript createElement() method to create elements on keydown, it will not be compatible with jQuery's draggable() method

I'm currently developing a drag and drop feature for a project, allowing users to add items to a work area and then position them by dragging. I'm facing an issue where I want to create multiple instances of the same element using a key code, but ...

When a Vue.js datepicker is set as required, it can be submitted even if

When using the vuejs-datepicker, setting the html required attribute on input fields may not work as expected. This can lead to the form being submitted without an input value. <form> <datepicker placeholder="Select Date" required></datep ...

I am experiencing difficulties with my Angular 8 NPM package as it is unable to locate its own

I am encountering an issue where my assets are successfully copied over to my scoped npm package, but they are not available after the application is served. Currently, the images in my application are searching for a path like this: https://localhost:420 ...

Python responding to an Ajax request using jQuery

Currently, I am experimenting with integrating a pre-built inline editor from the following source: https://github.com/wbotelhos/inplace Regrettably, the available support documentation is lacking and my expertise in Javascript, jQuery, or Ajax is limited ...

Vitejs is currently loading the entire bundle size instead of just the specific selected files

While working with Vue 3 and Vite, I came across an issue that seems quite strange. The Oh Vue Icons library is loading a massive 108 MB of bundle size, which significantly slows down the loading time even in ViteJS. Here's how my setup looks like: im ...

Secure Access with Skype Bot Verification

Recently, I managed to set up a NodeJS bot to synchronize messages between Discord and Skype chats. Although I am relatively new to Javascript and completely unfamiliar with NodeJS, the existence of a framework called Spype has been quite beneficial. The i ...

What is the purpose of Jenkins creating a temporary volume alongside the workspace?

I am currently utilizing the gulp command to execute my JavaScript application on a docker container generated from an image constructed through a Dockerfile. I consider myself an intermediate user when it comes to Jenkins. Dockerfile FROM node:10.11.0-a ...

Combine less files in webpack to generate a single minified CSS output file

Can webpack be used to combine multiple less files into one minified CSS file? I'm having trouble setting different output paths for my files. How can I make my CSS file output to './assets/stylesheets/bundle/' instead of './assets/ja ...

The State Hook error "state variable is not defined" arises due to an issue with the state declaration in

function Header() { const [keys, setKeys] = useState([]); //custom addition const first = (e) => { var result = new Map() axios.post('http://localhost:8000/' + query) .then(function(response){ var content ...

What is the best way to incorporate a function within a $.click (jquery) event that utilizes an id directly from the clicked element?

It seems that my title may not be very clear, but I have a jQuery code snippet that is causing some issues. The problem stems from the fact that when I click on an image with the class 'slideimg', I expect a function named slideDo to be executed, ...

Fixing the Responsive Menu Issues

In order to achieve the desired effect of making the text from menu and logo disappear when minimizing the menu, you can use the following approach: Create a function called `smallNav()` to handle the resizing of the sidebar container: function sm ...

Create a collection of functions within an array that each return promises

I have created 4 different functions that return promises. By running the "hello" function and passing each subsequent function into the next .then, you can generate a single long string output. var hello = function(str){ return Promise.resolve(str + "h ...

The JSON array data is coming back as undefined

Currently facing an issue with the data sa var data = '[{"idcoupons_tbl":"1","discount_percent":"10"}]'; Every time I attempt to parse and retrieve a discount_percent, ie var result= jQuery.parseJSON(data); alert(result["discount_percent"]); ...

Struggling to determine whether an array contains data or is void in ReactJS?

In the state, I have an array and I set the default value of my state to an empty array []. After loading an API request, I need to display a loader until the data is ready. So, I am using a condition like this: (if the array length === 0, the loader wil ...