From 3b390858ff8b92f45f3c4adedc7dfe30df07e8ea Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <p.jentsch@uni-bielefeld.de>
Date: Tue, 8 Aug 2023 10:48:36 +0200
Subject: [PATCH] Use macros for html generation instead of variables

---
 .../corpora/_analysis/concordance.html.j2     | 277 +++++++++---------
 .../corpora/_analysis/reader.html.j2          | 135 ++++-----
 .../corpora/_analysis/template.html.j2        |  18 +-
 app/templates/corpora/analysis.html.j2        |  36 ++-
 4 files changed, 225 insertions(+), 241 deletions(-)

diff --git a/app/templates/corpora/_analysis/concordance.html.j2 b/app/templates/corpora/_analysis/concordance.html.j2
index 7fe1c6a6..a26c1a9a 100644
--- a/app/templates/corpora/_analysis/concordance.html.j2
+++ b/app/templates/corpora/_analysis/concordance.html.j2
@@ -2,168 +2,156 @@
 {% import 'corpora/_analysis/query_builder/_query_builder.html.j2' as query_builder with context %}
 
 
+{% set icon = 'list_alt' %}
 {% set name = 'Concordance' %}
+{% set description = 'Query your corpus with the CQP query language utilizing a KWIC view.' %}
 
-{% set description %}
-Query your corpus with the CQP query language utilizing a KWIC view.
-{% endset %}
-
-{% set id_prefix = name.lower().replace(' ', '-') + '-extension' %}
-
-{% set tab_content %}
-<i class="material-icons left">list_alt</i>{{ name }}</a>
-{% endset %}
 
