Changeset 4885eab in Klonkt for src/views/pages/post-edit.ejs
- Timestamp:
- 06/21/2026 03:05:14 PM (3 months ago)
- Branches:
- main
- Children:
- 5e61b17
- Parents:
- bbf9d1a
- File:
-
- 1 edited
-
src/views/pages/post-edit.ejs (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/views/pages/post-edit.ejs
rbbf9d1a r4885eab 15 15 %> 16 16 <div class="container post-edit-page"> 17 <h1><%= isNew ? 'Nieuwe post' : 'Post bewerken'%></h1>17 <h1><%= isNew ? t('pedit.title_new') : t('pedit.title_edit') %></h1> 18 18 19 19 <form method="post" action="<%= _base %><%= isNew ? '/posts/create' : '/posts/' + post.slug + '/save' %>" class="post-edit-form"> … … 22 22 <section class="pe-card"> 23 23 <label class="pe-field"> 24 <span> Titel</span>24 <span><%= t('pedit.f_title') %></span> 25 25 <input type="text" name="title" value="<%= post.title %>" required> 26 26 </label> 27 27 <div class="pe-row pe-row-2"> 28 28 <label class="pe-field"> 29 <span> Slug (URL)</span>30 <input type="text" name="slug" value="<%= post.slug %>" placeholder=" auto van titel als leeg">29 <span><%= t('pedit.f_slug') %></span> 30 <input type="text" name="slug" value="<%= post.slug %>" placeholder="<%= t('pedit.slug_placeholder') %>"> 31 31 </label> 32 32 <label class="pe-field"> 33 <span> Tags <small>(komma-gescheiden)</small></span>33 <span><%= t('pedit.f_tags') %> <small><%= t('pedit.tags_hint') %></small></span> 34 34 <input type="text" name="tags" value="<%= Array.isArray(post.tags) ? post.tags.join(', ') : '' %>"> 35 35 </label> 36 36 </div> 37 37 <label class="pe-field"> 38 <span> Samenvatting & Cirkel Preview</span>38 <span><%= t('pedit.f_excerpt') %></span> 39 39 <textarea name="excerpt" rows="2"><%= post.excerpt %></textarea> 40 <small class="pe-hint" style="opacity:.7"> Wordt ook gebruikt als samenvatting in <strong>Cirkels</strong> (andere sites die je post tonen). Leeg laten = begin van de post.</small>40 <small class="pe-hint" style="opacity:.7"><%- t('pedit.excerpt_hint') %></small> 41 41 </label> 42 42 </section> … … 44 44 <%# ── COVER ────────────────────────────────────────────────── %> 45 45 <section class="pe-card"> 46 <div class="pe-section-title"> Cover</div>46 <div class="pe-section-title"><%= t('pedit.s_cover') %></div> 47 47 <div class="pe-cover-row"> 48 48 <div class="pe-cover-thumb" id="cover-preview-wrap" <%= _hasCover ? '' : 'data-empty' %>> … … 52 52 <div class="pe-cover-actions"> 53 53 <label class="pe-field"> 54 <span> Cover URL</span>54 <span><%= t('pedit.f_cover_url') %></span> 55 55 <input type="text" name="cover_image_url" id="cover-url-field" 56 56 value="<%= post.cover_image_url || '' %>" 57 57 inputmode="url" autocapitalize="none" spellcheck="false" 58 placeholder=" /media/… of https://… (of upload met de knop)">58 placeholder="<%= t('pedit.cover_url_placeholder') %>"> 59 59 </label> 60 60 <div class="pe-cover-upload"> 61 61 <button type="button" class="pe-btn pe-btn-secondary" id="cover-upload-trigger"> 62 📷 Upload nieuwe cover62 📷 <%= t('pedit.cover_upload_btn') %> 63 63 </button> 64 64 <input type="file" id="cover-upload-field" accept="image/jpeg,image/png,image/webp,image/gif" hidden> … … 72 72 <section class="pe-card pe-card-content"> 73 73 <div class="pe-section-title"> 74 Content75 <small class="pe-content-hint"> Sleep een afbeelding om in te voegen · selecteer tekst om op te maken</small>74 <%= t('pedit.s_content') %> 75 <small class="pe-content-hint"><%= t('pedit.content_hint') %></small> 76 76 </div> 77 77 <div class="pe-editor-frame"> 78 78 <div class="pe-toolbar" id="pe-toolbar" role="toolbar" aria-label="Format"> 79 <button type="button" id="pe-fs-done" class="pe-fs-done" title=" Klaar met bewerken">✓ Klaar</button>80 <button type="button" data-cmd="bold" title=" Vet (Ctrl+B)" aria-label="Vet">79 <button type="button" id="pe-fs-done" class="pe-fs-done" title="<%= t('pedit.tb_done_title') %>">✓ <%= t('pedit.tb_done') %></button> 80 <button type="button" data-cmd="bold" title="<%= t('pedit.tb_bold_title') %>" aria-label="<%= t('pedit.tb_bold') %>"> 81 81 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4h8a4 4 0 0 1 0 8H6z"/><path d="M6 12h9a4 4 0 0 1 0 8H6z"/></svg> 82 82 </button> 83 <button type="button" data-cmd="italic" title=" Cursief (Ctrl+I)" aria-label="Cursief">83 <button type="button" data-cmd="italic" title="<%= t('pedit.tb_italic_title') %>" aria-label="<%= t('pedit.tb_italic') %>"> 84 84 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg> 85 85 </button> 86 <button type="button" data-cmd="underline" title=" Onderstreept" aria-label="Onderstreept">86 <button type="button" data-cmd="underline" title="<%= t('pedit.tb_underline') %>" aria-label="<%= t('pedit.tb_underline') %>"> 87 87 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" y1="20" x2="20" y2="20"/></svg> 88 88 </button> 89 89 <span class="pe-toolbar-sep" aria-hidden="true"></span> 90 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="h2" title=" Kop">H2</button>91 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="h3" title=" Subkop">H3</button>92 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="p" title=" Paragraaf">¶</button>90 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="h2" title="<%= t('pedit.tb_h2') %>">H2</button> 91 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="h3" title="<%= t('pedit.tb_h3') %>">H3</button> 92 <button type="button" class="pe-tb-text" data-cmd="formatBlock" data-arg="p" title="<%= t('pedit.tb_p') %>">¶</button> 93 93 <span class="pe-toolbar-sep" aria-hidden="true"></span> 94 <button type="button" data-cmd="insertUnorderedList" title=" Lijst" aria-label="Lijst">94 <button type="button" data-cmd="insertUnorderedList" title="<%= t('pedit.tb_ul') %>" aria-label="<%= t('pedit.tb_ul') %>"> 95 95 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="9" y1="6" x2="20" y2="6"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="18" x2="20" y2="18"/><circle cx="4.5" cy="6" r="1.2"/><circle cx="4.5" cy="12" r="1.2"/><circle cx="4.5" cy="18" r="1.2"/></svg> 96 96 </button> 97 <button type="button" data-cmd="insertOrderedList" title=" Genummerde lijst" aria-label="Genummerde lijst">97 <button type="button" data-cmd="insertOrderedList" title="<%= t('pedit.tb_ol') %>" aria-label="<%= t('pedit.tb_ol') %>"> 98 98 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/></svg> 99 99 </button> 100 <button type="button" data-cmd="formatBlock" data-arg="blockquote" title=" Quote" aria-label="Quote">100 <button type="button" data-cmd="formatBlock" data-arg="blockquote" title="<%= t('pedit.tb_quote') %>" aria-label="<%= t('pedit.tb_quote') %>"> 101 101 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.75-2-2-2H4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h2.5C6 17.5 4 19 3 19v2z"/><path d="M14 21c3 0 7-1 7-8V5c0-1.25-.75-2-2-2h-4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h2.5c-.5 4.5-2.5 6-3.5 6v2z"/></svg> 102 102 </button> 103 <button type="button" data-cmd="link-prompt" title=" Link (Ctrl+K)" aria-label="Link">103 <button type="button" data-cmd="link-prompt" title="<%= t('pedit.tb_link_title') %>" aria-label="<%= t('pedit.tb_link') %>"> 104 104 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg> 105 105 </button> 106 <button type="button" data-cmd="code-wrap" title=" Code (inline)" aria-label="Code">106 <button type="button" data-cmd="code-wrap" title="<%= t('pedit.tb_code_title') %>" aria-label="<%= t('pedit.tb_code') %>"> 107 107 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg> 108 108 </button> 109 109 <span class="pe-toolbar-sep" aria-hidden="true"></span> 110 <button type="button" id="insert-image-btn" title=" Afbeelding invoegen" aria-label="Afbeelding">110 <button type="button" id="insert-image-btn" title="<%= t('pedit.tb_image_title') %>" aria-label="<%= t('pedit.tb_image') %>"> 111 111 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="M21 15l-5-5L5 21"/></svg> 112 112 </button> 113 <button type="button" id="insert-track-btn" title=" Track invoegen" aria-label="Track">113 <button type="button" id="insert-track-btn" title="<%= t('pedit.tb_track_title') %>" aria-label="<%= t('pedit.tb_track') %>"> 114 114 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg> 115 115 </button> 116 <button type="button" id="insert-playlist-btn" title=" Playlist invoegen" aria-label="Playlist">116 <button type="button" id="insert-playlist-btn" title="<%= t('pedit.tb_playlist_title') %>" aria-label="<%= t('pedit.tb_playlist') %>"> 117 117 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="15" y2="18"/><polygon points="3 5 3 13 9 9"/></svg> 118 118 </button> 119 <button type="button" id="insert-embed-btn" title=" Embed (YouTube, Spotify, SoundCloud, Vimeo…)" aria-label="Media embedden">119 <button type="button" id="insert-embed-btn" title="<%= t('pedit.tb_embed_title') %>" aria-label="<%= t('pedit.tb_embed') %>"> 120 120 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><polygon points="10 9 15.5 12 10 15"/></svg> 121 121 </button> 122 122 <span class="pe-toolbar-spacer"></span> 123 <button type="button" data-cmd="removeFormat" title=" Wis opmaak" aria-label="Wis opmaak">123 <button type="button" data-cmd="removeFormat" title="<%= t('pedit.tb_clear') %>" aria-label="<%= t('pedit.tb_clear') %>"> 124 124 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7V4h16v3"/><path d="M9 20h6"/><path d="M5 5l14 14" stroke-linecap="round"/></svg> 125 125 </button> 126 <button type="button" id="pe-fullscreen-btn" title=" Volledig scherm" aria-label="Volledig scherm" aria-pressed="false">126 <button type="button" id="pe-fullscreen-btn" title="<%= t('pedit.tb_fullscreen') %>" aria-label="<%= t('pedit.tb_fullscreen') %>" aria-pressed="false"> 127 127 <svg class="fs-icon-expand" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg> 128 128 <svg class="fs-icon-compress" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" y1="10" x2="21" y2="3"/><line x1="3" y1="21" x2="10" y2="14"/></svg> … … 135 135 role="textbox" 136 136 aria-multiline="true" 137 aria-label=" Content"138 data-placeholder=" Begin met schrijven…"></div>137 aria-label="<%= t('pedit.editor_aria') %>" 138 data-placeholder="<%= t('pedit.editor_placeholder') %>"></div> 139 139 140 140 <%# Sticky "tik om te bewerken"-hint (alleen zichtbaar op touch + niet-fullscreen 141 141 via CSS). Puur visueel (pointer-events:none); de tik op het veld opent fullscreen. %> 142 <div class="pe-edit-hint" aria-hidden="true">✎ Tik om te bewerken</div>142 <div class="pe-edit-hint" aria-hidden="true">✎ <%= t('pedit.tap_to_edit') %></div> 143 143 144 144 <%# Hidden field is what actually submits to the server. The visible … … 153 153 <div class="pe-editor-status"> 154 154 <small id="content-upload-status" class="pe-status"></small> 155 <span class="pe-char-count"><span id="char-count">0</span> tekens</span>155 <span class="pe-char-count"><span id="char-count">0</span> <%= t('pedit.chars') %></span> 156 156 </div> 157 157 … … 162 162 <%# ── META ─────────────────────────────────────────────────── %> 163 163 <section class="pe-card"> 164 <div class="pe-section-title"> Publicatie</div>164 <div class="pe-section-title"><%= t('pedit.s_publication') %></div> 165 165 <div class="pe-row pe-row-2"> 166 166 <label class="pe-field"> 167 <span> Status</span>167 <span><%= t('pedit.f_status') %></span> 168 168 <% var _st = isNew ? 'published' : (post.status || 'draft'); %> 169 169 <select name="status"> 170 <option value="published" <%= _st === 'published' ? 'selected' : '' %>> Gepubliceerd</option>171 <option value="draft" <%= _st === 'draft' ? 'selected' : '' %>> Concept</option>172 <option value="archived" <%= _st === 'archived' ? 'selected' : '' %>> Gearchiveerd</option>170 <option value="published" <%= _st === 'published' ? 'selected' : '' %>><%= t('pedit.status_published') %></option> 171 <option value="draft" <%= _st === 'draft' ? 'selected' : '' %>><%= t('pedit.status_draft') %></option> 172 <option value="archived" <%= _st === 'archived' ? 'selected' : '' %>><%= t('pedit.status_archived') %></option> 173 173 </select> 174 174 </label> 175 175 <label class="pe-field"> 176 <span> Type</span>176 <span><%= t('pedit.f_type') %></span> 177 177 <select name="type"> 178 178 <% var ptype = post.type || 'post'; %> 179 <option value="post" <%= ptype === 'post' ? 'selected' : '' %>> Post</option>180 <option value="foto" <%= ptype === 'foto' ? 'selected' : '' %>> Foto</option>181 <option value="video" <%= ptype === 'video' ? 'selected' : '' %>> Video</option>182 <option value="audio" <%= ptype === 'audio' ? 'selected' : '' %>> Audio</option>179 <option value="post" <%= ptype === 'post' ? 'selected' : '' %>><%= t('pedit.type_post') %></option> 180 <option value="foto" <%= ptype === 'foto' ? 'selected' : '' %>><%= t('pedit.type_foto') %></option> 181 <option value="video" <%= ptype === 'video' ? 'selected' : '' %>><%= t('pedit.type_video') %></option> 182 <option value="audio" <%= ptype === 'audio' ? 'selected' : '' %>><%= t('pedit.type_audio') %></option> 183 183 </select> 184 184 </label> … … 188 188 <label class="pe-checkbox"> 189 189 <input type="checkbox" id="pin-toggle" <%= (Number(post.pinned) > 0) ? 'checked' : '' %>> 190 <span>📌 Vastpinnen bovenaan</span>190 <span>📌 <%= t('pedit.pin_label') %></span> 191 191 </label> 192 192 <input type="hidden" name="pinned" id="pin-rank" value="<%= post.pinned || 0 %>"> 193 193 <div class="pe-pin-pos" id="pin-pos" <%= (Number(post.pinned) > 0) ? '' : 'hidden' %>> 194 194 <span class="pe-pin-steps"> 195 <button type="button" class="pe-pin-btn" id="pin-up" aria-label=" Hoger zetten">▲</button>196 <button type="button" class="pe-pin-btn" id="pin-down" aria-label=" Lager zetten">▼</button>195 <button type="button" class="pe-pin-btn" id="pin-up" aria-label="<%= t('pedit.pin_up') %>">▲</button> 196 <button type="button" class="pe-pin-btn" id="pin-down" aria-label="<%= t('pedit.pin_down') %>">▼</button> 197 197 </span> 198 198 <span class="pe-pin-label" id="pin-label"></span> … … 201 201 <label class="pe-checkbox"> 202 202 <input type="checkbox" name="noindex" value="1" <%= post.noindex ? 'checked' : '' %>> 203 <span>🚫 noindex (verberg voor zoekmachines)</span>203 <span>🚫 <%= t('pedit.noindex_label') %></span> 204 204 </label> 205 205 <% if (typeof premiumUnlocked === 'undefined' || premiumUnlocked) { %> 206 206 <label class="pe-checkbox"> 207 207 <input type="checkbox" name="fan_only" value="1" <%= post.fan_only ? 'checked' : '' %>> 208 <span>🔒 Alleen voor ingelogde fans</span>208 <span>🔒 <%= t('pedit.fan_only_label') %></span> 209 209 </label> 210 210 <div style="margin-top:8px"> 211 <label style="display:block;font-size:12.5px;opacity:.8;margin-bottom:4px">📅 Publiceren op (laat leeg = direct)</label>211 <label style="display:block;font-size:12.5px;opacity:.8;margin-bottom:4px">📅 <%= t('pedit.publish_at_label') %></label> 212 212 <input type="datetime-local" name="publish_at" value="<%= post.publish_at ? String(post.publish_at).replace(' ','T').slice(0,16) : '' %>" style="padding:8px 10px;border-radius:8px;border:1px solid var(--rule,rgba(128,128,128,.4));background:transparent;color:inherit"> 213 <% if (post.status === 'scheduled' && post.publish_at) { %><div style="font-size:12px;opacity:.7;margin-top:4px">⏳ Ingepland voor <%= post.publish_at%></div><% } %>213 <% if (post.status === 'scheduled' && post.publish_at) { %><div style="font-size:12px;opacity:.7;margin-top:4px">⏳ <%= t('pedit.scheduled_for', { d: post.publish_at }) %></div><% } %> 214 214 </div> 215 215 <% } %> … … 219 219 <%# ── ACTIONS (sticky at bottom) ──────────────────────────── %> 220 220 <div class="pe-actions"> 221 <a href="<%= _base %><%= isNew ? '/' : '/' + post.slug %>" class="pe-btn"> Annuleren</a>221 <a href="<%= _base %><%= isNew ? '/' : '/' + post.slug %>" class="pe-btn"><%= t('pedit.cancel') %></a> 222 222 <div class="pe-actions-spacer"></div> 223 223 <% if (!isNew && post.status !== 'published') { %> 224 <button type="submit" name="action" value="publish" class="pe-btn pe-btn-success">📤 Publish</button>224 <button type="submit" name="action" value="publish" class="pe-btn pe-btn-success">📤 <%= t('pedit.publish') %></button> 225 225 <% } %> 226 <button type="submit" class="pe-btn pe-btn-primary">💾 Opslaan</button>226 <button type="submit" class="pe-btn pe-btn-primary">💾 <%= t('pedit.save') %></button> 227 227 </div> 228 228 </form> … … 983 983 if (!coverField.files[0]) return; 984 984 coverStatus.classList.remove('is-error'); 985 coverStatus.textContent = ' Uploaden…';985 coverStatus.textContent = '<%= t('pedit.js_uploading') %>'; 986 986 try { 987 987 const j = await uploadImage(coverField.files[0]); 988 988 coverUrl.value = j.url; 989 989 showCoverPreview(j.url); 990 coverStatus.textContent = ' Geüpload✓';990 coverStatus.textContent = '<%= t('pedit.js_uploaded') %> ✓'; 991 991 setTimeout(() => { coverStatus.textContent = ''; }, 2000); 992 992 } catch (e) { 993 993 coverStatus.classList.add('is-error'); 994 coverStatus.textContent = ' Mislukt: ' + e.message;994 coverStatus.textContent = '<%= t('pedit.js_failed') %>: ' + e.message; 995 995 } 996 996 }); … … 1053 1053 // UUIDs are noisy — show a 6-char prefix for visual hint 1054 1054 const v = String(value || ''); 1055 return ' Track' + (v.length > 8 ? v.slice(0, 6) + '…' : v);1056 } 1057 if (kind === 'album') return ' Album:' + value;1058 if (kind === 'playlist') return ' Playlist:' + value;1055 return '<%= t('pedit.chip_track') %> ' + (v.length > 8 ? v.slice(0, 6) + '…' : v); 1056 } 1057 if (kind === 'album') return '<%= t('pedit.chip_album') %> ' + value; 1058 if (kind === 'playlist') return '<%= t('pedit.chip_playlist') %> ' + value; 1059 1059 if (kind === 'embed') { 1060 1060 const clean = String(value || '').replace(/^https?:\/\/(www\.)?/, ''); … … 1187 1187 } 1188 1188 function linkPrompt() { 1189 const url = window.prompt(' Link URL (https://… of /pad)');1189 const url = window.prompt('<%= t('pedit.js_link_prompt') %>'); 1190 1190 if (!url) return; 1191 1191 execCmd('createLink', url); … … 1288 1288 if (fsBtn) { 1289 1289 fsBtn.setAttribute('aria-pressed', on ? 'true' : 'false'); 1290 fsBtn.title = on ? ' Klaar' : 'Volledig scherm';1290 fsBtn.title = on ? '<%= t('pedit.tb_done') %>' : '<%= t('pedit.tb_fullscreen') %>'; 1291 1291 } 1292 1292 if (window.visualViewport) { … … 1342 1342 editor.setAttribute('contenteditable', 'false'); 1343 1343 editor.classList.add('pe-tap-to-edit'); 1344 editor.setAttribute('data-placeholder', ' Tik om te schrijven…');1344 editor.setAttribute('data-placeholder', '<%= t('pedit.tap_to_write') %>'); 1345 1345 editor.addEventListener('click', function () { 1346 1346 if (!isFs()) openFs(); … … 1390 1390 async function uploadAndInsertImage(file) { 1391 1391 contentStatus.classList.remove('is-error'); 1392 contentStatus.textContent = ' Uploaden…';1392 contentStatus.textContent = '<%= t('pedit.js_uploading') %>'; 1393 1393 try { 1394 1394 const j = await uploadImage(file); … … 1396 1396 editor.focus({ preventScroll: true }); 1397 1397 document.execCommand('insertHTML', false, img); 1398 contentStatus.textContent = ' Ingevoegd✓';1398 contentStatus.textContent = '<%= t('pedit.js_inserted') %> ✓'; 1399 1399 setTimeout(() => { contentStatus.textContent = ''; }, 2000); 1400 1400 updateCharCount(); 1401 1401 } catch (e) { 1402 1402 contentStatus.classList.add('is-error'); 1403 contentStatus.textContent = ' Mislukt: ' + e.message;1403 contentStatus.textContent = '<%= t('pedit.js_failed') %>: ' + e.message; 1404 1404 } 1405 1405 } … … 1459 1459 if (embedBtn) { 1460 1460 embedBtn.addEventListener('click', () => { 1461 const raw = window.prompt(' Plak een media-URL om in te sluiten\n(YouTube, Spotify, SoundCloud, Vimeo, Apple Music, Bandcamp):');1461 const raw = window.prompt('<%= t('pedit.js_embed_prompt') %>'); 1462 1462 if (!raw) return; 1463 1463 const url = raw.trim(); 1464 if (!/^https?:\/\//i.test(url)) { alert(' Geef een volledige URL (https://…).'); return; }1464 if (!/^https?:\/\//i.test(url)) { alert('<%= t('pedit.js_embed_invalid') %>'); return; } 1465 1465 insertChip('embed', url); 1466 1466 }); … … 1501 1501 if (!filtered.length) { 1502 1502 tpList.innerHTML = ''; 1503 tpEmpty.textContent = q ? ' Geen tracks gevonden voor "' + q + '"' : 'Nog geen tracks. Upload via Beheer → Audio.';1503 tpEmpty.textContent = q ? '<%= t('pedit.js_no_tracks_found') %> ' + q : '<%= t('pedit.js_no_tracks_yet') %>'; 1504 1504 tpList.appendChild(tpEmpty); 1505 1505 return; … … 1527 1527 async function loadTracks() { 1528 1528 if (Array.isArray(tpCache)) return tpCache; 1529 tpEmpty.textContent = ' Tracks laden…';1529 tpEmpty.textContent = '<%= t('pedit.js_tracks_loading') %>'; 1530 1530 try { 1531 1531 const r = await fetch('/admin/playlists/api/tracks', { credentials: 'same-origin' }); … … 1534 1534 } catch (e) { 1535 1535 tpCache = []; 1536 tpEmpty.textContent = ' Kon tracks niet laden: ' + e.message;1536 tpEmpty.textContent = '<%= t('pedit.js_tracks_load_fail') %>: ' + e.message; 1537 1537 } 1538 1538 return tpCache; … … 1596 1596 playlistBtn.addEventListener('click', async () => { 1597 1597 if (typeof window.openPlaylistEditor !== 'function') { 1598 alert(' Playlist editor niet geladen');1598 alert('<%= t('pedit.js_playlist_editor_missing') %>'); 1599 1599 return; 1600 1600 } … … 1604 1604 if (j.ok && Array.isArray(j.playlists) && j.playlists.length > 0) { 1605 1605 const choice = prompt( 1606 ' Bestaande playlists:\n\n' +1606 '<%= t('pedit.js_playlist_existing') %>\n\n' + 1607 1607 j.playlists.map((p, i) => `${i + 1}. ${p.title} (${p.track_count} tracks)`).join('\n') + 1608 '\n\n Kies een nummer om in te voegen, leeg = nieuwe maken:'1608 '\n\n<%= t('pedit.js_playlist_choose') %>' 1609 1609 ); 1610 1610 if (choice && /^\d+$/.test(choice.trim())) { … … 1644 1644 <div class="tp-sheet" role="dialog" aria-modal="true" aria-labelledby="tp-title"> 1645 1645 <header class="tp-header"> 1646 <h2 id="tp-title" class="tp-h2"> Track invoegen</h2>1647 <button type="button" class="tp-close" data-tp-close aria-label=" Sluiten">1646 <h2 id="tp-title" class="tp-h2"><%= t('pedit.tp_title') %></h2> 1647 <button type="button" class="tp-close" data-tp-close aria-label="<%= t('pedit.tp_close') %>"> 1648 1648 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> 1649 1649 </button> … … 1653 1653 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg> 1654 1654 </span> 1655 <input type="search" class="tp-search" id="tp-search" placeholder=" Zoek op titel of artiest…" autocomplete="off" inputmode="search">1655 <input type="search" class="tp-search" id="tp-search" placeholder="<%= t('pedit.tp_search_placeholder') %>" autocomplete="off" inputmode="search"> 1656 1656 </div> 1657 <div class="tp-list" id="tp-list" role="listbox" aria-label=" Tracks">1658 <div class="tp-empty" id="tp-empty"> Tracks laden…</div>1657 <div class="tp-list" id="tp-list" role="listbox" aria-label="<%= t('pedit.tp_list_aria') %>"> 1658 <div class="tp-empty" id="tp-empty"><%= t('pedit.js_tracks_loading') %></div> 1659 1659 </div> 1660 1660 </div> … … 1682 1682 function descr(n) { 1683 1683 n = Number(n) || 0; 1684 if (n <= 1) return ' bovenaan';1685 return n + ' e van boven';1684 if (n <= 1) return '<%= t('pedit.pin_top') %>'; 1685 return n + '<%= t('pedit.pin_nth_suffix') %>'; 1686 1686 } 1687 1687 function render() {
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)