Compare commits

...

5 commits

9 changed files with 110 additions and 29 deletions

View file

@ -48,18 +48,24 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
// determine locale to resolve to
const pageLang = desiredLocale || (ctx.page && ctx.page.lang) || ctx.locale || defaultLanguage;
const LOCALE_URL_DEBUG = process.env.LOCALE_URL_DEBUG === "1" || process.env.LOCALE_URL_DEBUG === "true";
if (LOCALE_URL_DEBUG) {
console.warn(`[locale_url_resolve] resolving targetUrl="${targetUrl}" desiredLocale="${desiredLocale}" pageLang="${pageLang}"`);
}
// if requested locale is default, return the raw url
if (pageLang === defaultLanguage) {
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] requested locale is default (${defaultLanguage}) — returning raw URL "${targetUrl}"`);
return targetUrl;
// special case for homepage
if (targetUrl === "/" || targetUrl === "/index/") {
if (pageLang === defaultLanguage) {
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, default language (${defaultLanguage}) -> "/"`);
return "/";
}
const homepageUrl = `/${pageLang}/`;
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, language (${pageLang}) -> "${homepageUrl}"`);
return homepageUrl;
}
// normalize targetUrl to ensure trailing slash for comparison
const normUrl = targetUrl.endsWith("/") ? targetUrl : (targetUrl + "/");
// normalize targetUrl to include trailing slash for comparison
const normUrl = targetUrl.endsWith("/") ? targetUrl : `${targetUrl}/`;
// try to find the canonical (default language) page corresponding to targetUrl
let canonical = all.find(p => {
@ -83,7 +89,7 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
// if cannot find canonical page, fall back to a prefixed URL (best effort)
if (!canonical) {
const fallback = (`/${pageLang}${targetUrl}`).replace(/\/{2,}/g, "/");
const fallback = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/");
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] fallback -> "${fallback}"`);
return fallback;
}
@ -117,8 +123,8 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
return localized.url;
}
// no localized page found — fall back to prefixed path
const fallback2 = (`/${pageLang}${targetUrl}`).replace(/\/{2,}/g, "/");
// fallback to prefixed URL
const fallback2 = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/");
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] localized NOT found for key="${key}" — fallback -> "${fallback2}"`);
return fallback2;
});

30
_config/shortcodes.js Normal file
View file

@ -0,0 +1,30 @@
const seperator = {
start: '<!-- excerpt start -->',
end: '<!-- excerpt end -->',
total: '<!-- excerpt -->'
};
module.exports = function (eleventyConfig) {
// excerpt shortcode for feed layouts
// taken from https://github.com/brob/eleventy-plugin-blog-tools
eleventyConfig.addShortcode("excerpt", function (article) {
let excerpt = article.data.excerpt ? `<p>${article.data.excerpt}</p>` : "";
const articleContent = article.templateContent;
let startPosition = articleContent.toLowerCase().indexOf(seperator.start);
let endPosition = articleContent.toLowerCase().indexOf(seperator.end);
let totalPosition = articleContent.toLowerCase().indexOf(seperator.total)
if (totalPosition !== -1) {
excerpt = articleContent.substring(0, totalPosition);
} else if (startPosition !== -1 && endPosition !== -1) {
excerpt = articleContent.substring(startPosition + seperator.start.length, endPosition);
} else if (!article.data.excerpt) {
let startPosition = articleContent.toLowerCase().indexOf('<p>');
let endPosition = articleContent.toLowerCase().indexOf('</p>');
excerpt = articleContent.substring(startPosition + 3, endPosition);
}
return excerpt
});
};

View file

@ -1,7 +0,0 @@
const TIME_ZONE = "America/Santiago";
const defaultLanguage = "en";
module.exports = {
TIME_ZONE,
defaultLanguage
};

View file

@ -19,6 +19,11 @@ es = "música"
en = "etc"
es = "etc"
# blog
[read-more]
en = "read more..."
es = "leer más..."
# 404
[404]
en = "404 not found"

View file

@ -1,2 +1,4 @@
sitename = "yukinets"
motd = "kill everyone now!! condone first degree murder!!"
default_language = "en"
timezone = "America/Santiago"

View file

@ -1,5 +1,5 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% if title %} {{ title }} | {{ meta.sitename }} {% else %} {{ meta.sitename }} {% endif %}</title>
<title>{% if title %} {{ title }} | {{ site.sitename }} {% else %} {{ site.sitename }} {% endif %}</title>
<link rel="stylesheet" href="/css/{{ style if style else "main" }}.css">
<link rel="icon" type="image/png" href="/img/favicon.ico" width=16px>

View file

@ -1,9 +1,9 @@
<div class="header">
<h1>{{ meta.sitename }}</h1>
<h1>{{ site.sitename }}</h1>
<a href={{ "/" | locale_url_resolve }}><div class="header-banner" title="{{ "home" | i18n }}"></div></a>
<!--<div class="motd">
<marquee behavior="scroll" direction="left">
<p>{{ meta.motd }}</p>
<p>{{ site.motd }}</p>
</marquee>
</div>-->
</div>

37
_layouts/recent_feed.njk Normal file
View file

@ -0,0 +1,37 @@
{#
possible variables:
- cycling_tag: collection tag to cycle through
- sidebar: .njk include file as sidebar [optional]
#}
{% extends "_layouts/base.njk" %}
{% block content %}
{% if sidebar %}
<div id="feed-sidebar">
{% include sidebar %}
</div>
{% endif %}
<div id="feed">
<div class="true-content">
{{ content | safe }}
</div>
{% for post in collections[cycling_tag] | i18n_filter %}
<div class="feed-item">
<h2>2025</h2>
<h3 id="{{ post.data.title | slugify }}" class="post-title">{{ post.data.title }}</h3>
<p class="post-date">{{ post.date | date("dd/MM/yyyy") }}</p>
{#<p>Debug: {{ post.date }} -> {{ post.date | date("dd/MM/yyyy") }}</p>#}
{% if post.data.description %}
<p class="post-description">{{ post.data.description }}</p>
{% else %}
<p class="post-excerpt">{% excerpt post %}</p>
{% endif %}
<a href="{{ post.url | locale_url_resolve }}" class="post-link">{{ "read-more" | i18n }}</a>
{% if post.data.image %}
<img src="{{ post.data.image }}" alt="{{ post.data.image.alt }}" class="post-image">
{% endif %}
</div>
{% endfor %}
</div>
{% endblock content %}

View file

@ -1,9 +1,22 @@
const { TIME_ZONE, defaultLanguage } = require("./_config/utils");
const fs = require("fs");
const path = require("path");
const toml = require("@iarna/toml");
const addDateParsing = require("./_config/date");
const addFilters = require("./_config/filters");
const addPlugins = require("./_config/plugins");
const addShortcodes = require("./_config/shortcodes");
module.exports = function (eleventyConfig) {
let siteData;
const siteToml = fs.readFileSync(
path.join(__dirname, "_data", "site.toml"),
"utf-8"
);
siteData = toml.parse(siteToml);
eleventyConfig.addGlobalData("site", siteData);
eleventyConfig.setLayoutsDirectory("_layouts");
eleventyConfig.addPassthroughCopy("img");
@ -13,15 +26,10 @@ module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("robots.txt");
eleventyConfig.addPassthroughCopy("roms");
// add global site data for templates
// TODO: move _config/utils.js and global site data to _data/meta.toml
eleventyConfig.addGlobalData("site", {
defaultLocale: defaultLanguage
});
addDateParsing(eleventyConfig, { TIME_ZONE });
addFilters(eleventyConfig, { TIME_ZONE, defaultLanguage });
addPlugins(eleventyConfig, { defaultLanguage });
addDateParsing(eleventyConfig, { TIME_ZONE: siteData.timezone });
addFilters(eleventyConfig, { TIME_ZONE: siteData.timezone, defaultLanguage: siteData.default_language });
addPlugins(eleventyConfig, { defaultLanguage: siteData.default_language });
addShortcodes(eleventyConfig);
return {
markdownTemplateEngine: "njk",