jekyll-theme-chirpy 4.3.4 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -5
  3. data/_config.yml +9 -5
  4. data/_data/locales/en.yml +2 -1
  5. data/_data/locales/id-ID.yml +2 -1
  6. data/_data/locales/ko-KR.yml +91 -0
  7. data/_data/locales/zh-CN.yml +2 -1
  8. data/_includes/{disqus.html → comments/disqus.html} +4 -4
  9. data/_includes/comments/utterances.html +51 -0
  10. data/_includes/comments.html +5 -0
  11. data/_includes/footer.html +1 -1
  12. data/_includes/js-selector.html +1 -1
  13. data/_includes/mermaid.html +28 -0
  14. data/_includes/mode-toggle.html +48 -65
  15. data/_includes/read-time.html +3 -3
  16. data/_includes/refactor-content.html +109 -35
  17. data/_includes/related-posts.html +1 -1
  18. data/_includes/search-results.html +0 -8
  19. data/_includes/sidebar.html +10 -11
  20. data/_includes/timeago.html +11 -12
  21. data/_includes/toc.html +16 -0
  22. data/_includes/topbar.html +1 -1
  23. data/_includes/trending-tags.html +14 -0
  24. data/_includes/update-list.html +16 -0
  25. data/_layouts/default.html +6 -2
  26. data/_layouts/home.html +12 -9
  27. data/_layouts/page.html +45 -22
  28. data/_layouts/post.html +128 -127
  29. data/_sass/addon/commons.scss +154 -175
  30. data/_sass/addon/module.scss +48 -28
  31. data/_sass/addon/syntax.scss +55 -44
  32. data/_sass/addon/variables.scss +1 -1
  33. data/_sass/colors/dark-syntax.scss +3 -4
  34. data/_sass/colors/dark-typography.scss +11 -8
  35. data/_sass/colors/light-syntax.scss +3 -3
  36. data/_sass/colors/light-typography.scss +4 -5
  37. data/_sass/jekyll-theme-chirpy.scss +1 -1
  38. data/_sass/layout/home.scss +6 -2
  39. data/_sass/layout/post.scss +52 -46
  40. data/assets/js/dist/categories.min.js +2 -2
  41. data/assets/js/dist/commons.min.js +2 -2
  42. data/assets/js/dist/home.min.js +2 -2
  43. data/assets/js/dist/page.min.js +2 -2
  44. data/assets/js/dist/post.min.js +2 -2
  45. data/assets/js/dist/pvreport.min.js +2 -2
  46. metadata +7 -4
  47. data/_includes/panel.html +0 -59
@@ -38,63 +38,100 @@
38
38
  %}
39
39
  {% endif %}
40
40
 
41
-
42
41
  <!-- images -->
43
42
 
44
- {% if _content contains '<img src="' %}
45
-
46
- <!-- add CDN prefix if it exists -->
47
-
48
- {% if site.img_cdn != '' %}
49
- {% assign img_path_replacement = '<img src="' | append: site.img_cdn | append: '/' %}
50
- {% else %}
51
- {% assign img_path_replacement = '<img src="' | append: site.baseurl | append: '/' %}
52
- {% endif %}
53
-
54
- {% assign _content = _content | replace: '<img src="/', img_path_replacement %}
55
-
56
- <!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
57
-
58
- {% assign _content = _content | replace: '<img src="', '<img data-proofer-ignore data-src="' %}
59
-
60
- <!-- add image placehoder to prevent layout reflow -->
43
+ {% assign IMG_TAG = '<img ' %}
61
44
 
45
+ {% if _content contains IMG_TAG %}
62
46
  {% assign _img_content = nil %}
47
+ {% assign _img_snippets = _content | split: IMG_TAG %}
63
48
 
64
- {% assign _images = _content | split: '<img ' %}
65
-
66
- {% for _img in _images %}
49
+ {% for _img_snippet in _img_snippets %}
67
50
  {% if forloop.first %}
