update formatting of all js files

This commit is contained in:
yuki 2025-12-08 08:14:20 -03:00
parent 81412117d8
commit 96630677ca
Signed by: yuki
GPG key ID: 0C98E6FF04EC3915
10 changed files with 435 additions and 342 deletions

View file

@ -12,18 +12,27 @@ module.exports = function (eleventyConfig, { TIME_ZONE }) {
.startOf("day"); // Set to midnight in America/Santiago .startOf("day"); // Set to midnight in America/Santiago
} else if (typeof dateValue === "string" && dateValue) { } else if (typeof dateValue === "string" && dateValue) {
// handle string dates (ie from front matter, if used) // handle string dates (ie from front matter, if used)
localDate = DateTime.fromISO(dateValue, { zone: TIME_ZONE }).startOf("day"); localDate = DateTime.fromISO(dateValue, { zone: TIME_ZONE }).startOf(
"day",
);
} else { } else {
// handle invalid input // handle invalid input
console.warn(`Invalid date value: ${dateValue} for ${this.page.inputPath}`); console.warn(
`Invalid date value: ${dateValue} for ${this.page.inputPath}`,
);
localDate = DateTime.now().setZone(TIME_ZONE).startOf("day"); localDate = DateTime.now().setZone(TIME_ZONE).startOf("day");
} }
if (!localDate || localDate.isValid === false) { if (!localDate || localDate.isValid === false) {
throw new Error(`Invalid date value (${dateValue}) for ${this.page.inputPath}: ${localDate?.invalidReason || "Unknown"}`); throw new Error(
`Invalid date value (${dateValue}) for ${this.page.inputPath}: ${localDate?.invalidReason || "Unknown"}`,
);
} }
return localDate.toJSDate(); return localDate.toJSDate();
} catch (error) { } catch (error) {
console.error(`Date parsing error for ${this.page.inputPath}:`, error.message); console.error(
`Date parsing error for ${this.page.inputPath}:`,
error.message,
);
// fallback to current date in TIME_ZONE // fallback to current date in TIME_ZONE
return DateTime.now().setZone(TIME_ZONE).startOf("day").toJSDate(); return DateTime.now().setZone(TIME_ZONE).startOf("day").toJSDate();
} }

View file

