Compare commits

...

8 Commits

Author SHA1 Message Date
509b398b6d feat: Added featured post
All checks were successful
Deploy Blog to Folder / deploy (push) Successful in 4s
2025-08-23 13:39:09 -04:00
c25f32592b fix: Fixed CSS for post thumbnail
All checks were successful
Deploy Blog to Folder / deploy (push) Successful in 4s
2025-08-22 23:29:28 -04:00
b7822c8080 fix: Added padding to post thumbnail image
All checks were successful
Deploy Blog to Folder / deploy (push) Successful in 4s
2025-08-22 23:22:05 -04:00
d6439e36d7 feat: Finished initial individual post layout
All checks were successful
Deploy Blog to Folder / deploy (push) Successful in 5s
2025-08-22 23:20:15 -04:00
abb4861389 feat: Finished all blog posts layout page 2025-08-22 22:47:43 -04:00
4195aa8d8f chore: Progress sync for the night
All checks were successful
Deploy Blog to Folder / deploy (push) Successful in 4s
2025-08-21 01:08:50 -04:00
32bff9eaf9 chore: Moved reusable CSS classes to shared stylesheet 2025-08-21 01:08:31 -04:00
41d4174a09 fix: Fixed timezone date parsing issue 2025-08-21 01:07:35 -04:00
26 changed files with 259 additions and 82 deletions

View File

@ -3,6 +3,14 @@ import filtersPlugin from "./src/_config/filters.js";
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
export default async function(eleventyConfig) {
eleventyConfig.addDateParsing(function(dateValue) {
if (dateValue != null && typeof(dateValue) === 'object') {
dateValue = new Date(dateValue.getFullYear(), dateValue.getMonth(), dateValue.getDate() + 1);
}
return dateValue; // fallback
});
eleventyConfig.addPassthroughCopy(
{'./public/': '/'}
);

View File

@ -21,18 +21,6 @@
.content > p:not(:first-child) {
margin-top: 2rem;
}
.alternating-background-container > :nth-child(2n-1) {
background-color: var(--primary-alternating-color);
}
.alternating-background-container > :nth-child(2n) {
background-color: var(--secondary-alternating-color);
}
.alternating-background-container > div {
padding: 2rem 0;
}
.alternating-primary-brown {
--primary-alternating-color: rgba(var(--brown), .21);
}
@media (min-width: 992px) {
.title {

View File

@ -126,6 +126,7 @@ main > :last-child {
object-fit: cover;
object-position: center;
width: 100%;
border: 4px solid white;
}
.featured > h1,
.about > h1 {
@ -151,6 +152,14 @@ main > :last-child {
font-weight: 300;
margin-top: 1rem;
}
.featured .featured-text {
display: flex;
flex-direction: column;
}
.featured-text span {
color: rgba(var(--black), .56);
font-size: .85rem;
}
.about > div {
margin-top: 2rem;
@ -226,4 +235,7 @@ main > :last-child {
text-align: end;
padding-left: 2rem;
}
.featured > div > div {
width: 50%;
}
}

77
public/css/posts.css Normal file
View File

@ -0,0 +1,77 @@
.mb-2 {
margin-bottom: 2rem;
}
.post-layout {
display: flex;
flex-direction: column;
}
.post-layout main {
flex: 1;
}
.post-layout main .thumbnail {
width: 100%;
height: 300px;
object-fit: contain;
object-position: center;
}
.post-layout main > div {
background-color: rgba(255, 255, 255, .71);
padding: 2rem;
height: 100%;
}
.posts {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
grid-column-gap: 2rem;
grid-row-gap: 2rem;
}
.posts > a {
text-decoration: none;
color: rgba(var(--black), .76);
}
.posts > div {
width: 100%;
}
.post-card {
background-color: white;
border-radius: 1rem;
box-shadow: 0 2px 4px rgba(var(--black), .21);
transition: transform 0.3s ease, box-shadow 0.3s ease;
margin: 0 1rem;
}
.post-card:hover {
transform: translate(-4px, -4px); /* Up and left by 4px */
box-shadow: 0 8px 16px rgba(var(--black), 0.3); /* deeper shadow for “lifted” look */
}
.post-card > img {
width: 100%;
object-fit: cover;
object-position: center;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
}
.post-card .post-body {
padding: 2rem;
}
@media (min-width: 768px) {
.post-layout main .thumbnail {
height: 375px;
margin: 1rem 0;
}
}
@media (min-width: 992px) {
.posts {
grid-template-columns: repeat(2, 1fr);
}
.post-card {
margin: 0;
}
.post-layout main .thumbnail {
height: 375px;
margin: 2rem 0;
}
}

View File

@ -61,6 +61,14 @@ footer {
margin-right: auto;
}
.title {
font-size: 3rem;
font-weight: 400;
}
.text-center {
text-align: center;
}
.h-100 {
height: 100%;
}
@ -153,6 +161,19 @@ footer {
max-width: 100px;
}
.alternating-background-container > :nth-child(2n-1) {
background-color: var(--primary-alternating-color);
}
.alternating-background-container > :nth-child(2n) {
background-color: var(--secondary-alternating-color);
}
.alternating-background-container > div {
padding: 2rem 0;
}
.alternating-primary-brown {
--primary-alternating-color: rgba(var(--brown), .21);
}
.mobile-nav {
display: flex;
flex-direction: column;

38
public/js/navbar.js Normal file
View File

@ -0,0 +1,38 @@
const mobileNav = document.getElementById('mobile-nav');
function toggleMobileNav() {
if (mobileNav.classList.contains('show')) {
removeBackdrop()
} else {
const backdrop = document.createElement('div');
backdrop.className = 'mobile-nav-backdrop';
document.body.appendChild(backdrop);
backdrop.addEventListener('click', () => {
mobileNav.classList.remove('show');
removeBackdrop();
});
setTimeout(() => backdrop.classList.add('show'), 10);
}
mobileNav.classList.toggle('show');
}
function removeBackdrop() {
const backdrop = document.querySelector('.mobile-nav-backdrop');
if (backdrop) {
backdrop.classList.remove('show');
setTimeout(() => {
backdrop.remove();
}, 250);
}
}
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
if (mobileNav.classList.contains('show')) {
mobileNav.classList.remove('show');
removeBackdrop();
}
}
});
document.getElementById('mobile-nav-btn').addEventListener('click', toggleMobileNav);
document.getElementById('mobile-nav-close-btn').addEventListener('click', toggleMobileNav);

View File

@ -7,4 +7,9 @@ export default function(eleventyConfig) {
return array[0];
});
eleventyConfig.addFilter("firstWords", function (content, numWords = 100) {
if (!content) return "";
return content.split(/\s+/).slice(0, numWords).join(" ");
});
};

