Convert .eleventy.js to EJS, add friends to index's aside, create playground page to test site elements, add syntax highlighting with custom theme, convert header subtitle from link to paragraph, add support for custom alt text in 88x31 macro, new template for generic text pages, add changelog to about page with recent commits.

This commit is contained in:
天クマ 2026-07-04 14:34:59 -03:00
commit ab071b0f78
18 changed files with 948 additions and 2524 deletions

View file

@ -1,14 +1,33 @@
const fs = require("fs");
const path = require("path");
const i18n = require('./_data/i18n.js');
import fs from "fs";
import path from "path";
module.exports = function(eleventyConfig) {
eleventyConfig.addCollection("post", function(collectionApi) {
return collectionApi.getFilteredByGlob("./posts/*").sort((a, b) => b.date - a.date);
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
import safeLinks from "@sardine/eleventy-plugin-external-links";
import pluginGitCommitDate from "eleventy-plugin-git-commit-date";
import recentChanges from "eleventy-plugin-recent-changes";
import Webmentions from "eleventy-plugin-webmentions"; // configure later
import pluginInlineLinkFavicon from "eleventy-plugin-inline-link-favicon";
// import i18n from "./_data/i18n.js";
export default function (eleventyConfig) {
eleventyConfig.setQuietMode(true);
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(safeLinks);
eleventyConfig.addPlugin(pluginGitCommitDate);
eleventyConfig.addPlugin(recentChanges, {
commits: 10,
});
eleventyConfig.addCollection("misc", (api) =>
api.getFilteredByTag("misc")
);
eleventyConfig.addPlugin(pluginInlineLinkFavicon);
eleventyConfig.addCollection("post", function (collectionApi) {
return collectionApi
.getFilteredByGlob("./posts/*")
.sort((a, b) => b.date - a.date);
});
eleventyConfig.addCollection("misc", (api) => api.getFilteredByTag("misc"));
eleventyConfig.addFilter("getTranslation", (page, lang) => {
const dir = path.dirname(page.inputPath);
const file = path.join(dir, `${lang}.json`);
@ -19,26 +38,34 @@ module.exports = function(eleventyConfig) {
return {};
});
eleventyConfig.addCollection("88x31", () => {
return fs.readdirSync("static/images/88x31")
.map(file => ({
return fs
.readdirSync("static/images/88x31")
.map((file) => ({
url: `/static/images/88x31/${file}`,
fileSlug: file
fileSlug: file,
}));
});
eleventyConfig.addPassthroughCopy("static");
eleventyConfig.addNunjucksFilter("alternateLanguages", function(collection, postId, currentLanguageKey) {
return collection.filter(post =>
post.data.postId === postId && post.data.langKey !== currentLanguageKey
eleventyConfig.addNunjucksFilter(
"alternateLanguages",
function (collection, postId, currentLanguageKey) {
return collection
.filter(
(post) =>
post.data.postId === postId &&
post.data.langKey !== currentLanguageKey
)
.map(post => ({
.map((post) => ({
lang: post.data.langKey,
url: post.url,
title: post.data.title
}))
});
title: post.data.title,
}));
}
);
eleventyConfig.addFilter("absoluteUrl", function (url) {
const base = "https://adrianvic.github.io";
@ -52,24 +79,65 @@ module.exports = function(eleventyConfig) {
year: "numeric",
month: "numeric",
day: "numeric",
timeZone: "America/Sao_Paulo"
timeZone: "America/Sao_Paulo",
});
});
eleventyConfig.addNunjucksFilter("smartTitle", function (str) {
if (!str) return "";
const smallWords = ["a","an","and","at","but","by","for","in","nor","of","on","or","so","the","to","up","yet",
"e","de","do","da","dos","das","a","o","um","uma","em","por","para","com","no","na","nos"];
return str.toLowerCase().split(" ").map((word, i) => {
const smallWords = [
"a",
"an",
"and",
"at",
"but",
"by",
"for",
"in",
"nor",
"of",
"on",
"or",
"so",
"the",
"to",
"up",
"yet",
"e",
"de",
"do",
"da",
"dos",
"das",
"a",
"o",
"um",
"uma",
"em",
"por",
"para",
"com",
"no",
"na",
"nos",
];
return str
.toLowerCase()
.split(" ")
.map((word, i) => {
if (i === 0) return word.charAt(0).toUpperCase() + word.slice(1);
return smallWords.includes(word) ? word : word.charAt(0).toUpperCase() + word.slice(1);
}).join(" ");
return smallWords.includes(word)
? word
: word.charAt(0).toUpperCase() + word.slice(1);
})
.join(" ");
});
return {
pathPrefix: process.env.GITHUB_ACTIONS ? "" : "/tenkuma/web",
dir: {
output: "docs"
output: "docs",
},
};
}
};
};

View file

@ -92,7 +92,8 @@ module.exports = {
previous: "previous",
next: "next",
about: "about",
thisWebsiteDoesNotTrackYou: "This website does not track you."
thisWebsiteDoesNotTrackYou: "This website does not track you.",
mrnandoChannel: "Mr. Nando's channel"
},
pt: {
language: "português",
@ -160,6 +161,7 @@ module.exports = {
previous: "anterior",
next: "próximo",
about: "sobre",
thisWebsiteDoesNotTrackYou: "Esse website não rastreia você."
thisWebsiteDoesNotTrackYou: "Esse website não rastreia você.",
mrnandoChannel: "Canal do Mr. Nando"
}
};

View file

@ -14,6 +14,7 @@
<title>Adrian Victor{% if pageTitle or postTitle %} - {{ pageTitle or postTitle }}{% endif %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ '/static/main.css?fixcache=1' | url }}">
<link href="{{ '/static/prism.css' | url }}" rel="stylesheet"/>
<script type="module" src="{{ '/static/scripts/ccd.js' | url }}"></script>
<script type="module" src="{{ '/static/scripts/music.js' | url }}" defer></script>
<script type="module" src="{{ '/static/scripts/88x31.js' | url }}" defer></script>

View file

@ -1,7 +1,7 @@
<header>
<div>
<h1>{{ title or "Adrian Victor" }}</h1>
<a id="headerSubtitle"><i>{{ subtitle or "Fanasy is not a crime, find your castle in the sky." }}</i></a>
<p id="headerSubtitle"><i>{{ subtitle or "Fanasy is not a crime, find your castle in the sky." }}</i></p>
<script>
const headeri18n =
{
@ -20,10 +20,16 @@
<div id="music"></div>
<ul id="headerLinks">
{% if langKey %}
<a href="{{ ('/' ~ langKey ~ '/') | url }}">{{ i18n[langKey].home }}</a>
<a href="{{ ('/' ~ langKey ~ '/blog/') | url }}">blog</a>
<a href="{{ ('/' ~ langKey ~ '/misc/') | url }}">misc</a>
{% endif %}
{% if langKey == undefined %}
<a href="{{ ('/') | url }}">home</a>
{% endif %}
<a rel="me" href="https://mstdn.social/@tenkuma" style="display: none;">Mastodon</a>
<a href="https://github.com/adrianvic" rel="me" style="display: none;">github.com/aaronpk</a>
</ul>
</div>
</header>

View file

@ -1,8 +1,14 @@
{% macro i88x31(link) %}
{% macro i88x31(link, alt=link) %}
<img
class="i88x31"
src="{{ ('/static/images/88x31/' ~ link) | url }}"
{% if alt == link %}
data-tip="<b>{{ i18n[langKey].i88x31hover }}</b> ({{ link }})"
{% endif %}
{% if alt != link %}
data-tip="{{ alt }}"
{% endif %}
alt="{{ alt }}"
>
{% endmacro %}
@ -37,7 +43,7 @@
</a>
</div>
<div class="hsProjectContent">
<p>{{ projectDescription }}</p>
<p>{{ projectDescription | safe }}</p>
</div>
</div>
{% endmacro %}

6
_includes/text.njk Normal file
View file

@ -0,0 +1,6 @@
---
layout: base.njk
---
<main class="fullWidth">
{{ content | safe }}
</main>

View file

@ -187,6 +187,15 @@ layout: base.njk
<p class="end-text"><a href="{{ ('/' ~ langKey ~ '/blog/') | url }}">{{ i18n[langKey].showMore }}</a></p>
</div>
<div id="homeFriends">
<div>
<h1 class="nomargin negativeMargin">Friends</h1>
<hr style="margin-bottom: .4em;">
</div>
<a href="https://www.youtube.com/@mrnandokk">{{ i88x31("mrnandokk.gif", i18n[langKey].mrnandoChannel) }}</a>
</div>
<div id="homeWebrings">
<div>
<h1 class="nomargin negativeMargin">Webrings</h1>

View file

@ -19,6 +19,7 @@ tags: misc
<h2>{{ t.me }}</h2>
<div class="homeBadgesBox">
{{ i88x31("tenkuma.gif") }}
{{ i88x31("mrnandokk.gif") }}
</div>
<h2>{{ t.others }}</h2>
<div class="homeBadgesBox">

View file

@ -33,3 +33,16 @@ background: "bear3.jpg"
<dd>{{ t.githubPagesDesc }}</dd>
</dl>
</main>
<aside>
<div id="aboutChangelog">
<div>
<h1 class="nomargin negativeMargin">Changelog</h1>
<hr style="margin-bottom: .4em;">
</div>
<ul>
{%- for commit in collections.recentChanges %}
<li><b>{{ commit.abbrevHash }}</b> {{ commit.subject }}</li>
{%- endfor %}
</ul>
</div>
</aside>

2934
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,5 +11,13 @@
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
"type": "module",
"dependencies": {
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
"@sardine/eleventy-plugin-external-links": "^1.4.0",
"eleventy-plugin-git-commit-date": "^1.0.2",
"eleventy-plugin-inline-link-favicon": "^1.1.0",
"eleventy-plugin-recent-changes": "^1.0.1",
"eleventy-plugin-webmentions": "^2.1.0"
}
}

89
playground.njk Normal file
View file

@ -0,0 +1,89 @@
---
layout: text.njk
---
{% from "macros.njk" import i88x31 with context %}
{% from "macros.njk" import webring %}
{% from "macros.njk" import projectCard %}
{% from "macros.njk" import videoCard with context %}
<div class="box pageHeaderBox">
<h1>Playground</h1>
<p>This is a test page showcasing different elements from the website. By the way, this box is a page header box, which is a regular box without margin followed by a separator.</p>
</div>
<hr>
<h2>Text</h2>
<p>Flowers are red, they can also be blue. Just like <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=RDdQw4w9WgXcQ&start_radio=1&pp=ygUXbmV2ZXIgZ29ubmEgZ2l2ZSB5b3UgdXCgBwE%3D">links</a>. I'm not much of a poet... Anyways, did I get the link contrast right this time? And the paragraph spacing?</p>
<h3>Bolinho de Chuva</h3>
<p>Did you know here in Brazil we have a dessert literally called Bolinho de Chuva (lit. "rain cake")? It's basically fried dough with sugar, the best ones have banana inside. The tradition is to make them when it's raining, I have a lot of childhood memories of eating this and thinking of this now makes me realize it may be one of the reasons I like rain so much. Don't get me wrong, I hate being <i>in</i> the rain, I swear I can feel each drop puncturing me like a needle. What I like is to stay home and listen to the gentle song of falling droplets.</p>
<p>I was eating one when I wrote this.</p>
<h2>Alert box</h2>
<div class="box alert">
<p>This is a alert box.</p>
</div>
<h2>Code block</h2>
<p>Uses Eleventy highlight plugin, Prism CSS by RunDevelopment slightly edited to fit the website design language.</p>
{% highlight "js" %}
function myFunction() {
return true;
}
{% endhighlight %}
<h2>88x31 interactive images</h2>
<p>88x31 are looking too small on modern monitors, so you can now click on them to expand.</p>
{{ i88x31("tenkuma.gif") }}
{{ i88x31("anybrowser6.gif") }}
{{ i88x31("ai.gif") }}
{{ i88x31("WEBP.gif") }}
<h2>Webring widget</h2>
<p>Generic webring widget with custom background, link color and links.</p>
{{ webring({
text: "Breakcore Webring",
links: [
"<a href='https://webri.ng/webring/breakcoreweb/previous?via=https%3A%2F%2Fadrianvic.github.io%2F'>First</a>",
"<a href='https://appak.neocities.org/breakcore'>Second</a>",
"<a href='https://webri.ng/webring/breakcoreweb/next?via=https%3A%2F%2Fadrianvic.github.io%2F'>Third</a>"
],
image: "/static/images/metro-flowers.jpg"
}) }}
<h2>Project card</h2>
<p>These are used in the homepage to list my repos.</p>
{{
projectCard(
"Example project",
"I'm probably not entering heaven for this terrible picture I made of my Minecraft skin. Now I cannot delete it from the website files because it's being used here. I even had the balls to call it <a href='" ~ ('/static/images/me.png' | url ) ~ "'>me.png</a>.",
('/static/images/me.png' | url ),
'/static/images/me.png',
"PestoWiki"
)
}}
<h2>Video card</h2>
<p>The image, website and video duration are hardcoded so you don't ping any server to pull it (and it works without JS). Of course none of that is relevant to you, this site source is a mess so you don't have to deal with privacy invasive bullshit, I'm just stating that to fill space after the title, spacing is strange with no text here.</p>
<div style="width: 50%; margin: auto;">
{{
videoCard(
i18n["global"].homeVideoLink,
"I don't know the video title, it's pulling from the global string table.",
i18n["global"].homeVideoImage,
i18n["global"].homeVideoWebsite,
i18n["global"].homeVideoDuration
)
}}
</div>
<h2>Recent commits</h2>
<p>Thanks to <a href="https://www.npmjs.com/package/eleventy-plugin-recent-changes">workeffortwaste's eleventy-plugin-recent-changes</a> <3</p>
<ul>
{%- for commit in collections.recentChanges %}
<li><time>{{ commit.authorDate }}</time> {{ commit.subject }}</li>
{%- endfor %}
</ul>
<h2>Link with favicon</h2>
<p>Here's a link to {% ai "https://github.com/adrianivc" %}my github page{% endai %}. Thanks to <a href="https://www.npmjs.com/package/eleventy-plugin-recent-changes">bmuenzenmeyer's eleventy-plugin-inline-link-favicon</a> <3</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View file

@ -254,6 +254,10 @@ footer a {
height: 1em;
}
.fullWidth {
width: 100%;
}
.notificationBox {
transition: transform 1s cubic-bezier(0.19, 1, 0.22, 1);
width: fit-content;
@ -569,6 +573,11 @@ div.hs.selected {
opacity: 0 !important;
}
article {
max-width: 70%;
margin: auto;
}
.blogpostYoutubeVideo {
user-select: none;
box-shadow: 2px 7px 5px rgba(0, 0, 0, 0.3), 0px -4px 10px rgba(0, 0, 0, 0.3);
@ -712,6 +721,10 @@ div.hs.selected {
background-size: cover;
}
.webringGeneric p {
margin: 0;
}
.webringButtons {
display: flex;
gap: .4em;
@ -1059,6 +1072,11 @@ header div:first-child {
@media screen and (max-width: 1280px) {
body { font-size: 2vh; }
article {
max-width: 100%;
margin: auto;
}
header {
padding-top: 1.4rem;
text-align: center;

139
static/prism.css Normal file
View file

@ -0,0 +1,139 @@
/**
* Coy without shadows
* Based on Tim Shedor's Coy theme for prism.js
* Author: RunDevelopment
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
position: relative;
border-left: 10px solid rgba(255, 255, 255, 0.2);
background-color: rgba(0, 0, 0, 0.6);
background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-size: 3em 3em;
background-origin: content-box;
background-attachment: local;
margin: .5em 0;
padding: 0 1em;
}
pre[class*="language-"] > code {
display: block;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
position: relative;
padding: .2em;
border-radius: 0.3em;
color: #c92c2c;
border: 1px solid rgba(0, 0, 0, 0.1);
display: inline;
white-space: normal;
background-color: #fdfdfd;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.token.comment,
.token.block-comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #7D8B99;
}
.token.punctuation {
color: #5F6364;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.function-name,
.token.constant,
.token.symbol,
.token.deleted {
color: #c92c2c;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.function,
.token.builtin,
.token.inserted {
color: #2f9c0a;
}
.token.operator,
.token.entity,
.token.url,
.token.variable {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword,
.token.class-name {
color: #1990b8;
}
.token.regex,
.token.important {
color: #e90;
}
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.important {
font-weight: normal;
}
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.token.namespace {
opacity: .7;
}