Drupal modal dialogs can have various properties set through the data-dialog-options attribute. In fact, this attribute is implemented in the JQuery dialog widget API. One can write for instance

<a href="https://my-url" 
   class="edit-button use-ajax" 

This will open mi-url in an off-canvas dialog with a width of 400px.

The data-dialog-options attribute requires a json array. In the example above we use &quot; to write the quotes of the json array. The "normal" surrounding quotes open and close the html attribute.

The title of the modal can also be set by adding something like &quot;title&quot;:&quot;MyTitle&quot;. But in a twig template this doesn’t work if the title string is rendered through a variable. So one can’t write:

data-dialog-options="{&quot;title&quot;:&quot;" {{myVariable}} "&quot;}">Edit</a>

The first closing quotes, before {{myVariable}}, effectively tell twig to close the attribute. Twig then tries to make sense of what comes later on as different attributes, which results in a mess.

The solution for me was to define all the options separately, as a twig array:

{% set dataDialogOpts = { width: 400, title: maintitle } %}

In the above maintitle is a variable which I set earlier on in the template. I can then pass the variable as attribute to data-dialog-options, but it needs encoding and escaping first. Some of my titles had non-ascii characters which probably made the problem slightly more challenging than plain ascii. The solution was to json encode the twig array before escaping it, and for the latter to use the "html attr" strategy:

data-dialog-options = {{ dataDialogOpts|json_encode()|e('html_attr') }}

The complete link is:

  href="{{ url }}"
  data-dialog-options= {{ dataDialogOpts|json_encode()|e('html_attr') }}
  class="use-ajax">{{ label }}</a>

Clicking on the label opens an off-canvas modal with its title set to my maintitle variable.