Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/eleventy-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
cname: aryan-gupta.is-a.dev
cname: aryan-gupta.is-a.dev
44 changes: 18 additions & 26 deletions eleventy.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// eleventy.config.js
const { DateTime } = require("luxon"); // Import Luxon library for dates
const { DateTime } = require("luxon");
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const pluginTOC = require('eleventy-plugin-toc');
const markdownIt = require('markdown-it');
Expand All @@ -9,7 +8,6 @@ module.exports = function(eleventyConfig) {

eleventyConfig.addPlugin(syntaxHighlight);

// --- TOC & Anchor Plugin Configuration ---
eleventyConfig.setLibrary(
'md',
markdownIt({
Expand All @@ -19,70 +17,64 @@ module.exports = function(eleventyConfig) {
}).use(markdownItAnchor, {
slugify: s => s.trim().toLowerCase().replace(/[\s+,.']/g, '-').replace(/[()]/g, ''), // Ensure consistent slugification
permalink: markdownItAnchor.permalink.ariaHidden({
placement: 'before', // Or 'after'
class: 'heading-anchor-link', // Optional: A class for styling the anchor link
symbol: '#', // Optional: The symbol for the anchor link
level: [2,3,4] // Optional: Only add permalinks to h2, h3, h4
placement: 'before',
class: 'heading-anchor-link',
symbol: '#',
level: [2,3,4]
})
})
);

eleventyConfig.addPlugin(pluginTOC, {
tags: ['h2', 'h3'], // Which heading tags to include in the TOC, h4 can be added if needed
wrapper: 'nav', // What element to wrap the TOC in, e.g., 'nav'
wrapperClass: 'toc', // Class for the wrapper element
ul: true, // Whether to use an unordered list (ul) or ordered list (ol)
flat: false // Whether to generate a flat list or nested list
tags: ['h2', 'h3'],
wrapper: 'nav',
wrapperClass: 'toc',
ul: true,
flat: false
});

eleventyConfig.addCollection("research", function(collectionApi) {
return collectionApi.getFilteredByTag("research");
});

// --- Passthrough Copy ---
// (Keep your existing passthrough copy lines)
eleventyConfig.addPassthroughCopy("src/css");
eleventyConfig.addPassthroughCopy("src/js");
eleventyConfig.addPassthroughCopy("src/images");
eleventyConfig.addPassthroughCopy("src/favicon-32x32.png"); // Adjust if needed
eleventyConfig.addPassthroughCopy("src/favicon-32x32.png");
eleventyConfig.addPassthroughCopy("robots.txt");
eleventyConfig.addPassthroughCopy("sitemap.xml");

// --- Filters ---
// Readable Date Filter (e.g., May 5, 2025)
eleventyConfig.addFilter("readableDate", (dateObj, format = "DD") => {
// Luxon format tokens: https://moment.github.io/luxon/#/formatting?id=table-of-tokens

return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat(format);
});

// HTML Date String Filter (e.g., 2025-05-05)
eleventyConfig.addFilter('htmlDateString', (dateObj) => {
return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd');
});

// Truncate Filter (for excerpts)
eleventyConfig.addFilter("truncate", (content, length = 150, end = "...") => {
if (!content || typeof content !== 'string') return '';
if (content.length <= length) return content;
let truncated = content.substring(0, length);
let lastSpace = truncated.lastIndexOf(' ');
if (lastSpace > length / 2) { // Only truncate at space if it's not too early
if (lastSpace > length / 2) {
truncated = truncated.substring(0, lastSpace);
}
return truncated + end;
});

// --- Shortcodes ---
// Current Year Shortcode
eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`);

// --- Return Eleventy Options ---
return {
dir: {
input: "src",
includes: "_includes",
layout: "_includes/layouts/", // <<< Define layouts subfolder
layout: "_includes/layouts/",
output: "docs"
},
passthroughFileCopy: true,
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk"
};
};
};
12 changes: 12 additions & 0 deletions src/_includes/base.njk → src/_includes/layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400&family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<title>{{ title | default("Aryan Gupta - Portfolio") }}</title>
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
<link rel="stylesheet" href="/css/navigation.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/research.css">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" ... />
</head>
Expand Down Expand Up @@ -51,6 +55,14 @@
Blogs
</a>
</li>
<li>
<a href="/research/">
<svg class="nav-icon" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
<path d="M16,5c0,0.552-0.448,1-1,1s-1-0.448-1-1s0.448-1,1-1S16,4.448,16,5z M7,18c-0.552,0-1,0.448-1,1 s0.448,1,1,1s1-0.448,1-1S7.552,18,7,18z M10,6.5C9.724,6.5,9.5,6.724,9.5,7S9.724,7.5,10,7.5s0.5-0.224,0.5-0.5S10.276,6.5,10,6.5z M11,11.5c-0.276,0-0.5,0.224-0.5,0.5s0.224,0.5,0.5,0.5s0.5-0.224,0.5-0.5S11.276,11.5,11,11.5z M6,9.5c-0.276,0-0.5,0.224-0.5,0.5 s0.224,0.5,0.5,0.5s0.5-0.224,0.5-0.5S6.276,9.5,6,9.5z M12.36,7c0-1.301-1.059-2.36-2.36-2.36S7.64,5.699,7.64,7 S8.699,9.36,10,9.36S12.36,8.301,12.36,7z M11.64,7c0,0.904-0.736,1.64-1.64,1.64S8.36,7.904,8.36,7S9.096,5.36,10,5.36 S11.64,6.096,11.64,7z M7.56,14.4c0-1.081-0.879-1.96-1.96-1.96s-1.96,0.879-1.96,1.96s0.879,1.96,1.96,1.96S7.56,15.48,7.56,14.4z M6.84,14.4c0,0.684-0.557,1.24-1.24,1.24s-1.24-0.557-1.24-1.24s0.557-1.24,1.24-1.24S6.84,13.716,6.84,14.4z M31.36,25.5V31 c0,0.199-0.161,0.36-0.36,0.36H9c-0.146,0-0.277-0.088-0.333-0.223s-0.025-0.289,0.078-0.393l3.667-3.666 c0.067-0.067,0.159-0.105,0.254-0.105H25.14V25.5c0-0.199,0.161-0.36,0.36-0.36h2.229c0.704-1.289,1.075-2.744,1.075-4.222 c0-3.116-1.64-5.983-4.304-7.57c-0.544,0.906-1.536,1.514-2.668,1.514c-0.525,0-1.021-0.131-1.454-0.361l-3.062,5.301 c-0.099,0.174-0.318,0.232-0.492,0.132l-1.275-0.736l-0.557,0.964l1.276,0.737c0.083,0.048,0.143,0.126,0.167,0.219 c0.025,0.092,0.012,0.19-0.036,0.272l-0.917,1.587c-0.099,0.173-0.317,0.232-0.492,0.132l-4.763-2.749 c-0.172-0.1-0.231-0.319-0.132-0.491l0.917-1.588c0.048-0.083,0.126-0.144,0.219-0.168c0.091-0.024,0.191-0.013,0.273,0.036 l1.276,0.736l0.556-0.964l-1.276-0.736c-0.083-0.048-0.143-0.126-0.167-0.218c-0.025-0.092-0.012-0.19,0.036-0.273l7.666-13.276 C17.652,2.074,15.378,1.36,13,1.36C6.582,1.36,1.36,6.582,1.36,13S6.582,24.64,13,24.64v0.721C6.185,25.36,0.64,19.815,0.64,13 S6.185,0.64,13,0.64c2.506,0,4.903,0.748,6.958,2.153l1.14-1.973c0.1-0.172,0.321-0.229,0.491-0.132l4.763,2.747 c0.083,0.048,0.144,0.126,0.168,0.219s0.012,0.19-0.036,0.273l-2.998,5.191c0.875,0.551,1.458,1.525,1.458,2.633 c0,0.326-0.051,0.64-0.145,0.936c2.923,1.708,4.727,4.832,4.727,8.23c0,1.468-0.339,2.915-0.984,4.222H31 C31.199,25.14,31.36,25.301,31.36,25.5z M12.734,19.688c-0.005-0.002-0.01-0.005-0.014-0.008l-1.262-0.729l-0.557,0.964l4.139,2.389 l0.557-0.963L12.734,19.688z M13.892,19.525l0.478,0.276l0.557-0.964l-0.964-0.557l-0.556,0.964L13.892,19.525z M19.784,14.09 c-0.65-0.57-1.062-1.407-1.062-2.338c0-1.714,1.396-3.109,3.11-3.109c0.35,0,0.687,0.058,1.001,0.165l2.846-4.929L21.54,1.492 l-8.806,15.25l1.26,0.728c0.005,0.003,0.011,0.006,0.016,0.009l1.092,0.631l1.771,1.021L19.784,14.09z M24.223,11.752 c0-1.317-1.072-2.39-2.39-2.39s-2.39,1.072-2.39,2.39c0,0.784,0.379,1.481,0.964,1.917c0.009,0.004,0.019,0.009,0.027,0.015 c0.029,0.017,0.055,0.036,0.077,0.059c0.379,0.252,0.833,0.399,1.321,0.399c0.972,0,1.81-0.583,2.183-1.417 c0.005-0.012,0.011-0.024,0.017-0.037C24.155,12.4,24.223,12.084,24.223,11.752z M30.64,25.86h-2.673 c-0.021-0.001-0.038-0.001-0.055,0H25.86v1.474c0,0.199-0.161,0.36-0.36,0.36H12.816L9.869,30.64H30.64V25.86z"/>
</svg>
Research
</a>
</li>
</ul>
</nav>
</header>
Expand Down
7 changes: 3 additions & 4 deletions src/_includes/layouts/post.njk
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
layout: 'base.njk'
layout: 'layouts/base.njk'
---

<article class="blog-post-full">
<h1>{{ title }}</h1> {# Display title from front matter #}
{% if date %} {# Display date if available #}
<h1>{{ title }}</h1>
{% if date %}
<p class="post-meta">
Published on <time datetime="{{ date | htmlDateString }}">{{ date | readableDate }}</time>
</p>
Expand All @@ -19,7 +19,6 @@ layout: 'base.njk'
</aside>
{% endif %}

{# Display the main post content (from Markdown) #}
{{ content | safe }}
</article>

Expand Down
30 changes: 30 additions & 0 deletions src/_includes/layouts/research-list.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
layout: 'layouts/base.njk'
---

<main>
<section id="research-list">
<h1>{{ title }}</h1>
<p class="intro">{{ content | safe }}</p>
Copy link

Copilot AI Jun 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping {{ content }} (which itself outputs <p> tags) inside another <p> leads to invalid nested paragraphs. Consider using a <div class="intro">…</div> or output raw content without an extra <p> wrapper.

Suggested change
<p class="intro">{{ content | safe }}</p>
<div class="intro">{{ content | safe }}</div>

Copilot uses AI. Check for mistakes.

<div class="article-list">
{% for post in collections.research | reverse %}
<article class="article-item">
<div class="article-title-line">
<h2><a href="{{ post.url | url }}">{{ post.data.title }}</a></h2>
{% if post.data.status %}
<span class="status-badge status-{{ post.data.status | slug }}">{{ post.data.status }}</span>
Comment on lines +15 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Using a slug filter on status may not handle all edge cases.

Sanitize or restrict status values to ensure valid CSS class names and prevent styling issues.

Suggested implementation:

                            <span class="status-badge status-{{ post.data.status | cssclass }}">{{ post.data.status }}</span>

You must define a cssclass filter in your Eleventy/Nunjucks configuration that:

  • Converts the string to lowercase,
  • Replaces spaces and invalid characters with hyphens,
  • Removes any characters not allowed in CSS class names (e.g., only a-z, 0-9, and hyphens).

Example (in your .eleventy.js config):

eleventyConfig.addFilter("cssclass", function(value) {
  return String(value)
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
});

{% endif %}
</div>
<p class="meta">
<time datetime="{{ post.date | htmlDateString }}">{{ post.date | readableDate("DDD") }}</time>
</p>
{% if post.data.description %}
<p class="excerpt">{{ post.data.description }}</p>
{% endif %}
<a href="{{ post.url | url }}" class="read-more">Read More &rarr;</a>
</article>
{% endfor %}
</div>
</section>
</main>
34 changes: 34 additions & 0 deletions src/_includes/layouts/research-post.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
layout: 'layouts/base.njk'
---

<div class="page-with-left-sidebar">

{# The "Left Leaf": TOC Sidebar #}
<aside class="page-sidebar">
<div class="toc-container sticky-toc">
<h2>Table of Contents</h2>
{{ content | toc | safe }}
</div>
</aside>

{# The "Middle Leaf": Main Article Content #}
<main class="page-content-main">
<article>
<header class="research-header">
<h1>{{ title }}</h1>
<p class="meta">
Published on <time datetime="{{ date | htmlDateString }}">{{ date | readableDate("DDD") }}</time>
{% if status == "In Progress" and lastUpdated %}
<br>
<span class="last-updated">Last updated on <time datetime="{{ lastUpdated | htmlDateString }}">{{ lastUpdated | readableDate("DDD") }}</time></span>
{% endif %}
</p>
</header>
<div class="research-content">
{{ content | safe }}
</div>
</article>
</main>

</div>
2 changes: 1 addition & 1 deletion src/blog/index.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
layout: base.njk
layout: layouts/base.njk
title: Blog
permalink: /blog/index.html
templateEngineOverride: njk, md
Expand Down
9 changes: 4 additions & 5 deletions src/css/base.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/* --- Basic Reset & Defaults --- */
* {
box-sizing: border-box; /* Makes padding/border calculation more intuitive */
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: 'Poppins', sans-serif; /* Assuming you added Poppins font */
font-family: 'Poppins', sans-serif;
line-height: 1.6;
background-color: #0f0f24; /* << Dark blue/purple background */
color: #dcdcdc; /* << Light grey default text */
background-color: #0f0f24;
color: #dcdcdc;
padding-top: 60px;
}
Loading