source: Klonkt/src/views/pages/admin-seo.ejs@ 013e16c

main
Last change on this file since 013e16c was 013e16c, checked in by Robin <roboburr@…>, 4 weeks ago

Naar SEO & social, want sameAs is schema.org (Robins vraag)

Hij vroeg of het niet onder SEO en social hoort, "omdat het ook een soort
koppeling is". Dat is het, en sterker dan dat: op die pagina staat een blok
"Uitgever (JSON-LD / rich results)", en sameAs IS een schema.org-eigenschap.
Zelfde vocabulaire, zelfde plek. Het paneel staat nu direct onder Uitgever.

DAARDOOR VOEDT EEN KOPPELING NU TWEE UITGANGEN. Naast schema:sameAs op de
fediverse-actor komt hij in de JSON-LD van de pagina zelf, in _publisher. Dat
is hetzelfde feit, verteld aan de andere lezer -- en het was gratis, want het
blok stond er al.

BETERE LABELS, want de oude waren geschreven voor het audioscherm. "Ben jij dit
in MusicBrainz?" werd "MusicBrainz (dezelfde artiest elders)" als legenda, met
een hint die zegt wat het OPLEVERT in plaats van alleen wat het is: je komt als
sameAs in de JSON-LD en in je fediverse-profiel, en er verandert niets bij
MusicBrainz zelf. Dat laatste is de geruststelling die er hoort te staan. Plus
een veldlabel ("Zoek jezelf op") met de toelichting "de naam waaronder je muziek
uitbrengt" -- want dat is de vraag, niet je sitenaam. Drie talen.

Het zoekveld begint nu op publisher_name en valt terug op de sitetitel: op deze
pagina heb je die naam net ingevuld.

Meeverhuisd: het endpoint (/admin/seo/api/musicbrainz) en het clientblok, in een
nieuwe mod/admin-seo.js. Die pagina had nog geen JavaScript; opzoeken vraagt er
wel om. Het profielscherm is weer helemaal schoon.

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

  • Property mode set to 100644
