| 1 | <%#
|
|---|
| 2 | Wat er onder de zoekbalk staat. EEN render voor beide ingangen: het live
|
|---|
| 3 | resultatenvak (via /search/results) en de pagina /search?q=... zelf. Zo zien
|
|---|
| 4 | ze er per constructie hetzelfde uit; twee renders lopen gegarandeerd uit de
|
|---|
| 5 | pas.
|
|---|
| 6 |
|
|---|
| 7 | Verwacht: query, results (posts), tracks, events, pages, queryError,
|
|---|
| 8 | remoteUri, remote, remoteKind, mayLookup, remoteReacted, siteTitle,
|
|---|
| 9 | siteUrlBase, formatDate, t.
|
|---|
| 10 |
|
|---|
| 11 | GEEN SCRIPT hierin: het live vak zet dit via innerHTML neer, en daar draait
|
|---|
| 12 | niets. Gedrag (afspelen, waarderen, htmx-links) luistert op document.
|
|---|
| 13 | %>
|
|---|
| 14 | <%
|
|---|
| 15 | const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
|
|---|
| 16 | const _results = (typeof results !== 'undefined' && results) ? results : [];
|
|---|
| 17 | const _tracks = (typeof tracks !== 'undefined' && tracks) ? tracks : [];
|
|---|
| 18 | const _events = (typeof events !== 'undefined' && events) ? events : [];
|
|---|
| 19 | const _pages = (typeof pages !== 'undefined' && pages) ? pages : [];
|
|---|
| 20 | const _remote = (typeof remoteUri !== 'undefined' && remoteUri) ? remoteUri : '';
|
|---|
| 21 | // Alles via locals: een veld dat een aanroeper vergeet mag de render niet
|
|---|
| 22 | // laten omvallen (een kale verwijzing naar iets ongedefinieerds gooit).
|
|---|
| 23 | const _queryError = !!locals.queryError;
|
|---|
| 24 | const _mayLookup = !!locals.mayLookup;
|
|---|
| 25 | const _found = locals.remote || null;
|
|---|
| 26 | const _kind = locals.remoteKind || null;
|
|---|
| 27 | const _reacted = locals.remoteReacted || { liked: false, boosted: false };
|
|---|
| 28 | const _siteTitle = locals.siteTitle || '';
|
|---|
| 29 | const _inPost = t('search.in_post');
|
|---|
| 30 | const _any = _results.length || _tracks.length || _events.length || _pages.length;
|
|---|
| 31 | %>
|
|---|
| 32 | <% if (locals.query) { %>
|
|---|
| 33 | <div class="sr">
|
|---|
| 34 | <% if (_remote) { %>
|
|---|
| 35 | <%# Een geplakt adres is geen zoekterm maar een aanwijzing (shaer-utpi).
|
|---|
| 36 | Ophalen doen we alleen namens een ingelogde beheerder van de site. %>
|
|---|
| 37 | <section class="sr-section sr-fediverse">
|
|---|
| 38 | <h2 class="sr-title"><%= t('search.section_fediverse') %></h2>
|
|---|
| 39 | <% if (!_mayLookup) { %>
|
|---|
| 40 | <p class="sr-note"><%= t('search.fedi_signin') %></p>
|
|---|
| 41 | <% } else if (_found && _kind === 'note') { %>
|
|---|
| 42 | <%- include('./remote-object', { target: _found, uri: _remote, reacted: _reacted, siteTitle: _siteTitle, compact: true }) %>
|
|---|
| 43 | <% } else if (_found && _kind === 'actor') { %>
|
|---|
| 44 | <%- include('./remote-actor', { actor: _found, siteTitle: _siteTitle, compact: true }) %>
|
|---|
| 45 | <% } else { %>
|
|---|
| 46 | <p class="sr-note"><%= t('fedi.remote_notfound') %></p>
|
|---|
| 47 | <% } %>
|
|---|
| 48 | <% if (_found) { %><%- include('./fedi-interact-styles') %><% } %>
|
|---|
| 49 | </section>
|
|---|
| 50 | <% } %>
|
|---|
| 51 |
|
|---|
| 52 | <% if (_queryError) { %>
|
|---|
| 53 | <p class="sr-note"><%= t('search.error') %></p>
|
|---|
| 54 | <% } %>
|
|---|
| 55 |
|
|---|
| 56 | <% if (_tracks.length) { %>
|
|---|
| 57 | <section class="sr-section">
|
|---|
| 58 | <h2 class="sr-title"><%= t('search.section_tracks') %></h2>
|
|---|
| 59 | <div class="sr-tracks">
|
|---|
| 60 | <% _tracks.forEach(function (tr) {
|
|---|
| 61 | const tj = JSON.stringify({ id: tr.id, url: tr.url, title: tr.title, artist: tr.artist || '', cover: tr.cover || '' })
|
|---|
| 62 | .replace(/&/g, '&').replace(/'/g, ''').replace(/</g, '<'); %>
|
|---|
| 63 | <div class="post-audio-track sr-track" id="track-<%= tr.id %>"
|
|---|
| 64 | data-pcms-track-id="<%= tr.id %>" data-pcms-track-url="<%= tr.url %>"
|
|---|
| 65 | data-pcms-track='<%- tj %>'>
|
|---|
| 66 | <button type="button" class="pat-play" aria-label="<%= tr.title %>">
|
|---|
| 67 | <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M8 4l12 8-12 8z"/></svg>
|
|---|
| 68 | </button>
|
|---|
| 69 | <% if (tr.cover) { %>
|
|---|
| 70 | <span class="sr-track-cover" style="background-image:url('<%= tr.cover %>')" aria-hidden="true"></span>
|
|---|
| 71 | <% } %>
|
|---|
| 72 | <div class="pat-info">
|
|---|
| 73 | <div class="pat-title"><%= tr.title %></div>
|
|---|
| 74 | <% if (tr.artist || tr.album) { %>
|
|---|
| 75 | <div class="pat-artist"><%= tr.artist %><% if (tr.artist && tr.album) { %> · <% } %><%= tr.album %></div>
|
|---|
| 76 | <% } %>
|
|---|
| 77 | </div>
|
|---|
| 78 | <% if (tr.postUrl) { %>
|
|---|
| 79 | <a class="sr-track-link" href="<%= tr.postUrl %>"
|
|---|
| 80 | hx-get="<%= tr.postUrl %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" hx-push-url="<%= tr.postUrl %>"><%= _inPost %></a>
|
|---|
| 81 | <% } %>
|
|---|
| 82 | </div>
|
|---|
| 83 | <% }); %>
|
|---|
| 84 | </div>
|
|---|
| 85 | </section>
|
|---|
| 86 | <% } %>
|
|---|
| 87 |
|
|---|
| 88 | <% if (_results.length) { %>
|
|---|
| 89 | <section class="sr-section">
|
|---|
| 90 | <h2 class="sr-title"><%= t('search.section_posts') %></h2>
|
|---|
| 91 | <ol class="sr-list">
|
|---|
| 92 | <% _results.forEach(function (r) { %>
|
|---|
| 93 | <li>
|
|---|
| 94 | <a class="sr-item" href="<%= _base %>/<%= r.slug %>"
|
|---|
| 95 | hx-get="<%= _base %>/<%= r.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
|
|---|
| 96 | hx-push-url="<%= _base %>/<%= r.slug %>" hx-indicator="#pcms-loading">
|
|---|
| 97 | <span class="sr-item-title"><%= r.title || '(zonder titel)' %></span>
|
|---|
| 98 | <span class="sr-item-meta"><%= r.author_username %><% if (r.published_at) { %> · <%= formatDate(r.published_at) %><% } %></span>
|
|---|
| 99 | <% if (r.snippet) { %><span class="sr-item-snippet"><%- r.snippet %></span><% } %>
|
|---|
| 100 | </a>
|
|---|
| 101 | </li>
|
|---|
| 102 | <% }); %>
|
|---|
| 103 | </ol>
|
|---|
| 104 | </section>
|
|---|
| 105 | <% } %>
|
|---|
| 106 |
|
|---|
| 107 | <% if (_events.length) { %>
|
|---|
| 108 | <section class="sr-section">
|
|---|
| 109 | <h2 class="sr-title"><%= t('search.section_events') %></h2>
|
|---|
| 110 | <ol class="sr-list">
|
|---|
| 111 | <% _events.forEach(function (ev) { %>
|
|---|
| 112 | <li>
|
|---|
| 113 | <a class="sr-item" href="<%= ev.url %>">
|
|---|
| 114 | <span class="sr-item-title"><%= ev.where || ev.date %></span>
|
|---|
| 115 | <span class="sr-item-meta"><%= [ev.date, ev.time].filter(Boolean).join(' ') %></span>
|
|---|
| 116 | </a>
|
|---|
| 117 | </li>
|
|---|
| 118 | <% }); %>
|
|---|
| 119 | </ol>
|
|---|
| 120 | </section>
|
|---|
| 121 | <% } %>
|
|---|
| 122 |
|
|---|
| 123 | <% if (_pages.length) { %>
|
|---|
| 124 | <section class="sr-section">
|
|---|
| 125 | <h2 class="sr-title"><%= t('search.section_pages') %></h2>
|
|---|
| 126 | <ul class="sr-list">
|
|---|
| 127 | <% _pages.forEach(function (pg) { %>
|
|---|
| 128 | <li><a class="sr-item sr-item-row" href="<%= pg.url %>"><span class="sr-item-title"><%= pg.label %></span><span aria-hidden="true">→</span></a></li>
|
|---|
| 129 | <% }); %>
|
|---|
| 130 | </ul>
|
|---|
| 131 | </section>
|
|---|
| 132 | <% } %>
|
|---|
| 133 |
|
|---|
| 134 | <% if (!_queryError && !_any && !_remote) { %>
|
|---|
| 135 | <p class="sr-empty"><%= t('search.empty') %></p>
|
|---|
| 136 | <% } %>
|
|---|
| 137 | </div>
|
|---|
| 138 | <% } %>
|
|---|