Ternary Operators in Template Literals

Working on a small shortcode for Eleventy to generate <figure> markup, I realized I needed to test my optional parameters for values and alter my output if they didn’t exist.

Mozilla Dev Network’s documentation had some good examples, specifically nesting template literals and ternary operators.

In my situation, I created a shortcode to accept one required param (my filename) and two optional params (a caption, and a CSS class name):

module.exports = (image, caption, className) => {
  return `<figure${className ? ` class="${className}"` : ''}><img src="/img/${image}" />${caption ? `<figcaption>${caption}</figcaption>` : ''}</figure>`;

I’m using ternary operators to test for the presence of a className, as well as a caption. So I can invoke this shortcode in my Markdown files any of three ways:

  • Image only:
    {% figure "DSCF1433.jpg" %}
  • Image with caption:
    {% figure "DSCF1433.jpg" "This is a caption" %}
  • Image with caption and class name:
    {% figure "DSCF1433.jpg" "This is a caption" "cinemascope" %}
  • Image with class name, but no caption:
    {% figure "DSCF1433.jpg" "" "cinemascope" %}

As convenient and concise as this code is, it’s not particularly readable. I’m debating whether to pull the ternary operators into String variables above the main return statement, to be explicit about what I’m testing for, and what markup to wrap around a class name or a caption. Something like:

module.exports = (image, caption, className) => {
  const classMarkup = className ? ` class="${className}"` : '';
  const captionMarkup = caption ? `<figcaption>${caption}</figcaption>` : '';
  return `<figure${classMarkup}><img src="/img/${image}">${captionMarkup}</figure>`;

It’s three lines instead of one, but to my eye it’s easier to understand what I’m checking for, and how that gets output in the return statement. Perhaps I’m just heeding the call from my last post.

A gist of my shortcode is here.