Changeset fe86013 in Klonkt


Ignore:
Timestamp:
06/21/2026 11:45:21 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
929d98d
Parents:
137cca5
Message:

feat(i18n phase 4): post comments/like/related + search page (NL/EN/DE)

post.ejs (comment heading with plural, empty state, reply/delete/cancel,
comment form, pending notice, related posts), search.ejs (title, placeholder,
button, results with plural, sections, empty), like button (login title).

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

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/services/i18n.js

    r137cca5 rfe86013  
    9292    // Bottom-tab (mobiel)
    9393    'tab.home': 'Home', 'tab.search': 'Zoek', 'tab.write': 'Schrijven', 'tab.profile': 'Profiel',
     94    // Reacties + gerelateerd (post-pagina)
     95    'comments.heading_one': '{n} reactie', 'comments.heading_other': '{n} reacties',
     96    'comments.empty': 'Nog geen reacties.',
     97    'comments.to_start': 'om de conversatie te starten.',
     98    'comments.reply': 'Reageer', 'comments.delete': 'Verwijder', 'comments.cancel': 'Annuleren',
     99    'comments.delete_confirm': 'Deze reactie verwijderen?',
     100    'comments.reply_to': 'Antwoord aan {name}…',
     101    'comments.add_as': 'Reageer als', 'comments.placeholder': 'Deel je gedachten…',
     102    'comments.post': 'Plaats reactie', 'comments.login_to_comment': 'Log in om te reageren',
     103    'comments.pending': 'Je reactie wacht op goedkeuring. Hij verschijnt zodra een beheerder hem goedkeurt.',
     104    'related.title': 'Gerelateerde posts',
     105    // Zoeken + like
     106    'search.placeholder': 'Zoek posts en nummers…', 'search.button': 'Zoek',
     107    'search.error': 'Kon die zoekopdracht niet uitvoeren. Probeer een eenvoudiger term.',
     108    'search.results_one': '{n} resultaat voor “{q}”', 'search.results_other': '{n} resultaten voor “{q}”',
     109    'search.section_tracks': 'Nummers', 'search.section_posts': 'Posts',
     110    'search.empty': 'Niets gevonden.', 'search.in_post': 'in post →',
     111    'like.login_title': 'Log in om deze post te liken',
    94112  },
    95113  en: {
     
    169187    'auth.f_password': 'Password (min 8 chars)',
    170188    'tab.home': 'Home', 'tab.search': 'Search', 'tab.write': 'Write', 'tab.profile': 'Profile',
     189    'comments.heading_one': '{n} comment', 'comments.heading_other': '{n} comments',
     190    'comments.empty': 'No comments yet.',
     191    'comments.to_start': 'to start the conversation.',
     192    'comments.reply': 'Reply', 'comments.delete': 'Delete', 'comments.cancel': 'Cancel',
     193    'comments.delete_confirm': 'Delete this comment?',
     194    'comments.reply_to': 'Reply to {name}…',
     195    'comments.add_as': 'Add a comment as', 'comments.placeholder': 'Share your thoughts…',
     196    'comments.post': 'Post comment', 'comments.login_to_comment': 'Log in to comment',
     197    'comments.pending': 'Your comment is awaiting moderation. It will appear once an admin approves it.',
     198    'related.title': 'Related posts',
     199    'search.placeholder': 'Search posts and tracks…', 'search.button': 'Search',
     200    'search.error': 'Couldn’t run that search. Try a simpler term.',
     201    'search.results_one': '{n} result for “{q}”', 'search.results_other': '{n} results for “{q}”',
     202    'search.section_tracks': 'Tracks', 'search.section_posts': 'Posts',
     203    'search.empty': 'Nothing found.', 'search.in_post': 'in post →',
     204    'like.login_title': 'Log in to like this post',
    171205  },
    172206  de: {
     
    246280    'auth.f_password': 'Passwort (min. 8 Zeichen)',
    247281    'tab.home': 'Start', 'tab.search': 'Suche', 'tab.write': 'Schreiben', 'tab.profile': 'Profil',
     282    'comments.heading_one': '{n} Kommentar', 'comments.heading_other': '{n} Kommentare',
     283    'comments.empty': 'Noch keine Kommentare.',
     284    'comments.to_start': 'um das Gespräch zu starten.',
     285    'comments.reply': 'Antworten', 'comments.delete': 'Löschen', 'comments.cancel': 'Abbrechen',
     286    'comments.delete_confirm': 'Diesen Kommentar löschen?',
     287    'comments.reply_to': 'Antwort an {name}…',
     288    'comments.add_as': 'Kommentieren als', 'comments.placeholder': 'Teile deine Gedanken…',
     289    'comments.post': 'Kommentar posten', 'comments.login_to_comment': 'Zum Kommentieren anmelden',
     290    'comments.pending': 'Dein Kommentar wartet auf Freigabe. Er erscheint, sobald ein Administrator ihn genehmigt.',
     291    'related.title': 'Ähnliche Beiträge',
     292    'search.placeholder': 'Beiträge und Titel suchen…', 'search.button': 'Suchen',
     293    'search.error': 'Diese Suche konnte nicht ausgeführt werden. Versuch einen einfacheren Begriff.',
     294    'search.results_one': '{n} Ergebnis für „{q}“', 'search.results_other': '{n} Ergebnisse für „{q}“',
     295    'search.section_tracks': 'Titel', 'search.section_posts': 'Beiträge',
     296    'search.empty': 'Nichts gefunden.', 'search.in_post': 'im Beitrag →',
     297    'like.login_title': 'Zum Liken anmelden',
    248298  },
    249299};
  • src/views/pages/post.ejs

    r137cca5 rfe86013  
    7575  <section class="post-comments" id="comments">
    7676    <h2 class="comments-heading">
    77       <%= totalComments %> comment<%= totalComments === 1 ? '' : 's' %>
     77      <%= t(totalComments === 1 ? 'comments.heading_one' : 'comments.heading_other', { n: totalComments }) %>
    7878    </h2>
    7979
     
    8686          var s = document.createElement('div');
    8787          s.className = 'comments-pending-flash';
    88           s.textContent = 'Your comment is awaiting moderation. It will appear once an admin approves it.';
     88          s.textContent = <%- JSON.stringify(t('comments.pending')) %>;
    8989          document.currentScript.parentNode.insertBefore(s, document.currentScript);
    9090        }
     
    9393
    9494    <% if (!comments || !comments.length) { %>
    95       <p class="comments-empty">No comments yet.<% if (!user) { %> <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>">Log in</a> to start the conversation.<% } %></p>
     95      <p class="comments-empty"><%= t('comments.empty') %><% if (!user) { %> <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>"><%= t('nav.login') %></a> <%= t('comments.to_start') %><% } %></p>
    9696    <% } else { %>
    9797      <ol class="comments-list">
     
    113113              <div class="comment-actions">
    114114                <% if (user && canMutate) { %>
    115                   <button type="button" class="comment-reply-btn" data-reply-to="<%= c.id %>">Reply</button>
     115                  <button type="button" class="comment-reply-btn" data-reply-to="<%= c.id %>"><%= t('comments.reply') %></button>
    116116                <% } %>
    117117                <% if (user && permissions.canDeleteComment(user, c, site)) { %>
    118                   <form method="post" action="<%= _base %>/comments/<%= c.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
    119                     <button type="submit" class="comment-delete-btn">Delete</button>
     118                  <form method="post" action="<%= _base %>/comments/<%= c.id %>/delete" style="display:inline" onsubmit="return confirm('<%= t('comments.delete_confirm') %>')">
     119                    <button type="submit" class="comment-delete-btn"><%= t('comments.delete') %></button>
    120120                  </form>
    121121                <% } %>
     
    127127                  <input type="hidden" name="post_slug" value="<%= post.slug %>">
    128128                  <input type="hidden" name="parent_comment_id" value="<%= c.id %>">
    129                   <textarea name="content" rows="3" maxlength="4000" placeholder="Reply to <%= c.author_username %>…" required></textarea>
     129                  <textarea name="content" rows="3" maxlength="4000" placeholder="<%= t('comments.reply_to', { name: c.author_username }) %>" required></textarea>
    130130                  <div class="comment-reply-form-actions">
    131                     <button type="submit" class="btn btn-primary">Reply</button>
    132                     <button type="button" class="btn comment-cancel-reply">Cancel</button>
     131                    <button type="submit" class="btn btn-primary"><%= t('comments.reply') %></button>
     132                    <button type="button" class="btn comment-cancel-reply"><%= t('comments.cancel') %></button>
    133133                  </div>
    134134                </form>
     
    155155                        <div class="comment-actions">
    156156                          <% if (user && permissions.canDeleteComment(user, r, site)) { %>
    157                             <form method="post" action="<%= _base %>/comments/<%= r.id %>/delete" style="display:inline" onsubmit="return confirm('Delete this comment?')">
    158                               <button type="submit" class="comment-delete-btn">Delete</button>
     157                            <form method="post" action="<%= _base %>/comments/<%= r.id %>/delete" style="display:inline" onsubmit="return confirm('<%= t('comments.delete_confirm') %>')">
     158                              <button type="submit" class="comment-delete-btn"><%= t('comments.delete') %></button>
    159159                            </form>
    160160                          <% } %>
     
    176176        <input type="hidden" name="post_slug" value="<%= post.slug %>">
    177177        <label class="comment-form-label">
    178           <span>Add a comment as <strong><%= user.username %></strong></span>
    179           <textarea name="content" rows="3" maxlength="4000" placeholder="Share your thoughts…" required></textarea>
     178          <span><%= t('comments.add_as') %> <strong><%= user.username %></strong></span>
     179          <textarea name="content" rows="3" maxlength="4000" placeholder="<%= t('comments.placeholder') %>" required></textarea>
    180180        </label>
    181         <button type="submit" class="btn btn-primary">Post comment</button>
     181        <button type="submit" class="btn btn-primary"><%= t('comments.post') %></button>
    182182      </form>
    183183    <% } else if (!user) { %>
    184184      <p class="comments-login-cta">
    185         <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>" class="btn">Log in to comment</a>
     185        <a href="/auth/login?next=<%= encodeURIComponent(_base + '/' + post.slug + '#comments') %>" class="btn"><%= t('comments.login_to_comment') %></a>
    186186      </p>
    187187    <% } else { %>
     
    217217  <% if (relatedPosts && relatedPosts.length > 0) { %>
    218218    <section class="post-related" aria-labelledby="related-heading">
    219       <h2 class="post-related-heading" id="related-heading">Gerelateerde posts</h2>
     219      <h2 class="post-related-heading" id="related-heading"><%= t('related.title') %></h2>
    220220      <ul class="post-related-grid">
    221221        <% relatedPosts.forEach(function(rp) { %>
  • src/views/pages/search.ejs

    r137cca5 rfe86013  
    22<% const _tracks = (typeof tracks !== 'undefined' && tracks) ? tracks : []; %>
    33<div class="container search-page">
    4   <h1>Zoeken</h1>
     4  <h1><%= t('nav.search') %></h1>
    55
    66  <form method="get" action="<%= _base %>/search" class="search-page-form">
     
    99      name="q"
    1010      value="<%= query %>"
    11       placeholder="Zoek posts en nummers…"
     11      placeholder="<%= t('search.placeholder') %>"
    1212      autocomplete="off"
    1313      autofocus
    14       aria-label="Zoekopdracht">
    15     <button type="submit" class="btn btn-primary">Zoek</button>
     14      aria-label="<%= t('nav.search') %>">
     15    <button type="submit" class="btn btn-primary"><%= t('search.button') %></button>
    1616  </form>
    1717
    1818  <% if (queryError) { %>
    19     <p class="search-error">Kon die zoekopdracht niet uitvoeren. Probeer een eenvoudiger term.</p>
     19    <p class="search-error"><%= t('search.error') %></p>
    2020  <% } %>
    2121
    2222  <% if (query && !queryError) { %>
    2323    <p class="search-meta">
    24       <%= total %> resulta<%= total === 1 ? 'at' : 'ten' %> voor &ldquo;<%= query %>&rdquo;
     24      <%= t(total === 1 ? 'search.results_one' : 'search.results_other', { n: total, q: query }) %>
    2525    </p>
    2626  <% } %>
    2727
    2828  <% if (_tracks.length) { %>
    29     <h2 class="search-section-title">Nummers</h2>
     29    <h2 class="search-section-title"><%= t('search.section_tracks') %></h2>
    3030    <div class="search-tracks">
    3131      <% _tracks.forEach(function(t) {
     
    5656               hx-swap="innerHTML"
    5757               hx-push-url="<%= t.postUrl %>"
    58                aria-label="Open in post">in post →</a>
     58               aria-label="<%= t('search.in_post') %>"><%= t('search.in_post') %></a>
    5959          <% } %>
    6060        </div>
     
    6464
    6565  <% if (results && results.length) { %>
    66     <% if (_tracks.length) { %><h2 class="search-section-title">Posts</h2><% } %>
     66    <% if (_tracks.length) { %><h2 class="search-section-title"><%= t('search.section_posts') %></h2><% } %>
    6767    <ol class="search-results">
    6868      <% results.forEach(function(r) { %>
     
    8989
    9090  <% if (query && !queryError && !results.length && !_tracks.length) { %>
    91     <p class="search-empty">Niets gevonden.</p>
     91    <p class="search-empty"><%= t('search.empty') %></p>
    9292  <% } %>
    9393</div>
  • src/views/partials/like-button.ejs

    r137cca5 rfe86013  
    1818<% } else { %>
    1919  <a class="like-btn" href="/auth/login?next=<%= encodeURIComponent((typeof loginNext !== 'undefined' && loginNext) ? loginNext : '/') %>"
    20      title="Log in om deze post te liken">
     20     title="<%= t('like.login_title') %>">
    2121    <span class="like-heart" aria-hidden="true">♡</span>
    2222    <span class="like-count"><%= _cnt %></span>
Note: See TracChangeset for help on using the changeset viewer.