Changeset d54dade in Klonkt
- Timestamp:
- 06/15/2026 03:39:35 AM (3 months ago)
- Branches:
- main
- Children:
- 52badd3
- Parents:
- 7f46817d
- Location:
- src
- Files:
-
- 2 edited
-
routes/posts.js (modified) (2 diffs)
-
views/pages/post.ejs (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/posts.js
r7f46817d rd54dade 501 501 // Prev / next chronological (kept for back-compat — "post-nav" feature 502 502 // below the article still uses these as a simple linear navigation). 503 const prevPost = db.prepare(` 504 SELECT slug, title FROM posts 505 WHERE site_id = ? AND status = 'published' AND published_at < ? AND id != ? 506 ORDER BY published_at DESC LIMIT 1 507 `).get(site.id, post.published_at, post.id); 508 509 const nextPost = db.prepare(` 510 SELECT slug, title FROM posts 511 WHERE site_id = ? AND status = 'published' AND published_at > ? AND id != ? 512 ORDER BY published_at ASC LIMIT 1 513 `).get(site.id, post.published_at, post.id); 503 // Hub-modus: Gerelateerde posts + Newer/Older trekken uit ALLE users (alle 504 // sites), nieuwste->oudste. Solo-modus: binnen de huidige site (oud gedrag). 505 const isHub = res.locals.tenancy === 'hub'; 506 // Per-post URL-basis: in hub wijst een link naar /user/<site-slug>/<post-slug>. 507 const urlBaseFor = (p) => (isHub && p && p.site_slug) ? `/user/${p.site_slug}` : ''; 508 509 const prevPost = isHub 510 ? db.prepare(` 511 SELECT p.slug, p.title, s.slug AS site_slug 512 FROM posts p JOIN sites s ON s.id = p.site_id 513 WHERE p.status = 'published' AND p.published_at < ? AND p.id != ? 514 ORDER BY p.published_at DESC LIMIT 1 515 `).get(post.published_at, post.id) 516 : db.prepare(` 517 SELECT slug, title FROM posts 518 WHERE site_id = ? AND status = 'published' AND published_at < ? AND id != ? 519 ORDER BY published_at DESC LIMIT 1 520 `).get(site.id, post.published_at, post.id); 521 522 const nextPost = isHub 523 ? db.prepare(` 524 SELECT p.slug, p.title, s.slug AS site_slug 525 FROM posts p JOIN sites s ON s.id = p.site_id 526 WHERE p.status = 'published' AND p.published_at > ? AND p.id != ? 527 ORDER BY p.published_at ASC LIMIT 1 528 `).get(post.published_at, post.id) 529 : db.prepare(` 530 SELECT slug, title FROM posts 531 WHERE site_id = ? AND status = 'published' AND published_at > ? AND id != ? 532 ORDER BY published_at ASC LIMIT 1 533 `).get(site.id, post.published_at, post.id); 534 if (prevPost) prevPost._urlBase = urlBaseFor(prevPost); 535 if (nextPost) nextPost._urlBase = urlBaseFor(nextPost); 514 536 515 537 // ── Related posts: same-tag matching with recency fallback ───── 516 538 // Fetch ~50 candidates, score by tag overlap, take top 3. 517 539 // Excluding self via `id != ?`. 518 const candidates = db.prepare(` 519 SELECT id, slug, title, cover_image_url, published_at, tags 520 FROM posts 521 WHERE site_id = ? AND status = 'published' AND id != ? 522 ORDER BY published_at DESC 523 LIMIT 50 524 `).all(site.id, post.id); 540 const candidates = isHub 541 ? db.prepare(` 542 SELECT p.id, p.slug, p.title, p.cover_image_url, p.published_at, p.tags, s.slug AS site_slug 543 FROM posts p JOIN sites s ON s.id = p.site_id 544 WHERE p.status = 'published' AND p.id != ? 545 ORDER BY p.published_at DESC LIMIT 50 546 `).all(post.id) 547 : db.prepare(` 548 SELECT id, slug, title, cover_image_url, published_at, tags 549 FROM posts 550 WHERE site_id = ? AND status = 'published' AND id != ? 551 ORDER BY published_at DESC LIMIT 50 552 `).all(site.id, post.id); 525 553 526 554 // Parse tags JSON safely; missing/malformed → empty array. … … 558 586 } 559 587 // Strip the internal _overlap field before sending to view 560 relatedPosts = relatedPosts.map(({ _overlap, tags, ...rest }) => rest);588 relatedPosts = relatedPosts.map(({ _overlap, tags, ...rest }) => ({ ...rest, _urlBase: urlBaseFor(rest) })); 561 589 562 590 // ── Pinned navigation: prev/next pinned post ─────────────────── -
src/views/pages/post.ejs
r7f46817d rd54dade 212 212 <% relatedPosts.forEach(function(rp) { %> 213 213 <li class="post-related-card"> 214 <a href=" /<%= rp.slug %>"214 <a href="<%= rp._urlBase || '' %>/<%= rp.slug %>"<% if (!rp._urlBase) { %> 215 215 hx-get="/<%= rp.slug %>?partial=1" hx-target="#pcms-main" 216 hx-push-url="/<%= rp.slug %>" hx-indicator="#pcms-loading" >216 hx-push-url="/<%= rp.slug %>" hx-indicator="#pcms-loading"<% } %>> 217 217 <% if (rp.cover_image_url) { %> 218 218 <span class="post-related-cover" … … 242 242 Uses prevPinnedPost which now means "smaller rank". %> 243 243 <% if (prevPinnedPost) { %> 244 <a class="post-pinned-card post-pinned-card--prev" href=" /<%= prevPinnedPost.slug %>"245 hx-get=" /<%= prevPinnedPost.slug %>?partial=1" hx-target="#pcms-main"246 hx-push-url=" /<%= prevPinnedPost.slug %>" hx-indicator="#pcms-loading">244 <a class="post-pinned-card post-pinned-card--prev" href="<%= _base %>/<%= prevPinnedPost.slug %>" 245 hx-get="<%= _base %>/<%= prevPinnedPost.slug %>?partial=1" hx-target="#pcms-main" 246 hx-push-url="<%= _base %>/<%= prevPinnedPost.slug %>" hx-indicator="#pcms-loading"> 247 247 <span class="post-pinned-arrow" aria-hidden="true">←</span> 248 248 <span class="post-pinned-body"> … … 262 262 Uses nextPinnedPost which now means "larger rank". %> 263 263 <% if (nextPinnedPost) { %> 264 <a class="post-pinned-card post-pinned-card--next" href=" /<%= nextPinnedPost.slug %>"265 hx-get=" /<%= nextPinnedPost.slug %>?partial=1" hx-target="#pcms-main"266 hx-push-url=" /<%= nextPinnedPost.slug %>" hx-indicator="#pcms-loading">264 <a class="post-pinned-card post-pinned-card--next" href="<%= _base %>/<%= nextPinnedPost.slug %>" 265 hx-get="<%= _base %>/<%= nextPinnedPost.slug %>?partial=1" hx-target="#pcms-main" 266 hx-push-url="<%= _base %>/<%= nextPinnedPost.slug %>" hx-indicator="#pcms-loading"> 267 267 <span class="post-pinned-arrow" aria-hidden="true">→</span> 268 268 <span class="post-pinned-body"> … … 287 287 <nav class="post-nav"> 288 288 <% if (prevPost) { %> 289 <a class="post-nav-prev" href=" /<%= prevPost.slug %>"289 <a class="post-nav-prev" href="<%= prevPost._urlBase || '' %>/<%= prevPost.slug %>"<% if (!prevPost._urlBase) { %> 290 290 hx-get="/<%= prevPost.slug %>?partial=1" hx-target="#pcms-main" 291 hx-push-url="/<%= prevPost.slug %>" hx-indicator="#pcms-loading" >291 hx-push-url="/<%= prevPost.slug %>" hx-indicator="#pcms-loading"<% } %>> 292 292 <span class="post-nav-label">← Older</span> 293 293 <span class="post-nav-title"><%= prevPost.title %></span> … … 295 295 <% } else { %><span></span><% } %> 296 296 <% if (nextPost) { %> 297 <a class="post-nav-next" href=" /<%= nextPost.slug %>"297 <a class="post-nav-next" href="<%= nextPost._urlBase || '' %>/<%= nextPost.slug %>"<% if (!nextPost._urlBase) { %> 298 298 hx-get="/<%= nextPost.slug %>?partial=1" hx-target="#pcms-main" 299 hx-push-url="/<%= nextPost.slug %>" hx-indicator="#pcms-loading" >299 hx-push-url="/<%= nextPost.slug %>" hx-indicator="#pcms-loading"<% } %>> 300 300 <span class="post-nav-label">Newer →</span> 301 301 <span class="post-nav-title"><%= nextPost.title %></span>
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)