| [7bc636b] | 1 | <!-- Profile header (v9 structure)
|
|---|
| 2 | Body class controls collapse:
|
|---|
| 3 | .on-home → full size, avatar + bio + links
|
|---|
| 4 | .on-post → compact, just avatar + name
|
|---|
| 5 | .on-special → compact (archive/search/tag pages)
|
|---|
| 6 | .on-admin → hidden (admin pages don't show profile)
|
|---|
| 7 | -->
|
|---|
| 8 |
|
|---|
| 9 | <%
|
|---|
| 10 | // Show profile-header unless we're on an admin page or the site explicitly
|
|---|
| 11 | // disabled it via profile_enabled=0.
|
|---|
| 12 | const _showProfile = site
|
|---|
| 13 | && (site.profile_enabled === undefined || site.profile_enabled !== 0)
|
|---|
| 14 | && !(typeof bodyClass !== 'undefined' && bodyClass.indexOf('on-admin') >= 0);
|
|---|
| 15 |
|
|---|
| 16 | // profile_name and profile_bio used to be optional overrides exposed in the
|
|---|
| 17 | // admin form. P62 removed those form fields — title and description are the
|
|---|
| 18 | // single source of truth. We still consult the override columns first for
|
|---|
| 19 | // backward compat with any legacy data, but the form no longer writes them.
|
|---|
| 20 | const _displayName = (site && (site.profile_name || site.title)) || '';
|
|---|
| 21 | const _bioText = (site && (site.profile_bio || site.description || site.tagline)) || '';
|
|---|
| 22 |
|
|---|
| 23 | // Parse profile_links JSON column once.
|
|---|
| 24 | let _profileLinks = [];
|
|---|
| 25 | if (site && site.profile_links) {
|
|---|
| 26 | try { _profileLinks = JSON.parse(site.profile_links) || []; } catch (e) { _profileLinks = []; }
|
|---|
| 27 | }
|
|---|
| 28 | %>
|
|---|
| 29 |
|
|---|
| 30 | <% if (_showProfile) { %>
|
|---|
| 31 | <aside class="profile-header" aria-label="Site profile">
|
|---|
| 32 | <div class="container profile-header-inner">
|
|---|
| 33 |
|
|---|
| 34 | <a class="profile-photo" href="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 35 | hx-get="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/?partial=1"
|
|---|
| 36 | hx-target="#pcms-main" hx-swap="innerHTML"
|
|---|
| 37 | hx-push-url="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 38 | hx-indicator="#pcms-loading" aria-label="Home">
|
|---|
| [ab544fd] | 39 | <% if (site.profile_photo) { %>
|
|---|
| [7bc636b] | 40 | <img src="<%= site.profile_photo %>" alt="">
|
|---|
| [ab544fd] | 41 | <% } else if (typeof siteOwnerAvatar !== 'undefined' && siteOwnerAvatar) { %>
|
|---|
| 42 | <img src="<%= siteOwnerAvatar %>" alt="">
|
|---|
| [cb01666] | 43 | <% } else if (site.enable_audio_player && (typeof audioEnabled === 'undefined' || audioEnabled)) { %>
|
|---|
| [7bc636b] | 44 | <span class="profile-photo-fallback profile-photo-fallback--music" aria-hidden="true">
|
|---|
| 45 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|---|
| 46 | <path d="M9 17V5l12-2v12"/>
|
|---|
| 47 | <circle cx="6" cy="17" r="3"/>
|
|---|
| 48 | <circle cx="18" cy="15" r="3"/>
|
|---|
| 49 | </svg>
|
|---|
| 50 | </span>
|
|---|
| 51 | <% } else { %>
|
|---|
| 52 | <span class="profile-photo-fallback" aria-hidden="true"><%= (_displayName || '?').charAt(0).toUpperCase() %></span>
|
|---|
| 53 | <% } %>
|
|---|
| 54 | </a>
|
|---|
| 55 |
|
|---|
| 56 | <div class="profile-info">
|
|---|
| 57 | <h2 class="profile-name">
|
|---|
| 58 | <a href="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 59 | hx-get="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/?partial=1"
|
|---|
| 60 | hx-target="#pcms-main" hx-swap="innerHTML"
|
|---|
| 61 | hx-push-url="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 62 | hx-indicator="#pcms-loading">
|
|---|
| 63 | <%= _displayName %>
|
|---|
| 64 | </a>
|
|---|
| 65 | </h2>
|
|---|
| 66 | <% if (_bioText) { %>
|
|---|
| 67 | <p class="profile-bio"><%= _bioText %></p>
|
|---|
| 68 | <% } %>
|
|---|
| 69 |
|
|---|
| 70 | <% if (_profileLinks.length) { %>
|
|---|
| 71 | <% const _platforms = (typeof platforms_catalog !== 'undefined' && platforms_catalog) || {}; %>
|
|---|
| 72 | <ul class="profile-links" aria-label="External links">
|
|---|
| 73 | <% _profileLinks.forEach(function(l) {
|
|---|
| 74 | const meta = _platforms[l.platform];
|
|---|
| 75 | if (!meta) return; %>
|
|---|
| 76 | <li>
|
|---|
| 77 | <a class="profile-link profile-link--<%= l.platform %>"
|
|---|
| 78 | href="<%= l.platform === 'email' && l.url.indexOf('mailto:') !== 0 ? ('mailto:' + l.url) : l.url %>"
|
|---|
| 79 | target="<%= l.platform === 'email' ? '_self' : '_blank' %>"
|
|---|
| 80 | rel="noopener noreferrer"
|
|---|
| 81 | aria-label="<%= meta.label %>"
|
|---|
| 82 | title="<%= meta.label %>"
|
|---|
| 83 | style="--brand: <%= meta.brand %>">
|
|---|
| 84 | <%- meta.svg %>
|
|---|
| 85 | </a>
|
|---|
| 86 | </li>
|
|---|
| 87 | <% }); %>
|
|---|
| 88 | </ul>
|
|---|
| 89 | <% } %>
|
|---|
| [7c62efb] | 90 |
|
|---|
| 91 | <button type="button" class="profile-fedi-btn" data-fedi-actor-slug="<%= site.slug %>">
|
|---|
| 92 | 🐘 <%= t('fedi.profile_follow') %>
|
|---|
| 93 | </button>
|
|---|
| [7bc636b] | 94 | </div>
|
|---|
| 95 |
|
|---|
| 96 | </div>
|
|---|
| 97 | </aside>
|
|---|
| [7c62efb] | 98 | <script>
|
|---|
| 99 | (function () {
|
|---|
| 100 | if (window.__pcmsFediFollowWired) return;
|
|---|
| 101 | window.__pcmsFediFollowWired = true;
|
|---|
| 102 | document.addEventListener('click', function (e) {
|
|---|
| 103 | var b = e.target.closest && e.target.closest('.profile-fedi-btn');
|
|---|
| 104 | if (!b) return;
|
|---|
| 105 | var raw = window.prompt(<%- JSON.stringify(t('fedi.remote_prompt')) %>, '');
|
|---|
| 106 | if (!raw) return;
|
|---|
| 107 | // Strip a full @user@host handle (and any scheme/path) down to the server host.
|
|---|
| 108 | var server = raw.trim().replace(/^@?[^@\s]*@/, '').replace(/^https?:\/\//i, '').replace(/\/.*$/, '').trim();
|
|---|
| 109 | if (!server) return;
|
|---|
| 110 | var actor = location.origin + '/ap/users/' + encodeURIComponent(b.getAttribute('data-fedi-actor-slug') || '');
|
|---|
| 111 | location.href = 'https://' + server + '/authorize_interaction?uri=' + encodeURIComponent(actor);
|
|---|
| 112 | });
|
|---|
| 113 | })();
|
|---|
| 114 | </script>
|
|---|
| [7bc636b] | 115 | <% } %>
|
|---|
| 116 |
|
|---|
| 117 | <style>
|
|---|
| 118 | /* Profile header (v9 collapse pattern) */
|
|---|
| 119 | .profile-header {
|
|---|
| 120 | border-bottom: 1px solid var(--rule);
|
|---|
| 121 | background: var(--paper);
|
|---|
| 122 | padding: 1.5rem 0;
|
|---|
| 123 | transition: padding 250ms cubic-bezier(.4,0,.2,1);
|
|---|
| 124 | }
|
|---|
| 125 | .profile-header-inner {
|
|---|
| 126 | max-width: 800px;
|
|---|
| 127 | margin: 0 auto;
|
|---|
| 128 | padding: 0 1rem;
|
|---|
| 129 | display: flex;
|
|---|
| 130 | align-items: center;
|
|---|
| 131 | gap: 1.25rem;
|
|---|
| 132 | transition: gap 250ms;
|
|---|
| 133 | }
|
|---|
| 134 | .profile-photo {
|
|---|
| 135 | flex-shrink: 0;
|
|---|
| 136 | display: block;
|
|---|
| 137 | width: 80px;
|
|---|
| 138 | height: 80px;
|
|---|
| 139 | border-radius: 50%;
|
|---|
| 140 | overflow: hidden;
|
|---|
| 141 | background: var(--paper-2);
|
|---|
| 142 | border: 2px solid var(--rule);
|
|---|
| 143 | transition: width 250ms, height 250ms;
|
|---|
| 144 | cursor: pointer;
|
|---|
| 145 | }
|
|---|
| 146 | .profile-photo:hover {
|
|---|
| 147 | border-color: var(--accent);
|
|---|
| 148 | }
|
|---|
| 149 | .profile-photo img {
|
|---|
| 150 | width: 100%;
|
|---|
| 151 | height: 100%;
|
|---|
| 152 | object-fit: cover;
|
|---|
| 153 | pointer-events: none;
|
|---|
| 154 | }
|
|---|
| 155 | .profile-photo-fallback {
|
|---|
| 156 | display: flex;
|
|---|
| 157 | align-items: center;
|
|---|
| 158 | justify-content: center;
|
|---|
| 159 | width: 100%;
|
|---|
| 160 | height: 100%;
|
|---|
| 161 | font-family: var(--font-display, serif);
|
|---|
| 162 | font-size: 2rem;
|
|---|
| 163 | font-weight: 700;
|
|---|
| 164 | color: var(--ink-soft);
|
|---|
| 165 | background: var(--paper-2);
|
|---|
| 166 | pointer-events: none;
|
|---|
| 167 | }
|
|---|
| 168 | .profile-photo-fallback--music {
|
|---|
| 169 | color: var(--accent);
|
|---|
| 170 | }
|
|---|
| 171 | .profile-photo-fallback--music svg {
|
|---|
| 172 | width: 50%;
|
|---|
| 173 | height: 50%;
|
|---|
| 174 | }
|
|---|
| 175 | .profile-info {
|
|---|
| 176 | flex: 1;
|
|---|
| 177 | min-width: 0;
|
|---|
| 178 | }
|
|---|
| 179 | .profile-name {
|
|---|
| 180 | font-family: var(--font-display, serif);
|
|---|
| 181 | font-size: 1.75rem;
|
|---|
| 182 | margin: 0 0 0.25rem;
|
|---|
| 183 | line-height: 1.2;
|
|---|
| 184 | }
|
|---|
| 185 | .profile-name a {
|
|---|
| 186 | color: var(--ink);
|
|---|
| 187 | text-decoration: none;
|
|---|
| 188 | }
|
|---|
| 189 | .profile-bio {
|
|---|
| 190 | margin: 0;
|
|---|
| 191 | color: var(--ink-soft);
|
|---|
| 192 | font-size: 0.95rem;
|
|---|
| 193 | line-height: 1.4;
|
|---|
| 194 | }
|
|---|
| 195 |
|
|---|
| 196 | /* Compact mode on post / special pages */
|
|---|
| 197 | .on-post .profile-header,
|
|---|
| 198 | .on-special .profile-header,
|
|---|
| 199 | .on-search .profile-header,
|
|---|
| 200 | .on-archive .profile-header {
|
|---|
| 201 | padding: 0.75rem 0;
|
|---|
| 202 | }
|
|---|
| 203 | .on-post .profile-photo,
|
|---|
| 204 | .on-special .profile-photo,
|
|---|
| 205 | .on-search .profile-photo,
|
|---|
| 206 | .on-archive .profile-photo {
|
|---|
| 207 | width: 40px;
|
|---|
| 208 | height: 40px;
|
|---|
| 209 | border-width: 1px;
|
|---|
| 210 | }
|
|---|
| 211 | .on-post .profile-photo-fallback,
|
|---|
| 212 | .on-special .profile-photo-fallback,
|
|---|
| 213 | .on-search .profile-photo-fallback,
|
|---|
| 214 | .on-archive .profile-photo-fallback {
|
|---|
| 215 | font-size: 1rem;
|
|---|
| 216 | }
|
|---|
| 217 | .on-post .profile-name,
|
|---|
| 218 | .on-special .profile-name,
|
|---|
| 219 | .on-search .profile-name,
|
|---|
| 220 | .on-archive .profile-name {
|
|---|
| 221 | font-size: 1.1rem;
|
|---|
| 222 | margin: 0;
|
|---|
| 223 | }
|
|---|
| 224 | .on-post .profile-bio,
|
|---|
| 225 | .on-special .profile-bio,
|
|---|
| 226 | .on-search .profile-bio,
|
|---|
| 227 | .on-archive .profile-bio {
|
|---|
| 228 | display: none;
|
|---|
| 229 | }
|
|---|
| 230 |
|
|---|
| 231 | /* Hide on admin pages */
|
|---|
| 232 | .on-admin .profile-header { display: none; }
|
|---|
| 233 |
|
|---|
| 234 | /* Mobile tweaks */
|
|---|
| 235 | @media (max-width: 600px) {
|
|---|
| 236 | .profile-photo { width: 64px; height: 64px; }
|
|---|
| 237 | .profile-photo-fallback { font-size: 1.5rem; }
|
|---|
| 238 | .profile-name { font-size: 1.4rem; }
|
|---|
| 239 | }
|
|---|
| 240 |
|
|---|
| 241 | /* Social / streaming icon row */
|
|---|
| 242 | .profile-links {
|
|---|
| 243 | list-style: none;
|
|---|
| 244 | margin: 0.5rem 0 0;
|
|---|
| 245 | padding: 0;
|
|---|
| 246 | display: flex;
|
|---|
| 247 | gap: 0.5rem;
|
|---|
| 248 | flex-wrap: wrap;
|
|---|
| 249 | }
|
|---|
| 250 | .profile-link {
|
|---|
| 251 | display: inline-flex;
|
|---|
| 252 | align-items: center;
|
|---|
| 253 | justify-content: center;
|
|---|
| 254 | width: 36px;
|
|---|
| 255 | height: 36px;
|
|---|
| 256 | border-radius: 50%;
|
|---|
| 257 | background: var(--paper-2);
|
|---|
| 258 | color: var(--ink-soft);
|
|---|
| 259 | text-decoration: none;
|
|---|
| 260 | transition: background 120ms, color 120ms, transform 100ms ease;
|
|---|
| 261 | }
|
|---|
| 262 | .profile-link:hover {
|
|---|
| 263 | background: var(--brand, var(--accent));
|
|---|
| 264 | color: white;
|
|---|
| 265 | transform: translateY(-1px);
|
|---|
| 266 | }
|
|---|
| 267 | .profile-link svg { width: 18px; height: 18px; display: block; }
|
|---|
| 268 |
|
|---|
| 269 | /* Compact mode collapses social links too (post pages) */
|
|---|
| 270 | .on-post .profile-links,
|
|---|
| 271 | .on-special .profile-links,
|
|---|
| 272 | .on-archive .profile-links { display: none; }
|
|---|
| [7c62efb] | 273 |
|
|---|
| 274 | /* Follow-via-fediverse button */
|
|---|
| 275 | .profile-fedi-btn {
|
|---|
| 276 | margin-top: 0.65rem;
|
|---|
| 277 | display: inline-flex; align-items: center; gap: 0.4rem;
|
|---|
| 278 | padding: 0.4rem 0.85rem;
|
|---|
| 279 | border: 1px solid var(--rule);
|
|---|
| 280 | border-radius: 999px;
|
|---|
| 281 | background: var(--paper-2);
|
|---|
| 282 | color: var(--ink-soft);
|
|---|
| 283 | font: inherit; font-size: 0.85rem; font-weight: 600;
|
|---|
| 284 | cursor: pointer;
|
|---|
| 285 | transition: border-color 120ms, color 120ms, background 120ms;
|
|---|
| 286 | }
|
|---|
| 287 | .profile-fedi-btn:hover { border-color: var(--accent); color: var(--ink); }
|
|---|
| 288 | .on-post .profile-fedi-btn,
|
|---|
| 289 | .on-special .profile-fedi-btn,
|
|---|
| 290 | .on-search .profile-fedi-btn,
|
|---|
| 291 | .on-archive .profile-fedi-btn { display: none; }
|
|---|
| [7bc636b] | 292 | </style>
|
|---|