// ====== Related Posts (Blogger) - same label, 3 items, after 2021, nice links ====== (function () { const MIN_DATE = new Date('2022-01-01T00:00:00Z'); // μετά το 2021 const MAX_RESULTS_FETCH = 50; const ITEMS_TO_SHOW = 3; const GUARD_ATTR = 'data-crml-related-done'; // ---- CSS ---- (function injectCSS(){ if (document.getElementById('crml-related-style')) return; const css = ` .crml-related{margin:24px 0 8px} .crml-related h3{margin:0 0 10px;font-size:1.05rem} .crml-related-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px} @media (max-width:720px){.crml-related-grid{grid-template-columns:1fr}} .crml-related-card{background:#fff8e1;border:1px solid #f0e2b6;border-radius:14px;padding:12px;box-shadow:0 2px 6px rgba(0,0,0,.06);transition:transform .1s ease, box-shadow .1s ease} .crml-related-card:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,.08)} .crml-related-link{display:block;font-weight:600;text-decoration:none;color:#1a3d6b;line-height:1.3} .crml-related-meta{margin-top:6px;font-size:.85rem;opacity:.8} `; const s = document.createElement('style'); s.id = 'crml-related-style'; s.textContent = css; document.head.appendChild(s); })(); const $ = (sel, root=document) => root.querySelector(sel); function getTargetRoot(){ // Προτιμάμε τον γονέα της βασικής post-body const body = document.querySelector('.post-body,[itemprop="articleBody"]'); if (body && body.parentElement) return body.parentElement; // Fallback: το πρώτο βασικό wrapper return document.querySelector('.post, article, .post-outer') || document.body; } function getCurrentPostLink(root){ const a = $('h1 a, h2 a, .post-title a, [itemprop="headline"] a', root) || $('a[rel="bookmark"]', root); return a ? a.href : window.location.href; } function getOneLabel(root){ const lbl = $('.post-labels a, .label a, a[rel="tag"]', root) || document.querySelector('.post-labels a, .label a, a[rel="tag"]'); return lbl ? lbl.textContent.trim() : ''; } function isoDateToDate(s){ const d=new Date(s); return isNaN(d)?null:d; } async function fetchByLabel(label){ const base = `${location.origin}/feeds/posts/summary/-/${encodeURIComponent(label)}`; const url = `${base}?alt=json&max-results=${MAX_RESULTS_FETCH}&orderby=published&v=2`; const res = await fetch(url, { credentials: 'same-origin' }); if (!res.ok) throw new Error('Feed HTTP error ' + res.status); const data = await res.json(); return data && data.feed && Array.isArray(data.feed.entry) ? data.feed.entry : []; } function pickAlternateLink(entry){ const links = entry.link || []; const alt = links.find(l => l.rel === 'alternate'); return alt ? alt.href : null; } function renderRelated(root, items, label){ // Αν έχει ήδη μπει, μην ξαναβάλεις if (root.hasAttribute(GUARD_ATTR) || root.querySelector('.crml-related')) return; const body = root.querySelector('.post-body,[itemprop="articleBody"]') || root; const wrap = document.createElement('div'); wrap.className = 'crml-related'; wrap.innerHTML = `

Σχετικές αναρτήσεις (${label})

`; const grid = wrap.querySelector('.crml-related-grid'); items.forEach(it=>{ const card = document.createElement('div'); card.className = 'crml-related-card'; const a = document.createElement('a'); a.className = 'crml-related-link'; a.href = it.url; a.textContent = it.title; const meta = document.createElement('div'); meta.className = 'crml-related-meta'; meta.textContent = new Date(it.date).toLocaleDateString(); card.appendChild(a); card.appendChild(meta); grid.appendChild(card); }); body.parentElement.insertBefore(wrap, body.nextSibling); root.setAttribute(GUARD_ATTR, '1'); // σημαδάκι για να μη ξαναμπεί } async function buildOnce(){ const root = getTargetRoot(); if (!root || root.hasAttribute(GUARD_ATTR)) return; const label = getOneLabel(root); if (!label) return; const currentURL = getCurrentPostLink(root); let entries = []; try { entries = await fetchByLabel(label); } catch(e){ return; } const items = entries.map(e=>({ title: (e.title && e.title.$t) || '(Χωρίς τίτλο)', url: pickAlternateLink(e), date: e.published ? e.published.$t : null })).filter(x => x.url && x.date); const filtered = items.filter(x => { const d = isoDateToDate(x.date); return d && d >= MIN_DATE; // μετά το 2021 }).filter(x => x.url !== currentURL) // όχι η τρέχουσα .sort((a,b) => new Date(b.date) - new Date(a.date)) // νεότερα πρώτα .slice(0, ITEMS_TO_SHOW); if (filtered.length) renderRelated(root, filtered, label); } if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', buildOnce); } else { buildOnce(); } })();