68
- {% assign _img_content = _img %}
51
+ {% assign _img_content = _img_snippet %}
69
52
  {% continue %}
70
53
  {% endif %}
71
54
 
72
55
  {% assign _width = nil %}
73
56
  {% assign _height = nil %}
74
- {% assign _attrs = _img | split: '>' | first | split: ' ' %}
57
+ {% assign _src = nil %}
58
+
59
+ {% assign _left = _img_snippet | split: '/>' | first %}
60
+ {% assign _right = _img_snippet | replace: _left, '' %}
61
+
62
+ {% assign _left = _left | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
63
+ {% assign _attrs = _left | split: ' ' %}
75
64
 
76
65
  {% for _attr in _attrs %}
77
- {% capture _key %}{{ _attr | split: '=' | first }}{% endcapture %}
78
- {% capture _value %}{{ _attr | split: '=' | last | replace: '"', '' }}{% endcapture %}
66
+ {% assign _pair = _attr | split: '=' %}
67
+ {% if _pair.size < 2 %}
68
+ {% continue %}
69
+ {% endif %}
70
+
71
+ {% capture _key %}{{ _pair | first }}{% endcapture %}
72
+ {% capture _value %}{{ _pair | last | replace: '"', '' }}{% endcapture %}
79
73
 
80
74
  {% case _key %}
81
75
  {% when 'width' %}
82
76
  {% assign _width = _value %}
83
77
  {% when 'height' %}
84
78
  {% assign _height = _value %}
79
+ {% when 'src' %}
80
+ {% assign _src = _value %}
85
81
  {% endcase %}
86
82
 
87
- {% if _width and _height %}
88
- {% capture _svg %}data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{_width}} {{_height}}'%3E%3C/svg%3E{% endcapture %}
89
- {% assign _img_content = _img_content | append: '<img src="' | append: _svg | append: '" ' | append: _img %}
83
+ {% if _width and _height and _src %}
90
84
  {% break %}
91
85
  {% endif %}
92
-
93
86
  {% endfor %}
94
87
 
