source: Klonkt/src/views/pages/search.ejs@ 015ce46

main
Last change on this file since 015ce46 was 929d98d, checked in by roboburr <roboburr@…>, 3 months ago

fix(i18n): search.ejs tracks loop shadowed t() → 500

function(t) in the tracks loop shadowed the translate t(); label
search.in_post now fetched before the loop (_inPost). Known pitfall.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 6.5 KB
Line 
1<% const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : ''; %>
2<% const _tracks = (typeof tracks !== 'undefined' && tracks) ? tracks : []; %>
3<div class="container search-page">
4 <h1><%= t('nav.search') %></h1>
5
6 <form method="get" action="<%= _base %>/search" class="search-page-form">
7 <input
8 type="search"
9 name="q"
10 value="<%= query %>"
11 placeholder="<%= t('search.placeholder') %>"
12 autocomplete="off"
13 autofocus
14 aria-label="<%= t('nav.search') %>">
15 <button type="submit" class="btn btn-primary"><%= t('search.button') %></button>
16 </form>
17
18 <% if (queryError) { %>
19 <p class="search-error"><%= t('search.error') %></p>
20 <% } %>
21
22 <% if (query && !queryError) { %>
23 <p class="search-meta">
24 <%= t(total === 1 ? 'search.results_one' : 'search.results_other', { n: total, q: query }) %>
25 </p>
26 <% } %>
27
28 <% if (_tracks.length) { %>
29 <h2 class="search-section-title"><%= t('search.section_tracks') %></h2>
30 <% var _inPost = t('search.in_post'); /* t() vóór de loop ophalen: function(t) overschaduwt 'm */ %>
31 <div class="search-tracks">
32 <% _tracks.forEach(function(t) {
33 const tj = JSON.stringify({ id: t.id, url: t.url, title: t.title, artist: t.artist || '', cover: t.cover || '' })
34 .replace(/&/g, '&amp;').replace(/'/g, '&#39;').replace(/</g, '&lt;'); %>
35 <div class="post-audio-track search-track" id="track-<%= t.id %>"
36 data-pcms-track-id="<%= t.id %>" data-pcms-track-url="<%= t.url %>"
37 data-pcms-track='<%- tj %>'>
38 <button type="button" class="pat-play" aria-label="Speel <%= t.title %>">
39 <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M8 4l12 8-12 8z"/></svg>
40 </button>
41 <% if (t.cover) { %>
42 <span class="search-track-cover" style="background-image:url('<%= t.cover %>')" aria-hidden="true"></span>
43 <% } %>
44 <div class="pat-info">
45 <div class="pat-title"><%= t.title %></div>
46 <% if (t.artist || t.album) { %>
47 <div class="pat-artist">
48 <%= t.artist %><% if (t.artist && t.album) { %> &middot; <% } %><%= t.album %>
49 </div>
50 <% } %>
51 </div>
52 <% if (t.postUrl) { %>
53 <a class="search-track-link"
54 href="<%= t.postUrl %>"
55 hx-get="<%= t.postUrl %>?partial=1"
56 hx-target="#pcms-main"
57 hx-swap="innerHTML"
58 hx-push-url="<%= t.postUrl %>"
59 aria-label="<%= _inPost %>"><%= _inPost %></a>
60 <% } %>
61 </div>
62 <% }); %>
63 </div>
64 <% } %>
65
66 <% if (results && results.length) { %>
67 <% if (_tracks.length) { %><h2 class="search-section-title"><%= t('search.section_posts') %></h2><% } %>
68 <ol class="search-results">
69 <% results.forEach(function(r) { %>
70 <li class="search-result">
71 <h3 class="search-result-title">
72 <a href="<%= _base %>/<%= r.slug %>"
73 hx-get="<%= _base %>/<%= r.slug %>?partial=1"
74 hx-target="#pcms-main"
75 hx-swap="innerHTML"
76 hx-push-url="<%= _base %>/<%= r.slug %>"
77 hx-indicator="#pcms-loading">
78 <%= r.title || '(zonder titel)' %>
79 </a>
80 </h3>
81 <p class="search-result-meta">
82 <%= r.author_username %>
83 <% if (r.published_at) { %> &middot; <%= formatDate(r.published_at) %><% } %>
84 </p>
85 <p class="search-result-snippet"><%- r.snippet %></p>
86 </li>
87 <% }); %>
88 </ol>
89 <% } %>
90
91 <% if (query && !queryError && !results.length && !_tracks.length) { %>
92 <p class="search-empty"><%= t('search.empty') %></p>
93 <% } %>
94</div>
95
96<style>
97.search-page { max-width: 720px; margin: 3rem auto; padding: 0 1rem; }
98.search-page h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 1.5rem; }
99
100.search-page-form {
101 display: flex;
102 gap: 0.5rem;
103 margin-bottom: 1.5rem;
104}
105.search-page-form input {
106 flex: 1;
107 padding: 0.6rem 0.9rem;
108 border: 1px solid var(--rule);
109 border-radius: 5px;
110 background: var(--paper-2);
111 color: var(--ink);
112 font-size: 1rem;
113}
114.search-page-form input:focus {
115 outline: none;
116 border-color: var(--accent);
117}
118
119.search-meta {
120 color: var(--ink-muted, var(--ink-soft));
121 font-size: 0.9rem;
122 margin: 0 0 1rem;
123}
124.search-section-title {
125 font-family: var(--font-display, serif);
126 font-size: 1.1rem;
127 margin: 1.75rem 0 0.75rem;
128 color: var(--ink-soft);
129 text-transform: uppercase;
130 letter-spacing: 0.05em;
131}
132.search-error {
133 background: rgba(200, 60, 60, 0.15);
134 color: #c33;
135 padding: 0.75rem 1rem;
136 border-radius: 6px;
137 border: 1px solid rgba(200, 60, 60, 0.3);
138}
139.search-empty {
140 color: var(--ink-muted, var(--ink-soft));
141 text-align: center;
142 margin: 3rem 0;
143}
144
145/* Nummer-resultaten */
146.search-tracks { display: flex; flex-direction: column; gap: 0.25rem; }
147.search-track.post-audio-track {
148 display: flex;
149 align-items: center;
150 gap: 0.75rem;
151 padding: 0.5rem 0.6rem;
152 border-radius: 8px;
153}
154.search-track .search-track-cover {
155 width: 38px; height: 38px;
156 flex: 0 0 38px;
157 border-radius: 5px;
158 background-size: cover;
159 background-position: center;
160 background-color: var(--paper-2);
161}
162.search-track .pat-info { flex: 1; min-width: 0; }
163.search-track .pat-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
164.search-track .pat-artist { font-size: 0.82rem; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
165.search-track-link {
166 flex: 0 0 auto;
167 font-size: 0.82rem;
168 color: var(--accent);
169 text-decoration: none;
170 white-space: nowrap;
171}
172.search-track-link:hover { text-decoration: underline; }
173
174.search-results {
175 list-style: none;
176 margin: 0;
177 padding: 0;
178}
179.search-result {
180 padding: 1rem 0;
181 border-bottom: 1px solid var(--rule);
182}
183.search-result:last-child { border-bottom: 0; }
184
185.search-result-title {
186 font-family: var(--font-display, serif);
187 font-size: 1.25rem;
188 margin: 0 0 0.25rem;
189}
190.search-result-title a {
191 color: var(--ink);
192 text-decoration: none;
193}
194.search-result-title a:hover { color: var(--accent); }
195
196.search-result-meta {
197 margin: 0 0 0.5rem;
198 color: var(--ink-muted, var(--ink-soft));
199 font-size: 0.85rem;
200}
201
202.search-result-snippet {
203 margin: 0;
204 color: var(--ink-soft);
205 line-height: 1.5;
206}
207.search-result-snippet mark {
208 background: var(--accent);
209 color: white;
210 padding: 0.05em 0.25em;
211 border-radius: 3px;
212}
213</style>
Note: See TracBrowser for help on using the repository browser.