@ -18,16 +18,24 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
return ""; return "";
} }
// format in TIME_ZONE // format in TIME_ZONE
const formatted = DateTime.fromJSDate(dt, { zone: TIME_ZONE }) const formatted = DateTime.fromJSDate(dt, { zone: TIME_ZONE }).toFormat(
.toFormat(format); format,
console.log("Date input:", dt, "Formatted:", formatted, "Timezone:", TIME_ZONE); );
console.log(
"Date input:",
dt,
"Formatted:",
formatted,
"Timezone:",
TIME_ZONE,
);
return formatted; return formatted;
}); });
// filters collections by current language // filters collections by current language
eleventyConfig.addFilter("i18n_filter", function (collection, limit = null) { eleventyConfig.addFilter("i18n_filter", function (collection, limit = null) {
const lang = this.page.lang; // access page.lang from context const lang = this.page.lang; // access page.lang from context
let filtered = collection.filter(item => item.data.lang === lang); let filtered = collection.filter((item) => item.data.lang === lang);
if (limit !== null) { if (limit !== null) {
filtered = filtered.slice(0, limit); filtered = filtered.slice(0, limit);
} }
@ -36,54 +44,84 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
// takes all collections and returns only the tags not matched // takes all collections and returns only the tags not matched
// key-objects so may repurpose under different name // key-objects so may repurpose under different name
eleventyConfig.addFilter("exclude_collections", function (collections, ...keysToExclude) { eleventyConfig.addFilter(
"exclude_collections",
function (collections, ...keysToExclude) {
if (!collections || typeof collections !== "object") { if (!collections || typeof collections !== "object") {
console.warn("[exclude_collections] Invalid collections input:", collections); console.warn(
"[exclude_collections] Invalid collections input:",
collections,
);
return collections; return collections;
} }
const result = {}; const result = {};
Object.keys(collections).forEach(key => { Object.keys(collections).forEach((key) => {
if (!keysToExclude.includes(key)) { if (!keysToExclude.includes(key)) {
result[key] = collections[key]; result[key] = collections[key];
} }
}); });
if (process.env.LOCALE_URL_DEBUG === "1" || process.env.LOCALE_URL_DEBUG === "true") { if (
process.env.LOCALE_URL_DEBUG === "1" ||
process.env.LOCALE_URL_DEBUG === "true"
) {
console.warn("[excludeCollections] Excluded keys:", keysToExclude); console.warn("[excludeCollections] Excluded keys:", keysToExclude);
console.warn("[excludeCollections] Resulting keys:", Object.keys(result)); console.warn(
"[excludeCollections] Resulting keys:",
Object.keys(result),
);
} }
return result; return result;
}); },
);
const LOCALE_URL_DEBUG = process.env.LOCALE_URL_DEBUG === "1" || process.env.LOCALE_URL_DEBUG === "true"; const LOCALE_URL_DEBUG =
process.env.LOCALE_URL_DEBUG === "1" ||
process.env.LOCALE_URL_DEBUG === "true";
// locale_url replacement that uses pre-compile filesystem // locale_url replacement that uses pre-compile filesystem
eleventyConfig.addNunjucksFilter("locale_url_resolve", function (targetUrl, desiredLocale) { eleventyConfig.addNunjucksFilter(
const ctx = (this && this.ctx) ? this.ctx : {}; "locale_url_resolve",
const collections = (ctx.collections) ? ctx.collections : {}; function (targetUrl, desiredLocale) {
const ctx = this && this.ctx ? this.ctx : {};
const collections = ctx.collections ? ctx.collections : {};
const all = collections.all || []; const all = collections.all || [];
if (!targetUrl || typeof targetUrl !== "string") return targetUrl; if (!targetUrl || typeof targetUrl !== "string") return targetUrl;
if (!targetUrl.startsWith("/")) return targetUrl; // external or relative link -> leave as is if (!targetUrl.startsWith("/")) return targetUrl; // external or relative link -> leave as is
// determine locale to resolve to // determine locale to resolve to
const pageLang = desiredLocale || (ctx.page && ctx.page.lang) || ctx.locale || defaultLanguage; 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"; const LOCALE_URL_DEBUG =
process.env.LOCALE_URL_DEBUG === "1" ||
process.env.LOCALE_URL_DEBUG === "true";
if (LOCALE_URL_DEBUG) { if (LOCALE_URL_DEBUG) {
console.warn(`[locale_url_resolve] resolving targetUrl="${targetUrl}" desiredLocale="${desiredLocale}" pageLang="${pageLang}"`); console.warn(
`[locale_url_resolve] resolving targetUrl="${targetUrl}" desiredLocale="${desiredLocale}" pageLang="${pageLang}"`,
);
} }
// special case for homepage // special case for homepage
if (targetUrl === "/" || targetUrl === "/index/") { if (targetUrl === "/" || targetUrl === "/index/") {
if (pageLang === defaultLanguage) { if (pageLang === defaultLanguage) {
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, default language (${defaultLanguage}) -> "/"`); if (LOCALE_URL_DEBUG)
console.warn(
`[locale_url_resolve] homepage, default language (${defaultLanguage}) -> "/"`,
);
return "/"; return "/";
} }
const homepageUrl = `/${pageLang}/`; const homepageUrl = `/${pageLang}/`;
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, language (${pageLang}) -> "${homepageUrl}"`); if (LOCALE_URL_DEBUG)
console.warn(
`[locale_url_resolve] homepage, language (${pageLang}) -> "${homepageUrl}"`,
);
return homepageUrl; return homepageUrl;
} }
@ -91,48 +129,73 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
const normUrl = targetUrl.endsWith("/") ? targetUrl : `${targetUrl}/`; const normUrl = targetUrl.endsWith("/") ? targetUrl : `${targetUrl}/`;
// try to find the canonical (default language) page corresponding to targetUrl // try to find the canonical (default language) page corresponding to targetUrl
let canonical = all.find(p => { let canonical = all.find((p) => {
return (p.url === normUrl || p.url === targetUrl) && p.data && p.data.lang === defaultLanguage; return (
(p.url === normUrl || p.url === targetUrl) &&
p.data &&
p.data.lang === defaultLanguage
);
}); });
// if not found, try to find any page with that url (maybe targetUrl already localized) // if not found, try to find any page with that url (maybe targetUrl already localized)
if (!canonical) { if (!canonical) {
canonical = all.find(p => (p.url === normUrl || p.url === targetUrl)); canonical = all.find((p) => p.url === normUrl || p.url === targetUrl);
} }
if (LOCALE_URL_DEBUG) { if (LOCALE_URL_DEBUG) {
if (canonical) { if (canonical) {
const cs = (canonical.page && canonical.page.filePathStem) ? canonical.page.filePathStem : "(no stem)"; const cs =
const clang = (canonical.data && canonical.data.lang) ? canonical.data.lang : "(no lang)"; canonical.page && canonical.page.filePathStem
console.warn(`[locale_url_resolve] canonical found: url="${canonical.url}" filePathStem="${cs}" lang="${clang}"`); ? canonical.page.filePathStem
: "(no stem)";
const clang =
canonical.data && canonical.data.lang
? canonical.data.lang
: "(no lang)";
console.warn(
`[locale_url_resolve] canonical found: url="${canonical.url}" filePathStem="${cs}" lang="${clang}"`,
);
} else { } else {
console.warn(`[locale_url_resolve] canonical NOT found for targetUrl="${targetUrl}". Will fallback to prefixed URL.`); console.warn(
`[locale_url_resolve] canonical NOT found for targetUrl="${targetUrl}". Will fallback to prefixed URL.`,
);
} }
} }
// if cannot find canonical page, fall back to a prefixed URL (best effort) // if cannot find canonical page, fall back to a prefixed URL (best effort)
if (!canonical) { 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}"`); if (LOCALE_URL_DEBUG)
console.warn(`[locale_url_resolve] fallback -> "${fallback}"`);
return fallback; return fallback;
} }
// determine canonical filePathStem (the source input path without extension) // determine canonical filePathStem (the source input path without extension)
const canonicalLang = canonical.data && canonical.data.lang ? canonical.data.lang : defaultLanguage; const canonicalLang =
const canonicalStem = (canonical.page && canonical.page.filePathStem) ? canonical.page.filePathStem : ""; canonical.data && canonical.data.lang
? canonical.data.lang
: defaultLanguage;
const canonicalStem =
canonical.page && canonical.page.filePathStem
? canonical.page.filePathStem
: "";
// remove the canonical lang prefix from the stem to create a "key" to match across locales. // remove the canonical lang prefix from the stem to create a "key" to match across locales.
// ie "/en/about" -> "/about", "/es/about" -> "/about" // ie "/en/about" -> "/about", "/es/about" -> "/about"
const key = canonicalStem.replace(new RegExp(`^/${canonicalLang}`), "").replace(/^\/+/, ""); const key = canonicalStem
.replace(new RegExp(`^/${canonicalLang}`), "")
.replace(/^\/+/, "");
if (LOCALE_URL_DEBUG) { if (LOCALE_URL_DEBUG) {
console.warn(`[locale_url_resolve] canonicalLang="${canonicalLang}" canonicalStem="${canonicalStem}" key="${key}"`); console.warn(
`[locale_url_resolve] canonicalLang="${canonicalLang}" canonicalStem="${canonicalStem}" key="${key}"`,
);
} }
// find the localized page whose filePathStem ends with that key and whose lang matches pageLang. // find the localized page whose filePathStem ends with that key and whose lang matches pageLang.
const localized = all.find(p => { const localized = all.find((p) => {
const pLang = p.data && p.data.lang; const pLang = p.data && p.data.lang;
const pStem = (p.page && p.page.filePathStem) ? p.page.filePathStem : ""; const pStem = p.page && p.page.filePathStem ? p.page.filePathStem : "";
// be defensive: ensure pLang exists // be defensive: ensure pLang exists
if (!pLang) return false; if (!pLang) return false;
return pLang === pageLang && pStem.endsWith(key); return pLang === pageLang && pStem.endsWith(key);
@ -140,19 +203,28 @@ module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
if (localized && localized.url) { if (localized && localized.url) {
if (LOCALE_URL_DEBUG) { if (LOCALE_URL_DEBUG) {
const ls = (localized.page && localized.page.filePathStem) ? localized.page.filePathStem : "(no stem)"; const ls =
console.warn(`[locale_url_resolve] localized found: url="${localized.url}" filePathStem="${ls}" lang="${localized.data.lang}"`); localized.page && localized.page.filePathStem
? localized.page.filePathStem
: "(no stem)";
console.warn(
`[locale_url_resolve] localized found: url="${localized.url}" filePathStem="${ls}" lang="${localized.data.lang}"`,
);
} }
return localized.url; return localized.url;
} }
// fallback to prefixed URL // fallback to prefixed URL
const fallback2 = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/"); const fallback2 = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/");
if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] localized NOT found for key="${key}" — fallback -> "${fallback2}"`); if (LOCALE_URL_DEBUG)
console.warn(
`[locale_url_resolve] localized NOT found for key="${key}" — fallback -> "${fallback2}"`,
);
return fallback2; return fallback2;
}); },
);
// turn on disabled nunjucks filters // turn on disabled nunjucks filters
eleventyConfig.addFilter("keys", obj => Object.keys(obj)); eleventyConfig.addFilter("keys", (obj) => Object.keys(obj));
eleventyConfig.addFilter("values", obj => Object.values(obj)); eleventyConfig.addFilter("values", (obj) => Object.values(obj));
}; };

View file

@ -9,7 +9,7 @@ module.exports = function (eleventyConfig, { defaultLanguage }) {
// load translations // load translations
const translationsToml = fs.readFileSync( const translationsToml = fs.readFileSync(
path.join(__dirname, "..", "_data", "locale.toml"), path.join(__dirname, "..", "_data", "locale.toml"),
"utf-8" "utf-8",
); );
const translations = toml.parse(translationsToml); const translations = toml.parse(translationsToml);
@ -23,7 +23,7 @@ module.exports = function (eleventyConfig, { defaultLanguage }) {
translations, translations,
fallbackLocales: { fallbackLocales: {
"*": "en", "*": "en",
} },
}); });
// data extensions // data extensions

View file

@ -1,7 +1,7 @@
const seperator = { const seperator = {
start: '<!-- excerpt start -->', start: "<!-- excerpt start -->",
end: '<!-- excerpt end -->', end: "<!-- excerpt end -->",
total: '<!-- excerpt -->' total: "<!-- excerpt -->",
}; };
module.exports = function (eleventyConfig) { module.exports = function (eleventyConfig) {
@ -13,18 +13,21 @@ module.exports = function (eleventyConfig) {
let startPosition = articleContent.toLowerCase().indexOf(seperator.start); let startPosition = articleContent.toLowerCase().indexOf(seperator.start);
let endPosition = articleContent.toLowerCase().indexOf(seperator.end); let endPosition = articleContent.toLowerCase().indexOf(seperator.end);
let totalPosition = articleContent.toLowerCase().indexOf(seperator.total) let totalPosition = articleContent.toLowerCase().indexOf(seperator.total);
if (totalPosition !== -1) { if (totalPosition !== -1) {
excerpt = articleContent.substring(0, totalPosition); excerpt = articleContent.substring(0, totalPosition);
} else if (startPosition !== -1 && endPosition !== -1) { } else if (startPosition !== -1 && endPosition !== -1) {
excerpt = articleContent.substring(startPosition + seperator.start.length, endPosition); excerpt = articleContent.substring(
startPosition + seperator.start.length,
endPosition,
);
} else if (!article.data.excerpt) { } else if (!article.data.excerpt) {
let startPosition = articleContent.toLowerCase().indexOf('<p>'); let startPosition = articleContent.toLowerCase().indexOf("<p>");
let endPosition = articleContent.toLowerCase().indexOf('</p>'); let endPosition = articleContent.toLowerCase().indexOf("</p>");
excerpt = articleContent.substring(startPosition + 3, endPosition); excerpt = articleContent.substring(startPosition + 3, endPosition);
} }
return excerpt return excerpt;
}); });
}; };

View file

@ -11,7 +11,7 @@ module.exports = function (eleventyConfig) {
let siteData; let siteData;
const siteToml = fs.readFileSync( const siteToml = fs.readFileSync(
path.join(__dirname, "_data", "site.toml"), path.join(__dirname, "_data", "site.toml"),
"utf-8" "utf-8",
); );
siteData = toml.parse(siteToml); siteData = toml.parse(siteToml);
@ -27,12 +27,15 @@ module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("roms"); eleventyConfig.addPassthroughCopy("roms");
addDateParsing(eleventyConfig, { TIME_ZONE: siteData.timezone }); addDateParsing(eleventyConfig, { TIME_ZONE: siteData.timezone });
addFilters(eleventyConfig, { TIME_ZONE: siteData.timezone, defaultLanguage: siteData.default_language }); addFilters(eleventyConfig, {
TIME_ZONE: siteData.timezone,
defaultLanguage: siteData.default_language,
});
addPlugins(eleventyConfig, { defaultLanguage: siteData.default_language }); addPlugins(eleventyConfig, { defaultLanguage: siteData.default_language });
addShortcodes(eleventyConfig); addShortcodes(eleventyConfig);
return { return {
markdownTemplateEngine: "njk", markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk" htmlTemplateEngine: "njk",
} };
}; };

View file

@ -12,7 +12,9 @@ module.exports = {
// for blog posts under /blog/[year]/[year-month-day]-blogpost // for blog posts under /blog/[year]/[year-month-day]-blogpost
// extract the year and the blog post slug (remove date prefix) // extract the year and the blog post slug (remove date prefix)
const blogPostMatch = stem.match(/^\/blog\/(\d{4})\/\d{4}-\d{2}-\d{2}-(.+)$/); const blogPostMatch = stem.match(
/^\/blog\/(\d{4})\/\d{4}-\d{2}-\d{2}-(.+)$/,
);
if (blogPostMatch) { if (blogPostMatch) {
const [, year, slug] = blogPostMatch; const [, year, slug] = blogPostMatch;
return `/blog/${year}/${slug}/index.html`; // ie /blog/2025/my-post/index.html return `/blog/${year}/${slug}/index.html`; // ie /blog/2025/my-post/index.html
@ -25,6 +27,6 @@ module.exports = {
// default for non-index, non-blog-post pages // default for non-index, non-blog-post pages
return `${stem}/index.html`; return `${stem}/index.html`;
} },
} },
}; };

View file

@ -17,5 +17,5 @@ module.exports = {
// for non-index files: append /index.html for pretty URLs (e.g., /blog/test-post → /blog/test-post/index.html, URL /blog/test-post/) // for non-index files: append /index.html for pretty URLs (e.g., /blog/test-post → /blog/test-post/index.html, URL /blog/test-post/)
return `${stem}/index.html`; return `${stem}/index.html`;
} },
}; };

View file

@ -15,7 +15,9 @@ module.exports = {
} }
// handle blog posts with date prefix: /es/blog/[year]/[year-month-day]-slug // handle blog posts with date prefix: /es/blog/[year]/[year-month-day]-slug
const blogPostMatch = stem.match(/^\/es\/blog\/(\d{4})\/\d{4}-\d{2}-\d{2}-(.+)$/); const blogPostMatch = stem.match(
/^\/es\/blog\/(\d{4})\/\d{4}-\d{2}-\d{2}-(.+)$/,
);
if (blogPostMatch) { if (blogPostMatch) {
const [, , slug] = blogPostMatch; const [, , slug] = blogPostMatch;
return `/es/blog/${year}/${this.slugify(slug)}/index.html`; return `/es/blog/${year}/${this.slugify(slug)}/index.html`;
@ -29,6 +31,6 @@ module.exports = {
// default for other pages under /es/blog/ // default for other pages under /es/blog/
return `${stem}/index.html`; // ie /es/other-page/index.html return `${stem}/index.html`; // ie /es/other-page/index.html
} },
} },
}; };

View file

@ -1,5 +1,5 @@
module.exports = { module.exports = {
lang: 'es', lang: "es",
permalink: function (data) { permalink: function (data) {
let stem = data.page.filePathStem; let stem = data.page.filePathStem;
@ -15,5 +15,5 @@ module.exports = {
// default for other pages // default for other pages
return `${stem}/index.html`; // e.g., /es/about/index.html return `${stem}/index.html`; // e.g., /es/about/index.html
} },
}; };

View file

@ -6,11 +6,11 @@ const BASE_URL = `https://lastfm-last-played.biancarosa.com.br/${USERNAME}/lates
const getTrack = async () => { const getTrack = async () => {
const request = await fetch(BASE_URL); const request = await fetch(BASE_URL);
const json = await request.json(); const json = await request.json();
let status let status;
let isPlaying = json.track['@attr']?.nowplaying || false; let isPlaying = json.track["@attr"]?.nowplaying || false;
if(!isPlaying) { if (!isPlaying) {
// Trigger if a song isn't playing // Trigger if a song isn't playing
return; return;
} else { } else {
@ -27,16 +27,18 @@ const getTrack = async () => {
<!--<h2>listening to:</h2>--> <!--<h2>listening to:</h2>-->
<a href="https://fm.yuki.k4w411.net/" target="_blank"> <a href="https://fm.yuki.k4w411.net/" target="_blank">
<div id="trackInfo"> <div id="trackInfo">
<img src="${json.track.image[1]['#text']}"> <img src="${json.track.image[1]["#text"]}">
<div id="trackInfoText"> <div id="trackInfoText">
<h3 id="trackName">${json.track.name}</h3> <h3 id="trackName">${json.track.name}</h3>
<p id="artistName">by ${json.track.artist['#text']}</p> <p id="artistName">by ${json.track.artist["#text"]}</p>
</div> </div>
</div> </div>
</a> </a>
</div> </div>
` `;
}; };
getTrack(); getTrack();
setInterval(() => { getTrack(); }, 10000); setInterval(() => {
getTrack();
}, 10000);