NodeBB 4.14 turned on real HTML escaping for single-brace template interpolations (4.13 used an identity escape). This ports raw-HTML output to the double-brace forms ({{helper(...)}}, {{txEscape(content)}}, {{tx(name)}}), mirroring the harmony 2.2.72 -> 3.0.15 and core 4.13.2 -> 4.14.0 template diffs. Fixes the escaped-markup breakage on westgate.pw after the 2026.07.11-1 deploy.
Verified on a fresh 4.14.0 dev stack: no escaped tags on /, /categories, /category/2, /topic/1, /search; contract tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
Reviewed-on: #19
Reviewed-by: xtul <mpiasecki720@protonmail.com>
Co-authored-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
Co-committed-by: gitea-bot <gitea-bot@noreply.git.westgate.pw>
40 lines
2.5 KiB
Smarty
40 lines
2.5 KiB
Smarty
<button type="button" class="btn btn-ghost btn-sm ff-secondary d-flex align-items-center gap-2 dropdown-toggle h-100" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span component="category-selector-selected" class="fw-semibold">
|
|
{{{ if (selectedCategory && !showCategorySelectLabel) }}}
|
|
<span class="category-item d-inline-flex align-items-center gap-1 {{{ if selectedCategory.class }}}{selectedCategory.class}{{{ end }}}">
|
|
{{buildCategoryIcon(selectedCategory, "24px", "rounded-circle")}}
|
|
<span class="category-name">{{tx(selectedCategory.name)}}</span>
|
|
</span>
|
|
{{{ else }}}
|
|
<i class="fa fa-fw {{{ if selectCategoryIcon }}}{selectCategoryIcon}{{{ else }}}fa-list{{{ end }}} text-primary"></i>
|
|
<span class="d-none d-md-inline">{{{ if selectCategoryLabel }}}{selectCategoryLabel}{{{ else }}}[[topic:thread-tools.select-category]]{{{ end }}}</span>
|
|
{{{ end }}}
|
|
</span>
|
|
</button>
|
|
|
|
<div class="dropdown-menu p-1">
|
|
<div component="category-selector-search" class="p-1 hidden">
|
|
<input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
|
|
<hr class="mt-2 mb-0"/>
|
|
</div>
|
|
<ul component="category/list" class="list-unstyled mb-0 text-sm category-dropdown-menu ghost-scrollbar" role="menu">
|
|
<li component="category/no-matches" role="presentation" class="category hidden">
|
|
<a class="dropdown-item rounded-1" role="menuitem">[[search:no-matches]]</a>
|
|
</li>
|
|
{{{ each categoryItems }}}
|
|
<li role="presentation" class="category {{{ if ./disabledClass }}}disabled {{{ end }}}{{{ if ./class }}} {./class}{{{ end }}}" data-cid="{./cid}" data-name="{./name}" data-parent-cid="{./parentCid}">
|
|
<a class="dropdown-item rounded-1 {{{ if ./disabledClass }}}disabled{{{ end }}}" role="menuitem" href="#">{./level}
|
|
<span component="category-markup" style="{{{ if ./match }}}font-weight: bold;{{{end}}}">
|
|
<span class="category-item d-inline-flex align-items-center gap-1 {{{ if ./class }}}{./class}{{{ end }}}">
|
|
{{{ if ./icon }}}
|
|
{{buildCategoryIcon(@value, "24px", "rounded-circle")}}
|
|
{{{ end }}}
|
|
<span class="category-name">{{tx(./name)}}</span>
|
|
</span>
|
|
</span>
|
|
</a>
|
|
</li>
|
|
{{{ end }}}
|
|
</ul>
|
|
</div>
|