-{% set container_content %}
-<div class="row">
-  <div class="col s12">
-    <div class="card">
-      <div class="card-content">
-        <div class="row">
-          <div class="col s1">
-            <span class="card-title">Query</span>
+{% macro container_element(id_prefix) %}
+<div class="card">
+  <div class="card-content">
+    <div class="row">
+      <div class="col s1">
+        <span class="card-title">Query</span>
+      </div>
+      <div class="col s2">
+        <div class="switch" style="margin-top:8px; margin-left:0px;">
+          <label>
+            <input type="checkbox" id="{{ id_prefix }}-expert-mode-switch">
+            <span class="lever"></span>
+            expert mode
+          </label>
+        </div>
+      </div>
+    </div>
+    <div id="{{ id_prefix }}-expert-mode-display" class="hide">
+      {{ expert_mode.card_content(id_prefix) }}
+    </div>
+    <div id="{{ id_prefix }}-query-builder-display">
+      {# {{ query_builder.card_content(id_prefix) }} #}
+      <div class="row">
+        <form id="{{ id_prefix }}-form">
+          <div class="input-field col s12 m9">
+            <i class="material-icons prefix">search</i>
+            {# <input class="validate corpus-analysis-action" id="{{ id_prefix }}-form-query" name="query" type="text" required pattern=".*\S+.*" placeholder="Type in your query and or use the Query Builder functions below"></input> #}
+            <div class="chips input-field" style="margin-top:0px;"></div>
+            {# <label for="{{ id_prefix }}-form-query">Query</label> #}
+            <span class="error-color-text helper-text hide" id="{{ id_prefix }}-error"></span>
+            <a class="modal-trigger" data-manual-modal-chapter="manual-modal-cqp-query-language" href="#manual-modal" style="margin-left: 40px;"><i class="material-icons" style="font-size: inherit;">help</i> Corpus Query Language tutorial</a>
+            <span> | </span>
+            <a class="modal-trigger" data-manual-modal-chapter="manual-modal-tagsets" href="#manual-modal"><i class="material-icons" style="font-size: inherit;">info</i> Tagsets</a>
           </div>
-          <div class="col s2">
-            <div class="switch" style="margin-top:8px; margin-left:0px;">
-              <label>
-                <input type="checkbox" id="{{ id_prefix }}-expert-mode-switch">
-                <span class="lever"></span>
-                expert mode
-              </label>
-            </div>
+          <div class="input-field col s12 m3">
+            <i class="material-icons prefix">arrow_forward</i>
+            <input class="validate corpus-analysis-action" id="{{ id_prefix }}-form-subcorpus-name" name="subcorpus-name" type="text" required pattern="^[A-Z][a-z0-9\-]*" value="Last"></input>
+            <label for="{{ id_prefix }}-form-subcorpus-name">Subcorpus name</label>
           </div>
-        </div>
-        <div id="{{ id_prefix }}-expert-mode-display" class="hide">
-          {{ expert_mode.card_content(id_prefix) }}
-        </div>
-        <div id="{{ id_prefix }}-query-builder-display">
-          {# {{ query_builder.card_content(id_prefix) }} #}
-          <div class="row">
-            <form id="{{ id_prefix }}-form">
-              <div class="input-field col s12 m9">
-                <i class="material-icons prefix">search</i>
-                {# <input class="validate corpus-analysis-action" id="{{ id_prefix }}-form-query" name="query" type="text" required pattern=".*\S+.*" placeholder="Type in your query and or use the Query Builder functions below"></input> #}
-                <div class="chips input-field" style="margin-top:0px;"></div>
-                {# <label for="{{ id_prefix }}-form-query">Query</label> #}
-                <span class="error-color-text helper-text hide" id="{{ id_prefix }}-error"></span>
-                <a class="modal-trigger" data-manual-modal-chapter="manual-modal-cqp-query-language" href="#manual-modal" style="margin-left: 40px;"><i class="material-icons" style="font-size: inherit;">help</i> Corpus Query Language tutorial</a>
-                <span> | </span>
-                <a class="modal-trigger" data-manual-modal-chapter="manual-modal-tagsets" href="#manual-modal"><i class="material-icons" style="font-size: inherit;">info</i> Tagsets</a>
-              </div>
-              <div class="input-field col s12 m3">
-                <i class="material-icons prefix">arrow_forward</i>
-                <input class="validate corpus-analysis-action" id="{{ id_prefix }}-form-subcorpus-name" name="subcorpus-name" type="text" required pattern="^[A-Z][a-z0-9\-]*" value="Last"></input>
-                <label for="{{ id_prefix }}-form-subcorpus-name">Subcorpus name</label>
-              </div>
-              <div class="col s12 hide" style="margin-left: 44px;">
-                <p><i> Preview:</i></p>
-                <p id="query-preview"></p>
-                <br>
-              </div>
-              <div class="col s12" style="margin-left: 44px;">
-                <h6>Use the following options to build your query.</h6>
-                <p></p>
-                <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#positional-attr-modal" data-position="bottom" data-tooltip="Search for any token, for example a word, a lemma or a part-of-speech tag">Add new token to your query</a>
-                <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#structural-attr-modal" data-position="bottom" data-tooltip="Structure your query with structural attributes, for example sentences, entities or annotate the text">Add structural attributes to your query</a>
-              </div>
-              <div class="col s12 right-align">
-                <p class="hide-on-small-only">&nbsp;</p>
-                <button class="btn waves-effect waves-light corpus-analysis-action" id="{{ id_prefix }}-form-submit" type="submit" name="submit">
-                  Send 
-                  <i class="material-icons right">send</i>
-                </button>
-              </div>
-            </form>
+          <div class="col s12 hide" style="margin-left: 44px;">
+            <p><i> Preview:</i></p>
+            <p id="query-preview"></p>
+            <br>
           </div>
-        </div>
+          <div class="col s12" style="margin-left: 44px;">
+            <h6>Use the following options to build your query.</h6>
+            <p></p>
+            <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#positional-attr-modal" data-position="bottom" data-tooltip="Search for any token, for example a word, a lemma or a part-of-speech tag">Add new token to your query</a>
+            <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#structural-attr-modal" data-position="bottom" data-tooltip="Structure your query with structural attributes, for example sentences, entities or annotate the text">Add structural attributes to your query</a>
+          </div>
+          <div class="col s12 right-align">
+            <p class="hide-on-small-only">&nbsp;</p>
+            <button class="btn waves-effect waves-light corpus-analysis-action" id="{{ id_prefix }}-form-submit" type="submit" name="submit">
+              Send 
+              <i class="material-icons right">send</i>
+            </button>
+          </div>
+        </form>
       </div>
     </div>
   </div>
+</div>
 
-  <div class="col s12">
-    <div id="{{ id_prefix }}-subcorpus-list"></div>
+<div id="{{ id_prefix }}-subcorpus-list"></div>
 
-    <div class="card">
-      <div class="card-content">
-        <span class="card-title">Results</span>
-        <p></p>
-        <br>
-        <div class="progress hide" id="{{ id_prefix }}-progress">
-          <div class="indeterminate"></div>
-        </div>
-        <form id="{{ id_prefix }}-ui-form">
+<div class="card">
+  <div class="card-content">
+    <span class="card-title">Results</span>
+    <p></p>
+    <br>
+    <div class="progress hide" id="{{ id_prefix }}-progress">
+      <div class="indeterminate"></div>
+    </div>
+    <form id="{{ id_prefix }}-ui-form">
+      <div class="row">
+        <div class="col s12 m9 l9">
           <div class="row">
-            <div class="col s12 m9 l9">
-              <div class="row">
-                <div class="input-field col s4 l3">
-                  <i class="material-icons prefix">short_text</i>
-                  <select class="corpus-analysis-action" name="context">
-                    <option value="10" selected>10</option>
-                    <option value="15">15</option>
-                    <option value="20">20</option>
-                    <option value="25">25</option>
-                    <option value="30">30</option>
-                  </select>
-                  <label>Context</label>
-                </div>
-                <div class="input-field col s4 l3">
-                  <i class="material-icons prefix">format_list_numbered</i>
-                  <select class="corpus-analysis-action" name="per-page">
-                    <option value="10" selected>10</option>
-                    <option value="15">15</option>
-                    <option value="20">20</option>
-                    <option value="25">25</option>
-                  </select>
-                  <label>Matches per page</label>
-                </div>
-                <div class="input-field col s4 l3">
-                  <i class="material-icons prefix">format_shapes</i>
-                  <select name="text-style">
-                    <option value="0">Plain text</option>
-                    <option value="1" selected>Highlight entities</option>
-                    <option value="2">Token text</option>
-                  </select>
-                  <label>Text style</label>
-                </div>
-                <div class="input-field col s4 l3">
-                  <i class="material-icons prefix">format_quote</i>
-                  <select name="token-representation">
-                    <option value="lemma">lemma</option>
-                    <option value="pos">pos</option>
-                    <option value="simple_pos">simple_pos</option>
-                    <option value="word" selected>word</option>
-                  </select>
-                  <label>Token representation</label>
-                </div>
-              </div>
+            <div class="input-field col s4 l3">
+              <i class="material-icons prefix">short_text</i>
+              <select class="corpus-analysis-action" name="context">
+                <option value="10" selected>10</option>
+                <option value="15">15</option>
+                <option value="20">20</option>
+                <option value="25">25</option>
+                <option value="30">30</option>
+              </select>
+              <label>Context</label>
+            </div>
+            <div class="input-field col s4 l3">
+              <i class="material-icons prefix">format_list_numbered</i>
+              <select class="corpus-analysis-action" name="per-page">
+                <option value="10" selected>10</option>
+                <option value="15">15</option>
+                <option value="20">20</option>
+                <option value="25">25</option>
+              </select>
+              <label>Matches per page</label>
+            </div>
+            <div class="input-field col s4 l3">
+              <i class="material-icons prefix">format_shapes</i>
+              <select name="text-style">
+                <option value="0">Plain text</option>
+                <option value="1" selected>Highlight entities</option>
+                <option value="2">Token text</option>
+              </select>
+              <label>Text style</label>
+            </div>
+            <div class="input-field col s4 l3">
+              <i class="material-icons prefix">format_quote</i>
+              <select name="token-representation">
+                <option value="lemma">lemma</option>
+                <option value="pos">pos</option>
+                <option value="simple_pos">simple_pos</option>
+                <option value="word" selected>word</option>
+              </select>
+              <label>Token representation</label>
             </div>
           </div>
-        </form>
-        <div class="row">
-          <div class="col s9"><p class="hide" id="{{ id_prefix }}-subcorpus-info"></p></div>
-          <div class="col s3 right-align" id="{{ id_prefix }}-subcorpus-actions"></div>
         </div>
-        <table class="highlight">
-          <thead>
-            <tr>
-              <th style="width: 2%;"></th>
-              <th style="width: 8%;">Source</th>
-              <th class="right-align" style="width: 22.5%;">Left context</th>
-              <th class="center-align" style="width: 40%;">KWIC</th>
-              <th class="left-align" style="width: 22.5%;">Right Context</th>
-              <th class="left-align" style="width: 5%;"></th>
-            </tr>
-          </thead>
-          <tbody id="{{ id_prefix }}-subcorpus-items"></tbody>
-        </table>
-        <ul class="pagination hide" id="{{ id_prefix }}-subcorpus-pagination"></ul>
       </div>
+    </form>
+    <div class="row">
+      <div class="col s9"><p class="hide" id="{{ id_prefix }}-subcorpus-info"></p></div>
+      <div class="col s3 right-align" id="{{ id_prefix }}-subcorpus-actions"></div>
     </div>
+    <table class="highlight">
+      <thead>
+        <tr>
+          <th style="width: 2%;"></th>
+          <th style="width: 8%;">Source</th>
+          <th class="right-align" style="width: 22.5%;">Left context</th>
+          <th class="center-align" style="width: 40%;">KWIC</th>
+          <th class="left-align" style="width: 22.5%;">Right Context</th>
+          <th class="left-align" style="width: 5%;"></th>
+        </tr>
+      </thead>
+      <tbody id="{{ id_prefix }}-subcorpus-items"></tbody>
+    </table>
+    <ul class="pagination hide" id="{{ id_prefix }}-subcorpus-pagination"></ul>
   </div>
 </div>
-{% endset %}
+{% endmacro %}
 
-{% set modals %}
+{# The extension modals #}
+{% macro modals(id_prefix) %}
 <div id="structural-attr-modal" class="modal">
   <div class="modal-content">
     <h6>Which structural attribute do you want to add to your query?<a class="modal-trigger" data-manual-modal-chapter="manual-modal-query-builder" href="#manual-modal"><i class="material-icons left" id="add-structural-attribute-tutorial-info-icon">help_outline</i></a></h6>
@@ -177,9 +165,10 @@ Query your corpus with the CQP query language utilizing a KWIC view.
     </div>
   </div>
 </div>
-{% endset %}
+{% endmacro %}
 
-{% set scripts %}
+{# The extension scripts #}
+{% macro scripts(id_prefix) %}
 <script>
   const corpusAnalysisConcordance = new CorpusAnalysisConcordance(corpusAnalysisApp);
   {# const concordanceQueryBuilder = new ConcordanceQueryBuilder(); #}
diff --git a/app/templates/corpora/_analysis/reader.html.j2 b/app/templates/corpora/_analysis/reader.html.j2
index 683435f9..276c76c0 100644
--- a/app/templates/corpora/_analysis/reader.html.j2
+++ b/app/templates/corpora/_analysis/reader.html.j2
@@ -1,89 +1,84 @@
-{% set name = 'Reader' %}
+{# The extension icon #}
+{% set icon = 'chrome_reader_mode' %}
 
-{% set description %}
-Inspect your corpus in detail with a full text view, including annotations.
-{% endset %}
+{# The extension name #}
+{% set name = 'Reader' %}
 
-{% set id_prefix = name.lower().replace(' ', '-') + '-extension' %}
+{# The extension description #}
+{% set description = 'Inspect your corpus in detail with a full text view, including annotations.' %}
 
-{% set tab_content %}
-<i class="material-icons left">chrome_reader_mode</i>{{ name }}</a>
-{% endset %}
 
-{% set container_content %}
-<div class="row">
-  <div class="col s12">
-    <div class="card">
-      <div class="card-content">
-        <form id="reader-extension-form">
+{# The extension container content #}
+{% macro container_content(id_prefix) %}
+<div class="card">
+  <div class="card-content">
+    <form id="{{ id_prefix }}-form">
+      <div class="row">
+        <div class="col s12 m9 l10">
           <div class="row">
-            <div class="col s12 m9 l10">
-              <div class="row">
-                <div class="input-field col s4 m3">
-                  <i class="material-icons prefix">format_list_numbered</i>
-                  <select class="corpus-analysis-action" name="per-page">
-                    <option value="500" selected>500</option>
-                    <option value="1000">1000</option>
-                    <option value="1500">1500</option>
-                  </select>
-                  <label>Tokens per page</label>
-                </div>
-                <div class="input-field col s4 m3">
-                  <i class="material-icons prefix">format_shapes</i>
-                  <select name="text-style">
-                    <option value="0">Plain text</option>
-                    <option value="1" selected>Highlight entities</option>
-                    <option value="2">Token text</option>
-                  </select>
-                  <label>Text style</label>
-                </div>
-                <div class="input-field col s4 m3">
-                  <i class="material-icons prefix">format_quote</i>
-                  <select name="token-representation">
-                    <option value="lemma">lemma</option>
-                    <option value="pos">pos</option>
-                    <option value="simple_pos">simple_pos</option>
-                    <option value="word" selected>word</option>
-                  </select>
-                  <label>Token representation</label>
-                </div>
-                <div class="col s12">
-                  <span class="error-color-text helper-text hide" id="reader-extension-error"></span>
-                </div>
-              </div>
+            <div class="input-field col s4 m3">
+              <i class="material-icons prefix">format_list_numbered</i>
+              <select class="corpus-analysis-action" name="per-page">
+                <option value="500" selected>500</option>
+                <option value="1000">1000</option>
+                <option value="1500">1500</option>
+              </select>
+              <label>Tokens per page</label>
+            </div>
+            <div class="input-field col s4 m3">
+              <i class="material-icons prefix">format_shapes</i>
+              <select name="text-style">
+                <option value="0">Plain text</option>
+                <option value="1" selected>Highlight entities</option>
+                <option value="2">Token text</option>
+              </select>
+              <label>Text style</label>
             </div>
-            <div class="col s12 m3 l2 right-align">
-              <p class="hide-on-small-only">&nbsp;</p>
-              <button class="btn hide waves-effect waves-light corpus-analysis-action" id="reader-extension-form-submit" type="submit" name="submit">Send <i class="material-icons right">send</i></button>
+            <div class="input-field col s4 m3">
+              <i class="material-icons prefix">format_quote</i>
+              <select name="token-representation">
+                <option value="lemma">lemma</option>
+                <option value="pos">pos</option>
+                <option value="simple_pos">simple_pos</option>
+                <option value="word" selected>word</option>
+              </select>
+              <label>Token representation</label>
+            </div>
+            <div class="col s12">
+              <span class="error-color-text helper-text hide" id="{{ id_prefix }}-error"></span>
             </div>
           </div>
-        </form>
+        </div>
+        <div class="col s12 m3 l2 right-align">
+          <p class="hide-on-small-only">&nbsp;</p>
+          <button class="btn hide waves-effect waves-light corpus-analysis-action" id="{{ id_prefix }}-form-submit" type="submit" name="submit">Send <i class="material-icons right">send</i></button>
+        </div>
       </div>
-    </div>
+    </form>
   </div>
+</div>
 
-  <div class="col s12">
-    <div class="card">
-      <div class="card-content">
-        <div class="progress hide" id="reader-extension-progress">
-          <div class="indeterminate"></div>
-        </div>
-        <table>
-          <tbody>
-            <tr><td id="reader-extension-corpus"></td></tr>
-          </tbody>
-        </table>
-        <ul class="pagination hide" id="reader-extension-corpus-pagination"></ul>
-      </div>
+<div class="card">
+  <div class="card-content">
+    <div class="progress hide" id="{{ id_prefix }}-progress">
+      <div class="indeterminate"></div>
     </div>
+    <table>
+      <tbody>
+        <tr><td id="{{ id_prefix }}-corpus"></td></tr>
+      </tbody>
+    </table>
+    <ul class="pagination hide" id="{{ id_prefix }}-corpus-pagination"></ul>
   </div>
 </div>
-{% endset %}
+{% endmacro %}
 
-{% set modals = '' %}
+{# The extension modals #}
+{% macro modals(id_prefix) %}{% endmacro %}
 
-{% set scripts %}
+{# The extension scripts #}
+{% macro scripts(id_prefix) %}
 <script>
   const corpusAnalysisReader = new CorpusAnalysisReader(corpusAnalysisApp);
 </script>
-{% endset %}
+{% endmacro %}
diff --git a/app/templates/corpora/_analysis/template.html.j2 b/app/templates/corpora/_analysis/template.html.j2
index 00565b16..b55ca772 100644
--- a/app/templates/corpora/_analysis/template.html.j2
+++ b/app/templates/corpora/_analysis/template.html.j2
@@ -1,3 +1,5 @@
+{# The extension icon #}
+{% set icon = '' %}
 
 {# The extension name #}
 {% set name = '' %}
@@ -5,22 +7,12 @@
 {# The extension description #}
 {% set description = '' %}
 
-{# 
-  The extension id prefix, used for related HTML elements with an id.
-  The prefix is used to avoid id conflicts with other extensions.
-  Reserved ids (do not use):
-    - <id_prefix>-extension-container
-#}
-{% set id_prefix = name.lower().replace(' ', '-') + '-extension' %}
-
-{# The extension tab content #}
-{% set tab_content = name %}
 
 {# The extension container content #}
-{% set container_content = '' %}
+{% macro container_content(id_prefix) %}{% endmacro %}
 
 {# The extension modals #}
-{% set modals = '' %}
+{% macro modals(id_prefix) %}{% endmacro %}
 
 {# The extension scripts #}
-{% set scripts = '' %}
+{% macro scripts(id_prefix) %}{% endmacro %}
diff --git a/app/templates/corpora/analysis.html.j2 b/app/templates/corpora/analysis.html.j2
index 046fa161..4c43552a 100644
--- a/app/templates/corpora/analysis.html.j2
+++ b/app/templates/corpora/analysis.html.j2
@@ -4,16 +4,25 @@
 {% import 'corpora/_analysis/reader.html.j2' as reader_extension %}
 {% import 'corpora/_analysis/static_visualization.html.j2' as static_visualization_extension %}
 
-{% set extensions = [concordance_extension, reader_extension, static_visualization_extension] %}
-{% block main_attribs %} class="service-scheme" data-service="corpus-analysis" id="corpus-analysis-app-container"{% endblock main_attribs %}
+{% set extensions =
+  {
+    'concordance-extension': concordance_extension,
+    'reader-extension': reader_extension,
+    'static-visualizations-extension': static_visualization_extension
+  }
+%}
+
 
+{% block main_attribs %} class="service-scheme" data-service="corpus-analysis" id="corpus-analysis-app-container"{% endblock main_attribs %}
 
 
 {% block page_content %}
 <ul class="row tabs no-autoinit" id="corpus-analysis-app-extension-tabs">
   <li class="tab col s3"><a class="active" href="#corpus-analysis-app-home-container"><i class="nopaque-icons service-icons left" data-service="corpus-analysis"></i>Corpus analysis</a></li>
-  {% for extension in extensions if extension.name != 'Static Visualization (beta)' %}
-  <li class="tab col s3"><a href="#{{ extension.id_prefix }}-container">{{ extension.tab_content }}</a></li>
+  {% for id, extension in extensions.items() if extension.name != 'Static Visualization (beta)' %}
+  <li class="tab col s3">
+    <a href="#{{ id }}-container"><i class="material-icons left">extension.icon</i>{{ extension.name }}</a>
+  </li>
   {% endfor %}
 </ul>
 
@@ -21,9 +30,9 @@
   <h1>{{ title }}</h1>
 
   <div class="row" id="corpus-analysis-app-extension-cards">
-    {% for extension in extensions if extension.name != 'Static Visualization (beta)' %}
+    {% for id, extension in extensions.items() if extension.name != 'Static Visualization (beta)' %}
     <div class="col s3">
-      <div class="card extension-selector hoverable" data-target="{{ extension.id_prefix }}-container">
+      <div class="card extension-selector hoverable" data-target="{{ id }}-container">
         <div class="card-content">
           <span class="card-title">{{ extension.name }}</span>
           <p>{{ extension.description }}</p>
@@ -37,9 +46,9 @@
 </div>
 
 
-{% for extension in extensions if extension.name != 'Static Visualization (beta)' %}
-<div id="{{ extension.id_prefix }}-container">
-  {{ extension.container_content }}
+{% for id, extension in extensions.items() if extension.name != 'Static Visualization (beta)' %}
+<div id="{{ id }}-container">
+  {{ extension.container_content(id) }}
 </div>
 {% endfor %}
 {% endblock page_content %}
@@ -61,10 +70,9 @@
   </div>
 </div>
 
-{% for extension in extensions %}
-{{ extension.modals }}
+{% for id, extension in extensions.items() %}
+{{ extension.modals(id) }}
 {% endfor %}
-
 {% endblock modals %}
 
 {% block scripts %}
@@ -73,8 +81,8 @@
   const corpusAnalysisApp = new CorpusAnalysisApp({{ corpus.hashid|tojson }});
 </script>
 
-{% for extension in extensions %}
-{{ extension.scripts }}
+{% for id, extension in extensions.items() %}
+{{ extension.scripts(id) }}
 {% endfor %}
 
 <script>
-- 
GitLab