File size: 10.3 KB
Line 
1<div class="container admin-site-edit-page">
2 <p><a href="/admin" class="btn">&larr; <%= t('aseo.back') %></a></p>
3 <h1><%= t('aseo.title') %></h1>
4 <p class="admin-tagline"><%= t('aseo.tagline_pre') %> <strong><%= site.title %></strong> <%= t('aseo.tagline_post') %></p>
5
6 <% if (typeof success !== 'undefined' && success) { %><div class="audio-flash audio-flash--ok"><%= success %></div><% } %>
7 <% if (typeof error !== 'undefined' && error) { %><div class="audio-flash audio-flash--err"><%= error %></div><% } %>
8
9 <form method="post" action="/admin/seo" class="site-form">
10
11 <fieldset>
12 <legend><%= t('aseo.index_legend') %></legend>
13 <label class="cb">
14 <input type="checkbox" name="robots_index" value="1" <%= site.robots_index ? 'checked' : '' %>>
15 <span><%= t('aseo.index_label') %> <small class="form-hint-inline">— <%= t('aseo.index_hint_pre') %> <code>noindex</code> <%= t('aseo.index_hint_post') %></small></span>
16 </label>
17 </fieldset>
18
19 <fieldset>
20 <legend><%= t('aseo.title_legend') %></legend>
21 <label>
22 <span><%= t('aseo.title_template') %> <small class="form-hint-inline">— <%= t('aseo.title_template_hint_pre') %> <code>{title}</code> <%= t('aseo.title_template_hint_and') %> <code>{site}</code></small></span>
23 <input type="text" name="title_template" value="<%= site.title_template || '{title} — {site}' %>" maxlength="200" placeholder="{title} — {site}">
24 </label>
25 <label>
26 <span><%= t('aseo.default_desc') %> <small class="form-hint-inline">— <%= t('aseo.default_desc_hint') %></small></span>
27 <textarea name="default_description" rows="2" maxlength="500" placeholder="<%= t('aseo.default_desc_ph') %>"><%= site.default_description || '' %></textarea>
28 </label>
29 <label>
30 <span><%= t('aseo.canonical') %> <small class="form-hint-inline">— <%= t('aseo.canonical_hint') %></small></span>
31 <input type="text" name="canonical" value="<%= site.canonical || '' %>" placeholder="https://yourdomain.com" maxlength="200">
32 </label>
33 <label>
34 <span><%= t('aseo.author') %> <small class="form-hint-inline">— <%= t('aseo.author_hint') %></small></span>
35 <input type="text" name="author" value="<%= site.author || '' %>" maxlength="120" placeholder="<%= t('aseo.author_ph') %>">
36 </label>
37 </fieldset>
38
39 <fieldset>
40 <legend><%= t('aseo.social_legend') %></legend>
41 <label>
42 <span><%= t('aseo.og_image') %> <small class="form-hint-inline">— <%= t('aseo.og_image_hint') %></small></span>
43 <input type="text" name="og_image_default" value="<%= site.og_image_default || '' %>" placeholder="https://yourdomain.com/share.jpg" maxlength="500">
44 </label>
45 <label>
46 <span><%= t('aseo.og_theme') %> <small class="form-hint-inline">— <%= t('aseo.og_theme_hint') %></small></span>
47 <select name="og_theme">
48 <option value="" <%= !site.og_theme ? 'selected' : '' %>><%= t('aseo.og_theme_auto') %></option>
49 <option value="light" <%= site.og_theme === 'light' ? 'selected' : '' %>><%= t('aseo.og_theme_light') %></option>
50 <option value="dark" <%= site.og_theme === 'dark' ? 'selected' : '' %>><%= t('aseo.og_theme_dark') %></option>
51 </select>
52 </label>
53 <label>
54 <span><%= t('aseo.og_locale') %> <small class="form-hint-inline">— <%= t('aseo.og_locale_hint_pre') %> <code>nl_NL</code> <%= t('aseo.og_locale_hint_or') %> <code>en_US</code></small></span>
55 <input type="text" name="og_locale" value="<%= site.og_locale || '' %>" placeholder="nl_NL" maxlength="32">
56 </label>
57 <label>
58 <span><%= t('aseo.twitter') %> <small class="form-hint-inline">— <%= t('aseo.twitter_hint') %></small></span>
59 <input type="text" name="twitter" value="<%= site.twitter || '' %>" placeholder="@jouwnaam" maxlength="64">
60 </label>
61 <label>
62 <span><%= t('aseo.fb_app') %> <small class="form-hint-inline">— <%= t('aseo.fb_app_hint') %></small></span>
63 <input type="text" name="facebook_app_id" value="<%= site.facebook_app_id || '' %>" maxlength="64">
64 </label>
65 </fieldset>
66
67 <fieldset>
68 <legend><%= t('aseo.publisher_legend') %></legend>
69 <label>
70 <span><%= t('aseo.type') %></span>
71 <select name="schema_type">
72 <option value="Person" <%= site.schema_type === 'Organization' ? '' : 'selected' %>><%= t('aseo.type_person') %></option>
73 <option value="Organization" <%= site.schema_type === 'Organization' ? 'selected' : '' %>><%= t('aseo.type_org') %></option>
74 </select>
75 </label>
76 <label>
77 <span><%= t('aseo.publisher_name') %> <small class="form-hint-inline">— <%= t('aseo.publisher_name_hint') %></small></span>
78 <input type="text" name="publisher_name" value="<%= site.publisher_name || '' %>" maxlength="200">
79 </label>
80 <label>
81 <span><%= t('aseo.publisher_url') %></span>
82 <input type="text" name="publisher_url" value="<%= site.publisher_url || '' %>" placeholder="https://yourdomain.com" maxlength="200">
83 </label>
84 <label>
85 <span><%= t('aseo.publisher_logo') %></span>
86 <input type="text" name="publisher_logo" value="<%= site.publisher_logo || '' %>" placeholder="https://yourdomain.com/logo.png" maxlength="500">
87 </label>
88 </fieldset>
89
90 <%# ── MUSICBRAINZ ─────────────────────────────────────────────
91 Direct onder Uitgever, en dat is geen willekeur: sameAs IS een
92 schema.org-eigenschap, en dat blok hierboven is waar ons schema.org
93 vandaan komt. Een koppeling hier voedt twee uitgangen tegelijk -- de
94 JSON-LD van de pagina en het fediverse-profiel (shaer-mbz). %>
95 <fieldset id="mb-veld">
96 <legend><%= t('aseo.mb_legend') %></legend>
97 <p class="form-hint"><%= t('aseo.mb_hint') %></p>
98
99 <input type="hidden" name="mb_artist_id" id="mb-id" value="<%= site.mb_artist_id || '' %>">
100 <input type="hidden" name="mb_artist_name" id="mb-naam" value="<%= site.mb_artist_name || '' %>">
101
102 <p class="mb-huidig" id="mb-huidig" <%= site.mb_artist_id ? '' : 'hidden' %>>
103 <%= t('aseo.mb_linked') %>
104 <strong id="mb-huidig-naam"><%= site.mb_artist_name || site.mb_artist_id || '' %></strong>
105 <a id="mb-huidig-link" target="_blank" rel="noopener"
106 href="https://musicbrainz.org/artist/<%= site.mb_artist_id || '' %>"><%= t('aseo.mb_open') %></a>
107 <button type="button" class="btn" id="mb-wis"><%= t('aseo.mb_unlink') %></button>
108 </p>
109
110 <label>
111 <span><%= t('aseo.mb_search_label') %> <small class="form-hint-inline">— <%= t('aseo.mb_search_hint') %></small></span>
112 <div class="mb-zoek">
113 <input type="text" id="mb-q" value="<%= site.publisher_name || site.title || '' %>"
114 autocomplete="off" placeholder="<%= t('aseo.mb_placeholder') %>">
115 <button type="button" class="btn" id="mb-zoek-btn"><%= t('aseo.mb_search') %></button>
116 </div>
117 </label>
118 <div id="mb-uit" class="mb-uit" hidden></div>
119 </fieldset>
120
121 <fieldset>
122 <legend><%= t('aseo.verify_legend') %></legend>
123 <label>
124 <span><%= t('aseo.verify_google') %></span>
125 <input type="text" name="google_verification" value="<%= site.google_verification || '' %>" maxlength="200">
126 </label>
127 <label>
128 <span><%= t('aseo.verify_bing') %> <small class="form-hint-inline">— <%= t('aseo.verify_bing_hint') %></small></span>
129 <input type="text" name="bing_verification" value="<%= site.bing_verification || '' %>" maxlength="200">
130 </label>
131 <label>
132 <span><%= t('aseo.verify_pinterest') %> <small class="form-hint-inline">— <%= t('aseo.verify_pinterest_hint') %></small></span>
133 <input type="text" name="pinterest_verification" value="<%= site.pinterest_verification || '' %>" maxlength="200">
134 </label>
135 <label>
136 <span><%= t('aseo.verify_yandex') %></span>
137 <input type="text" name="yandex_verification" value="<%= site.yandex_verification || '' %>" maxlength="200">
138 </label>
139 </fieldset>
140
141 <button type="submit" class="btn btn-primary"><%= t('aseo.save') %></button>
142 </form>
143</div>
144
145<style>
146.admin-site-edit-page { max-width: 760px; margin: 3rem auto; padding: 0 1rem; }
147.admin-site-edit-page h1 { font-family: var(--font-display, serif); font-size: 1.8rem; margin: 0 0 0.4rem; }
148.admin-site-edit-page .admin-tagline { color: var(--ink-muted); margin: 0 0 1.75rem; }
149
150.site-form { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
151/* <fieldset> does not shrink because the UA sets min-inline-size:min-content → mobile overflow.
152 min-width:0 forces it to shrink. */
153.site-form fieldset { min-width: 0; }
154.site-form input, .site-form textarea, .site-form select { min-width: 0; }
155.site-form fieldset {
156 border: 1px solid var(--rule);
157 border-radius: 8px;
158 padding: 1rem 1.25rem;
159 background: var(--paper-2);
160 display: flex;
161 flex-direction: column;
162 gap: 0.85rem;
163}
164.site-form fieldset legend { font-family: var(--font-display, serif); font-size: 1rem; padding: 0 0.4rem; }
165.site-form label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; color: var(--ink-muted, var(--ink-soft)); }
166.site-form label.cb { flex-direction: row; align-items: flex-start; gap: 0.55rem; font-size: 0.9rem; color: var(--ink); }
167.site-form label.cb input { margin-top: 0.15rem; }
168.site-form label > span { line-height: 1.35; }
169.form-hint-inline { font-weight: 400; color: var(--ink-muted); font-size: 0.82em; }
170.site-form code { background: var(--paper); padding: 0.05rem 0.35rem; border-radius: 3px; font-size: 0.85em; }
171.site-form input[type="text"], .site-form textarea, .site-form select {
172 padding: 0.55rem 0.85rem;
173 border: 1px solid var(--rule);
174 border-radius: 5px;
175 background: var(--paper);
176 color: var(--ink);
177 font-family: inherit;
178 font-size: 0.95rem;
179 width: 100%;
180 box-sizing: border-box;
181}
182.site-form textarea { resize: vertical; min-height: 2.6rem; }
183.site-form select { max-width: 320px; }
184.site-form input:focus, .site-form textarea:focus, .site-form select:focus {
185 outline: none; border-color: var(--accent);
186}
187.seo-pointer p { margin: 0; font-size: 0.9rem; color: var(--ink-muted); }
188.seo-pointer a { color: var(--accent); font-weight: 600; }
189.site-form > button[type="submit"] { align-self: flex-start; }
190</style>
Note: See TracBrowser for help on using the repository browser.