View File

@ -1,2 +1,3 @@
<script type="module" src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script>
<script src="/js/navbar.js"></script>

View File

@ -23,46 +23,5 @@
</footer>
{% include "components/scripts.liquid" %}
<script>
// TODO: move to script file
const mobileNav = document.getElementById('mobile-nav');
function toggleMobileNav() {
if (mobileNav.classList.contains('show')) {
removeBackdrop()
} else {
const backdrop = document.createElement('div');
backdrop.className = 'mobile-nav-backdrop';
document.body.appendChild(backdrop);
backdrop.addEventListener('click', () => {
mobileNav.classList.remove('show');
removeBackdrop();
});
setTimeout(() => backdrop.classList.add('show'), 10);
}
mobileNav.classList.toggle('show');
}
function removeBackdrop() {
const backdrop = document.querySelector('.mobile-nav-backdrop');
if (backdrop) {
backdrop.classList.remove('show');
setTimeout(() => {
backdrop.remove();
}, 250);
}
}
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
if (mobileNav.classList.contains('show')) {
mobileNav.classList.remove('show');
removeBackdrop();
}
}
});
document.getElementById('mobile-nav-btn').addEventListener('click', toggleMobileNav);
document.getElementById('mobile-nav-close-btn').addEventListener('click', toggleMobileNav);
</script>
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% include "components/meta-tags.liquid" %}
{% include "components/headers.liquid" %}
<link rel="stylesheet" href="/css/posts.css">
<title>{{ title | default: metadata.title }} - Cyper's Blog</title>
</head>
<body class="post-layout">
<header>
{% include "components/navbars.liquid" %}
</header>
<main>
<div class="container">
<h1>{{ title }}</h1>
<p class="timestamp">{{ date | date: "%B %-d, %Y" }}</p>
<img class="thumbnail" src="{{ thumbnail }}">
{{ content }}
</div>
</main>
<footer>
{% include "components/footer.liquid" %}
</footer>
{% include "components/scripts.liquid" %}
</body>
</html>

