JezK
Edit File: blog.php
<?php /** * blog-index.php – dynamic blog listing with "Load More". * * Requirements satisfied: * - Includes header.php, home-section.php, and footer.php * - Shows first 10 blog cards, then reveals 5 more on each click * - When all posts are visible, button text changes and disables */ // -------------------- Build & sort post list -------------------- $blogDir = __DIR__ . '/blog'; $files = array_filter(glob($blogDir . '/*.php'), 'is_file'); $posts = []; foreach ($files as $file) { if (basename($file) === 'index.php') continue; // skip potential /blog/index.php $content = file_get_contents($file); if (preg_match('/<title>(.*?)<\/title>/is', $content, $m)) { $title = trim($m[1]); } else { $title = ucwords(str_replace(['-', '_'], ' ', basename($file, '.php'))); } $posts[] = [ 'title' => $title, 'url' => '/blog/' . basename($file), 'mtime' => filemtime($file), ]; } usort($posts, fn($a, $b) => $b['mtime'] <=> $a['mtime']); // --------------------- Page components -------------------------- include_once __DIR__ . '/header.php'; ?> <!-- Home hero section (full-width) --> <section class="home-section"> <?php include_once __DIR__ . '/home-section.php'; ?> </section> <!-- Blog list wrapper --> <style> :root { --bg: #f9fafb; --card-bg:#fff; --text:#1f2937; --muted:#6b7280; --radius:1rem; --shadow:0 4px 12px rgba(0,0,0,.04); --shadow-hover:0 6px 18px rgba(0,0,0,.08); } body{background:var(--bg);color:var(--text);} /* backup if header.css absent */ .container{max-width:1120px;margin-inline:auto;padding:clamp(1rem,2vw,2rem);} .section-title{font-size:clamp(1.5rem,4vw,2rem);font-weight:700;margin-bottom:1.5rem;text-align:center;} .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:1.25rem;} .card{background:var(--card-bg);padding:1rem;border-radius:var(--radius);box-shadow:var(--shadow);transition:.25s ease;} .card:hover{transform:translateY(-4px);box-shadow:var(--shadow-hover);} .card a{display:block;text-decoration:none;color:inherit;height:100%;} .card-title{font-size:1rem;font-weight:600;line-height:1.4;margin-bottom:.5rem;min-height:3rem;} .card-date{font-size:.85rem;color:var(--muted);} .hidden{display:none;} #loadMore{display:inline-block;margin:2rem auto;padding:.75rem 2rem;font-size:1rem;font-weight:600;border:none;border-radius:999px;background:#2563eb;color:#fff;cursor:pointer;transition:background .2s ease;} #loadMore:hover{background:#1e4fba;} #loadMore[disabled]{opacity:.5;cursor:not-allowed;} #noMore{margin:2rem auto;text-align:center;color:var(--muted);font-size:.95rem;} </style> <main class="container"> <section class="blog-section" aria-labelledby="blog-heading"> <h1 id="blog-heading" class="section-title">Latest Blog Posts</h1> <div class="grid" id="blogGrid"> <?php $initialLimit = 10; $index = 0; foreach ($posts as $post): $hiddenClass = ($index >= $initialLimit) ? 'hidden' : ''; ?> <div class="card <?= $hiddenClass ?>"> <a href="<?= htmlspecialchars($post['url']) ?>"> <div class="card-title"><?= htmlspecialchars($post['title']) ?></div> <div class="card-date"><?= date('F j, Y', $post['mtime']) ?></div> </a> </div> <?php $index++; endforeach; ?> </div> <?php if (count($posts) > $initialLimit): ?> <button id="loadMore">Load more</button> <p id="noMore" class="hidden">There are no more blogs.</p> <?php endif; ?> </section> </main> <script> (function(){ const grid = document.getElementById('blogGrid'); if(!grid) return; const step = 5; const btn = document.getElementById('loadMore'); const noMoreTxt = document.getElementById('noMore'); function revealNext(){ const hiddenCards = grid.querySelectorAll('.card.hidden'); if(hiddenCards.length===0){ btn.setAttribute('disabled','disabled'); btn.style.display='none'; noMoreTxt.classList.remove('hidden'); return; } for(let i=0;i<step && i<hiddenCards.length;i++){ hiddenCards[i].classList.remove('hidden'); } if(grid.querySelectorAll('.card.hidden').length===0){ btn.setAttribute('disabled','disabled'); btn.style.display='none'; noMoreTxt.classList.remove('hidden'); } } if(btn){btn.addEventListener('click',revealNext);} })(); </script> <?php include_once __DIR__ . '/footer.php'; ?>