95
- {% unless _width and _height %}
96
- {% assign _img_content = _img_content | append: '<img ' | append: _img %}
97
- {% endunless %}
88
+ {% if _src %}
89
+ {% unless _src contains '://' %}
90
+
91
+ <!-- Add CDN URL -->
92
+ {% if site.img_cdn %}
93
+ {% assign _src_prefix = site.img_cdn %}
94
+ {% else %}
95
+ {% assign _src_prefix = site.baseurl %}
96
+ {% endif %}
97
+
98
+ <!-- Add image path -->
99
+ {% if page.img_path %}
100
+ {% assign _path = page.img_path %}
101
+ {% assign last_char = _path | slice: -1 %}
102
+
103
+ {% unless last_char == '/' %}
104
+ {% assign _path = _path | append: '/' %}
105
+ {% endunless %}
106
+
107
+ {% assign _src_prefix = _src_prefix | append: _path %}
108
+ {% endif %}
109
+
110
+ {% assign _final_src = _src_prefix | append: _src %}
111
+ {% assign _left = _left | replace: _src, _final_src %}
112
+
113
+ {% endunless %}
114
+
115
+ <!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
116
+
117
+ {% assign _left = _left | replace: 'src=', 'data-src=' %}
118
+
119
+ {% endif %}
120
+
121
+ <!-- Add SVG placehoder to prevent layout reflow -->
122
+
123
+ {% if _width and _height %}
124
+ {%- capture _svg -%}
125
+ src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
126
+ {%- endcapture -%}
127
+
128
+ {% assign _left = _svg | append: ' ' | append: _left %}
129
+ {% endif %}
130
+
131
+ <!-- Bypass the HTML-proofer test -->
132
+ {% assign _left = _left | append: ' data-proofer-ignore' %}
133
+
134
+ {% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
98
135
 
99
136
  {% endfor %}
100
137
 
@@ -118,16 +155,16 @@
118
155
  {% assign _left = _snippet | split: '><' | last%}
119
156
 
120
157
  {% if _left contains 'file="' %}
121
- {% assign _text = _left | split: 'file="' | last | split: '"' | first %}
158
+ {% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
122
159
  {% assign _label_icon = 'far fa-file-code' %}
123
160
  {% else %}
124
161
  {% assign _lang = _left | split: 'language-' | last | split: ' ' | first %}
125
- {% capture _text %}{% include language-alias.html language=_lang %}{% endcapture %}
162
+ {% capture _label_text %}{% include language-alias.html language=_lang %}{% endcapture %}
126
163
  {% assign _label_icon = 'fas fa-code small' %}
127
164
  {% endif %}
128
165
 
129
166
  {% capture _label %}
130
- <span text-data="{{ _text }}"><i class="fa-fw {{ _label_icon }}"></i></span>
167
+ <span label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
131
168
  {% endcapture %}
132
169
 
133
170
  {% assign _new_content = _new_content | append: _snippet
@@ -147,6 +184,43 @@
147
184
 
148
185
  {% endif %}
149
186
 
187
+ <!-- Create heading anchors -->
188
+
189
+ {% assign heading_levels = '2,3,4,5' | split: ',' %}
190
+ {% assign _heading_content = _content %}
191
+
192
+ {% for level in heading_levels %}
193
+ {% capture mark_start %}<h{{ level }} id="{% endcapture %}
194
+ {% capture mark_end %}</h{{ level }}>{% endcapture %}
195
+
196
+ {% if _heading_content contains mark_start %}
197
+ {% assign _new_content = nil %}
198
+ {% assign heading_snippets = _heading_content | split: mark_start %}
199
+
200
+ {% for snippet in heading_snippets %}
201
+ {% if forloop.first %}
202
+ {% assign _new_content = snippet %}
203
+ {% continue %}
204
+ {% endif %}
205
+
206
+ {% assign id = snippet | split: '"' | first %}
207
+ {% capture anchor %}<a href="#{{ id }}" class="anchor"><i class="fas fa-hashtag"></i></a>{% endcapture %}
208
+
209
+ {% assign left = snippet | split: mark_end | first %}
210
+ {% assign right = snippet | replace: left, '' %}
211
+
212
+ {% assign _new_content = _new_content | append: mark_start
213
+ | append: left | append: anchor | append: mark_end | append: right
214
+ %}
215
+
216
+ {% endfor %}
217
+
218
+ {% assign _heading_content = _new_content %}
219
+
220
+ {% endif %}
221
+ {% endfor %}
222
+
223
+ {% assign _content = _heading_content %}
150
224
 
151
225
  <!-- return -->
152
226
 
@@ -94,7 +94,7 @@
94
94
  <div class="text-muted small">
95
95
  <p>
96
96
  {% include no-linenos.html content=post.content %}
97
- {{ content | markdownify | strip_html | truncate: 200 }}
97
+ {{ content | markdownify | strip_html | truncate: 200 | escape }}
98
98
  </p>
99
99
  </div>
100
100
  </div>
@@ -4,15 +4,7 @@
4
4
  <div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
5
5
  <div class="col-12 col-sm-11 post-content">
6
6
  <div id="search-hints">
7
- <h4 class="text-muted mb-4">{{ site.data.locales[lang].panel.trending_tags }}</h4>
8
-
9
7
  {% include trending-tags.html %}
10
-
11
- {% for tag in trending_tags %}
12
- {% capture url %}/tags/{{ tag | slugify | url_encode }}/{% endcapture %}
13
- <a class="post-tag" href="{{ url | relative_url }}">{{ tag | replace: '-', ' ' }}</a>
14
- {% endfor %}
15
-
16
8
  </div>
17
9
  <div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
18
10
  </div>
@@ -53,6 +53,16 @@
53
53
 
54
54
  <div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center align-items-center">
55
55
 
56
+ {% unless site.theme_mode %}
57
+ <button class="mode-toggle btn" aria-label="Switch Mode">
58
+ <i class="fas fa-adjust"></i>
59
+ </button>
60
+
61
+ {% if site.data.contact.size > 0 %}
62
+ <span class="icon-border"></span>
63
+ {% endif %}
64
+ {% endunless %}
65
+
56
66
  {% for entry in site.data.contact %}
57
67
  {% capture url %}
58
68
  {%- if entry.type == 'github' -%}
@@ -71,7 +81,6 @@
71
81
 
72
82
  {% if url %}
73
83
  <a href="{{ url }}" aria-label="{{ entry.type }}"
74
- {% unless site.theme_mode %}class="order-{{ forloop.index | plus: 2 }}"{% endunless %}
75
84
  {% unless entry.noblank %}target="_blank" rel="noopener"{% endunless %}>
76
85
  <i class="{{ entry.icon }}"></i>
77
86
  </a>
@@ -79,16 +88,6 @@
79
88
 
80
89
  {% endfor %}
81
90
 
82
- {% unless site.theme_mode %}
83
- {% if site.data.contact.size > 0 %}
84
- <span class="icon-border order-2"></span>
85
- {% endif %}
86
-
87
- <span id="mode-toggle-wrapper" class="order-1">
88
- {% include mode-toggle.html %}
89
- </span>
90
- {% endunless %}
91
-
92
91
  </div> <!-- .sidebar-bottom -->
93
92
 
94
93
  </div><!-- #sidebar -->
@@ -1,27 +1,26 @@
1
1
  <!--
2
2
  Date format snippet
3
- See: /assets/js/_utils/timeage.js
3
+ See: ${JS_ROOT}/utils/timeago.js
4
4
  -->
5
5
 
6
6
  {% assign tooltip_df = site.data.locales[lang].date_format.tooltip %}
7
7
  {% assign post_long_df = site.data.locales[lang].date_format.post.long %}
8
8
  {% assign post_short_df = site.data.locales[lang].date_format.post.short %}
9
9
 
10
- {% if include.preposition %}
11
- {{ include.preposition }}
12
- {% endif %}
13
- <span class="timeago {% if include.class %}{{ include.class }}{% endif %}"
14
- {% if include.tooltip %}
15
- data-toggle="tooltip"
16
- data-placement="bottom"
17
- title="{{ include.date | date: tooltip_df }}"
18
- {% endif %}>
10
+ <em class="timeago{% if include.class %} {{ include.class }}{% endif %}"
11
+ date="{{ include.date }}"
12
+ {% if include.tooltip %}
13
+ data-toggle="tooltip"
14
+ data-placement="bottom"
15
+ title="{{ include.date | date: tooltip_df }}"
16
+ {% endif %}>
17
+
19
18
  {%- assign this_year = site.time | date: "%Y" -%}
20
19
  {%- assign post_year = include.date | date: "%Y" -%}
20
+
21
21
  {%- if post_year == this_year -%}
22
22
  {{ include.date | date: post_short_df }}
23
23
  {%- else -%}
24
24
  {{ include.date | date: post_long_df }}
25
25
  {%- endif -%}
26
- <i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
27
- </span>
26
+ </em>
@@ -0,0 +1,16 @@
1
+ {% assign enable_toc = false %}
2
+ {% if site.toc and page.toc %}
3
+ {% if page.content contains '<h2' or page.content contains '<h3' %}
4
+ {% assign enable_toc = true %}
5
+ {% endif %}
6
+ {% endif %}
7
+
8
+ {% if enable_toc %}
9
+ <!-- BS-toc.js will be loaded at medium priority -->
10
+ <script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js"></script>
11
+
12
+ <div id="toc-wrapper" class="pl-0 pr-4 mb-5">
13
+ <div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[lang].panel.toc -}}</div>
14
+ <nav id="toc" data-toggle="toc"></nav>
15
+ </div>
16
+ {% endif %}
@@ -50,7 +50,7 @@
50
50
  <div id="topbar-title">
51
51
  {% if page.layout == 'home' %}
52
52
  {{- site.data.locales[lang].title | default: site.title -}}
53
- {% elsif page.collection == 'tabs' %}
53
+ {% elsif page.collection == 'tabs' or page.dynamic_title %}
54
54
  {%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
55
55
  {{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
56
56
  {% else %}
@@ -34,3 +34,17 @@
34
34
  {% endif %}
35
35
  {% endfor %}
36
36
  {% endfor %}
37
+
38
+ {% if trending_tags.size > 0 %}
39
+ <div id="access-tags">
40
+ <div class="panel-heading">{{- site.data.locales[lang].panel.trending_tags -}}</div>
41
+ <div class="d-flex flex-wrap mt-3 mb-1 mr-3">
42
+
43
+ {% for tag_name in trending_tags %}
44
+ {% assign url = tag_name | slugify | url_encode | prepend: "/tags/" | append: "/" %}
45
+ <a class="post-tag" href="{{ url | relative_url }}">{{ tag_name }}</a>
46
+ {% endfor %}
47
+
48
+ </div>
49
+ </div>
50
+ {% endif %}
@@ -22,3 +22,19 @@
22
22
  {% for entry in all_list limit:MAX_SIZE %}
23
23
  {% assign update_list = update_list | push: entry %}
24
24
  {% endfor %}
25
+
26
+ {% if update_list.size > 0 %}
27
+
28
+ <div id="access-lastmod" class="post">
29
+ <div class="panel-heading">{{- site.data.locales[lang].panel.lastmod -}}</div>
30
+ <ul class="post-content pl-0 pb-1 ml-1 mt-2">
31
+ {% for item in update_list %}
32
+ {% assign index = item | split: "::" | last | plus: 0 %}
33
+ {% assign post = site.posts[index] %}
34
+ {% assign url = post.url | relative_url %}
35
+ <li><a href="{{ url }}">{{ post.title }}</a></li>
36
+ {% endfor %}
37
+ </ul>
38
+ </div> <!-- #access-lastmod -->
39
+
40
+ {% endif %}
@@ -13,10 +13,14 @@ layout: compress
13
13
  {% endif %}
14
14
  {% endcapture %}
15
15
 
16
- <html lang="{{ site.lang }}" {{ prefer_mode }}>
16
+ <html lang="{{ site.lang }}"{{ prefer_mode }}>
17
17
 
18
18
  {% include head.html %}
19
19
 
20
+ {% unless site.theme_mode %}
21
+ {% include mode-toggle.html %}
22
+ {% endunless %}
23
+
20
24
  <body data-spy="scroll" data-target="#toc">
21
25
 
22
26
  {% include sidebar.html %}
@@ -26,7 +30,7 @@ layout: compress
26
30
  <div id="main-wrapper">
27
31
  <div id="main">
28
32
 
29
- {% include refactor-content.html content=content %}
33
+ {{ content }}
30
34
 
31
35
  {% include footer.html %}
32
36
 
data/_layouts/home.html CHANGED
@@ -53,13 +53,13 @@ layout: page
53
53
  <div class="post-content">
54
54
  <p>
55
55
  {% include no-linenos.html content=post.content %}
56
- {{ content | markdownify | strip_html | truncate: 200 }}
56
+ {{ content | markdownify | strip_html | truncate: 200 | escape }}
57
57
  </p>
58
58
  </div>
59
59
 
60
- <div class="post-meta text-muted d-flex justify-content-between">
60
+ <div class="post-meta text-muted d-flex">
61
61
 
62
- <div>
62
+ <div class="mr-auto">
63
63
  <!-- posted date -->
64
64
  <i class="far fa-calendar fa-fw"></i>
65
65
  {% include timeago.html date=post.date tooltip=true %}
@@ -68,12 +68,15 @@ layout: page
68
68
  <i class="far fa-clock fa-fw"></i>
69
69
  {% include read-time.html content=post.content %}
70
70
 
71
- <!-- page views -->
72
- {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
73
- <i class="far fa-eye fa-fw"></i>
74
- <span id="pv_{{-post.title-}}" class="pageviews">
75
- <i class="fas fa-spinner fa-spin fa-fw"></i>
76
- </span>
71
+ <!-- categories -->
72
+ {% if post.categories.size > 0 %}
73
+ <i class="far fa-folder-open fa-fw"></i>
74
+ <span>
75
+ {% for category in post.categories %}
76
+ {{ category }}
77
+ {%- unless forloop.last -%},{%- endunless -%}
78
+ {% endfor %}
79
+ </span>
77
80
  {% endif %}
78
81
  </div>
79
82
 
data/_layouts/page.html CHANGED
@@ -1,41 +1,64 @@
1
1
  ---
2
2
  layout: default
3
- # The page layout
4
3
  ---
5
4
 
5
+ {% include lang.html %}
6
+
6
7
  <div class="row">
7
- <div class="col-12 col-lg-11 col-xl-8">
8
- <div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 mb-md-4">
9
- {% if page.dynamic_title %}
8
+
9
+ <!-- core -->
10
+ <div id="core-wrapper" class="col-12 col-lg-11 col-xl-8">
11
+ <div class="post pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
12
+
13
+ {% capture _content %}
14
+ {% if layout.refactor or page.layout == 'page' %}
15
+ {% include refactor-content.html content=content %}
16
+ {% else %}
17
+ {{ content }}
18
+ {% endif %}
19
+ {% endcapture %}
20
+
21
+ {% if page.layout == 'page' or page.collection == 'tabs'%}
22
+ {% assign title = site.data.locales[lang].tabs[tab_key] | default: page.title %}
10
23
  <h1 class="dynamic-title">
11
- {% if page.collection == 'tabs' %}
12
- {%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
13
- {{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
14
- {% else %}
15
- {{- page.title -}}
16
- {% endif %}
24
+ {{ title }}
17
25
  </h1>
18
26
  <div class="post-content">
19
- {{ content }}
27
+ {{ _content }}
20
28
  </div>
21
29
  {% else %}
22
- {{ content }}
30
+ {{ _content }}
23
31
  {% endif %}
24
- </div> <!-- #page -->
25
- </div><!-- .col-12 -->
26
32
 
27
- {% include panel.html %}
33
+ </div>
34
+ </div> <!-- #core-wrapper -->
35
+
36
+ <!-- pannel -->
37
+ <div id="panel-wrapper" class="col-xl-3 pl-2 text-muted topbar-down">
38
+
39
+ <div class="access">
40
+ {% include update-list.html %}
41
+ {% include trending-tags.html %}
42
+ </div>
43
+
44
+ {% for _include in layout.pannel_includes %}
45
+ {% assign _include_path = _include | append: '.html' %}
46
+ {% include {{ _include_path }} %}
47
+ {% endfor %}
48
+ </div>
28
49
 
29
50
  </div>
30
51
 
31
- {% if site.disqus.comments and page.comments %}
52
+ <!-- tail -->
53
+ {% if layout.tail_includes %}
32
54
  <div class="row">
33
55
  <div class="col-12 col-lg-11 col-xl-8">
34
- <div class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
35
-
36
- {% include disqus.html %}
37
-
38
- </div> <!-- .pl-1 pr-1 -->
39
- </div> <!-- .col-12 -->
56
+ <div id="tail-wrapper" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
57
+ {% for _include in layout.tail_includes %}
58
+ {% assign _include_path = _include | append: '.html' %}
59
+ {% include {{ _include_path }} %}
60
+ {% endfor %}
61
+ </div>
62
+ </div>
40
63
  </div> <!-- .row -->
41
64
  {% endif %}