From a965274a315839842a63e18841c6ddb4ec68da82 Mon Sep 17 00:00:00 2001 From: dangrubbb Date: Sat, 28 Feb 2026 16:30:19 -0500 Subject: [PATCH] Add dynamic blog preview to homepage - Create blog/posts.json for managing blog post metadata - Add blog preview box (max 1/3 screen width) to homepage - Fetch latest post dynamically with image and excerpt - Updates automatically when new posts added to JSON - Styled to fit no-scroll homepage layout - Link to full blog page for each post --- blog/posts.json | 10 ++++++++ index.html | 6 +++++ script.js | 39 +++++++++++++++++++++++++++- style.css | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 blog/posts.json diff --git a/blog/posts.json b/blog/posts.json new file mode 100644 index 0000000..6b67010 --- /dev/null +++ b/blog/posts.json @@ -0,0 +1,10 @@ +[ + { + "id": "01", + "title": "First Blog Post", + "date": "2026-02-28", + "excerpt": "This is the first blog post excerpt. Add your own blog entries by updating this JSON file with a title, date, image path, and excerpt.", + "image": "./src/img/CannotConnect.JPEG", + "slug": "first-blog-post" + } +] diff --git a/index.html b/index.html index 7dd0444..2e45751 100644 --- a/index.html +++ b/index.html @@ -243,6 +243,12 @@ EXCLUSIVE: Leaked mixtape from Darnea's vault

+
+
+

Loading latest post...

+
+
+
diff --git a/script.js b/script.js index 59b84a2..dc80c30 100644 --- a/script.js +++ b/script.js @@ -126,4 +126,41 @@ uncomment the code below. //
CSS
//
${css.join("\n\n")}
// -// `; \ No newline at end of file +// `; + +// Load latest blog post preview +async function loadLatestBlogPost() { + try { + const response = await fetch('./blog/posts.json'); + const posts = await response.json(); + + if (posts.length === 0) { + document.getElementById('latestBlogPreview').innerHTML = '

No blog posts yet.

'; + return; + } + + // Get the latest post (first in the array) + const latestPost = posts[0]; + + // Create the preview HTML + const previewHTML = ` + ${latestPost.title} +
${new Date(latestPost.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}
+ ${latestPost.title} +

${latestPost.excerpt}

+ Read more → + `; + + document.getElementById('latestBlogPreview').innerHTML = previewHTML; + } catch (error) { + console.error('Error loading blog posts:', error); + document.getElementById('latestBlogPreview').innerHTML = '

Error loading blog posts.

'; + } +} + +// Load blog preview when page is ready +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', loadLatestBlogPost); +} else { + loadLatestBlogPost(); +} \ No newline at end of file diff --git a/style.css b/style.css index de180ac..a5bffd9 100644 --- a/style.css +++ b/style.css @@ -294,6 +294,74 @@ body { text-decoration: underline; } +/* Blog Preview Box */ +.blog-preview-container { + margin: 30px auto 0; + max-width: 33%; + width: 100%; + display: flex; + justify-content: center; +} + +.blog-preview { + border: 1px solid rgba(155, 169, 180, 0.3); + border-radius: 4px; + padding: 15px; + background: linear-gradient(135deg, rgba(13, 10, 20, 0.6), rgba(50, 30, 80, 0.3)); + overflow: hidden; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +.blog-preview img { + width: 100%; + height: auto; + max-height: 150px; + object-fit: cover; + border-radius: 3px; + margin-bottom: 10px; +} + +.blog-preview-title { + color: #ffff00; + font-weight: bold; + font-size: 0.95rem; + margin: 10px 0 5px; + text-decoration: none; + display: block; +} + +.blog-preview-title:hover { + text-decoration: underline; +} + +.blog-preview-date { + color: #aa95bd; + font-size: 0.8rem; + margin-bottom: 8px; +} + +.blog-preview-excerpt { + color: #9d9aa4; + font-size: 0.85rem; + line-height: 1.4; + margin: 8px 0 10px; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.blog-preview-link { + display: inline-block; + color: #6be1e9; + font-size: 0.8rem; + text-decoration: none; +} + +.blog-preview-link:hover { + text-decoration: underline; +} + /* Push the navigation to the bottom using flexbox spacer */ .bottom-nav { margin-top: auto;