View File

@ -31,7 +31,7 @@ css: about.css
help even one person or introduce a new perspective to someone, then this blog has served its purpose and I can be happy.
</p>
<p>
While this blog isn't my "safe space" per se, it is a place where I will express my unfiltered thoughts and opinions. I encourage everyone else to do the same, and to please be respectful of others' opinions while doing so.
This blog is a place where I will express my unfiltered thoughts and opinions. I encourage everyone else to do the same, and to please be respectful of others' opinions while doing so.
</p>
</div>
</div>

View File

@ -35,15 +35,17 @@ css: home.css
</div>
<div>
<div class="container featured">
{% assign latestPost = collections.posts | last %}
<h1>Featured Posts</h1>
<div>
<div>
<img src="https://dummyimage.com/1280x720/fff/aaa" alt="Featured Post Image" />
<img class="featured-image" src="{{ latestPost.data.thumbnail }}" alt="{{ latestPost.data.title }}" />
</div>
<div>
<h2>Latest Post Title Goes Here</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Alias nisi dolorem velit facere ea? Fugit dolor libero dolorem laborum sapiente labore quidem eos, ratione deleniti. Hic sunt ea aspernatur iusto!</p>
<a href="#">Read more...</a>
<div class="featured-text">
<h2>{{ latestPost.data.title }}</h2>
<span>{{ latestPost.data.date | date: "%B %-d, %Y" }}</span>
<p>{{ latestPost.templateContent | strip_html | firstWords: 25 }}</p>
<a href="{{ latestPost.url }}">Read more...</a>
</div>
</div>
</div>

View File

@ -1,5 +1,7 @@
---
title: Example post 11111
title: Example post 1
date: 2025-08-01
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
First post! Content change

View File

@ -1,5 +1,7 @@
---
title: Example post 10
date: 2025-08-10
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 3
date: 2025-08-11
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 12
date: 2025-08-12
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 2 - for Paz
date: 2025-08-02
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 3
date: 2025-08-03
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 4
date: 2025-08-04
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 5
date: 2025-08-05
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 6
date: 2025-08-06
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 7
date: 2025-08-07
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 8
date: 2025-08-08
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,5 +1,7 @@
---
title: Example post 9
date: 2025-08-09
thumbnail: https://dummyimage.com/1280x720/ccc/fff
---
Second post!

View File

@ -1,4 +1,4 @@
{
"layout": "layout.liquid",
"layout": "post-layout.liquid",
"tags": "posts"
}

View File

@ -7,24 +7,35 @@ pagination:
permalink: "/posts{% if pagination.pageNumber != 0 %}/{{ pagination.pageNumber }}{% endif %}/"
layout: layout.liquid
title: Posts
css: posts.css
---
<div class="container">
<h1>All Posts</h1>
</div>
<div class="container">
<ul>
<div class="alternating-background-container alternating-primary-brown">
<div>
<div class="contaier">
<h1 class="title text-center">All Posts</h1>
</div>
</div>
<div class="container posts">
{% for post in pagination.items %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a> {{ post.date | date: "%B %-d, %Y" }}
</li>
<a href="{{ post.url }}">
<div class="post-card">
{% if post.data.thumbnail %}
<img src="{{ post.data.thumbnail }}" alt="{{ post.data.title }}" />
{% endif %}
<div class="post-body">
<p class="post-date">{{ post.date | date: "%B %-d, %Y" }}</p>
<h1>{{ post.data.title }}</h1>
<p>{{ post.data.context }}</p>
<!-- <p>Views {} | Likes {}</p> -->
</div>
</div>
</a>
{% endfor %}
</ul>
</div>
</div>
<div class="pagination">
<div class="container">
<div class="pagination mb-2">
{% if pagination.href.previous %}
<a href="{{ pagination.href.previous }}">← Previous</a>
{% endif %}
@ -34,4 +45,5 @@ title: Posts
{% if pagination.href.next %}
<a href="{{ pagination.href.next }}">Next →</a>
{% endif %}
</div>
</div>