diff options
| author | Danilo M. <danix@danix.xyz> | 2026-04-17 11:58:02 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-04-17 11:58:02 +0200 |
| commit | 94a11324999f07feff138364633e8442947b628a (patch) | |
| tree | fe2f7d918a1829f504f7e5bdba7cffea2e1816f1 | |
| parent | 22f60cd3a437d369328f0eb75542602460c526d7 (diff) | |
| download | danixxyz-94a11324999f07feff138364633e8442947b628a.tar.gz danixxyz-94a11324999f07feff138364633e8442947b628a.zip | |
fix: use language-specific 404 layouts for proper i18n support
Created separate 404.html layouts in themes/danix-xyz-hacker/layouts/it/ and
themes/danix-xyz-hacker/layouts/en/ with hardcoded language-specific links.
Hugo automatically routes language requests to the correct layout, enabling
proper i18n context and translations. Removed generic 404.html and all
JavaScript detection hacks.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
| -rw-r--r-- | content/en/404.md | 5 | ||||
| -rw-r--r-- | content/it/404.md | 5 | ||||
| -rw-r--r-- | themes/danix-xyz-hacker/assets/js/not-found-page.js | 23 | ||||
| -rw-r--r-- | themes/danix-xyz-hacker/layouts/en/404.html (renamed from themes/danix-xyz-hacker/layouts/404.html) | 13 | ||||
| -rw-r--r-- | themes/danix-xyz-hacker/layouts/it/404.html | 151 |
5 files changed, 165 insertions, 32 deletions
diff --git a/content/en/404.md b/content/en/404.md new file mode 100644 index 0000000..ce95b59 --- /dev/null +++ b/content/en/404.md @@ -0,0 +1,5 @@ +--- +title: "404" +outputs: + - html +--- diff --git a/content/it/404.md b/content/it/404.md new file mode 100644 index 0000000..ce95b59 --- /dev/null +++ b/content/it/404.md @@ -0,0 +1,5 @@ +--- +title: "404" +outputs: + - html +--- diff --git a/themes/danix-xyz-hacker/assets/js/not-found-page.js b/themes/danix-xyz-hacker/assets/js/not-found-page.js index cec60bd..e86af02 100644 --- a/themes/danix-xyz-hacker/assets/js/not-found-page.js +++ b/themes/danix-xyz-hacker/assets/js/not-found-page.js @@ -31,29 +31,6 @@ document.addEventListener('alpine:init', () => { } })); - Alpine.data('notFoundNav', () => { - const isItalian = window.location.pathname.startsWith('/it/'); - return { - get homeLink() { - return isItalian ? '/it/' : '/'; - }, - get articlesLink() { - return isItalian ? '/it/articles/' : '/articles/'; - }, - get contactLink() { - return isItalian ? '/it/is/here/' : '/is/here/'; - }, - goHome() { - window.location.href = this.homeLink; - }, - goArticles() { - window.location.href = this.articlesLink; - }, - goContact() { - window.location.href = this.contactLink; - } - }; - }); console.log('notFoundPage Alpine component registered'); }); diff --git a/themes/danix-xyz-hacker/layouts/404.html b/themes/danix-xyz-hacker/layouts/en/404.html index 341f90b..6ed4892 100644 --- a/themes/danix-xyz-hacker/layouts/404.html +++ b/themes/danix-xyz-hacker/layouts/en/404.html @@ -1,10 +1,5 @@ {{ define "main" }} -<!-- Detect language from current URL --> -<script> -window.currentLang = window.location.pathname.startsWith('/it/') ? 'it' : 'en'; -</script> - <!-- Pass articles data to JavaScript for Alpine.js --> <script> window.articlesData = [ @@ -81,14 +76,14 @@ window.articlesData = [ </div> <!-- Navigation Links --> - <div class="space-y-4 flex flex-col items-center mb-12" x-data="notFoundNav()"> - <a :href="homeLink" @click.prevent="goHome()" class="btn btn-primary"> + <div class="space-y-4 flex flex-col items-center mb-12"> + <a href="/" class="btn btn-primary"> {{ i18n "goHome" }} </a> - <a :href="articlesLink" @click.prevent="goArticles()" class="btn btn-secondary"> + <a href="/articles/" class="btn btn-secondary"> {{ i18n "browseArticles" }} </a> - <a :href="contactLink" @click.prevent="goContact()" class="btn btn-outline"> + <a href="/is/here/" class="btn btn-outline"> {{ i18n "contactSupport" }} </a> </div> diff --git a/themes/danix-xyz-hacker/layouts/it/404.html b/themes/danix-xyz-hacker/layouts/it/404.html new file mode 100644 index 0000000..805b19a --- /dev/null +++ b/themes/danix-xyz-hacker/layouts/it/404.html @@ -0,0 +1,151 @@ +{{ define "main" }} + +<!-- Pass articles data to JavaScript for Alpine.js --> +<script> +window.articlesData = [ + {{ range (where .Site.RegularPages "Section" "articles") }} + { + title: '{{ .Title | safeJS }}', + url: '{{ .Permalink }}', + date: '{{ .Date.Format "Jan 02, 2006" }}', + content: '{{ (.Summary | plainify | safeJS) }}' + }, + {{ end }} +]; +</script> + +<main class="min-h-screen px-4 py-12"> + <div class="mx-auto px-4 py-12 max-w-4xl border border-border glow-accent rounded-lg bg-bg p-8" x-data="notFoundPage()"> + <div class="text-center"> + <!-- 404 Heading --> + <h1 class="text-7xl md:text-8xl font-bold text-accent mb-4 animate-fade-in"> + 404 + </h1> + + <!-- Error Message --> + <h2 class="text-3xl md:text-4xl font-bold mb-6"> + {{ i18n "notFound" }} + </h2> + + <p class="text-lg text-text-dim mb-8"> + {{ i18n "notFoundMessage" }} + </p> + + <!-- Search Box --> + <div class="mb-12"> + <form id="search-form" class="flex flex-col gap-4"> + <label for="search-input" class="sr-only">{{ i18n "searchPlaceholder" }}</label> + <input + id="search-input" + type="text" + placeholder="{{ (i18n "searchPlaceholder") }}" + class="px-4 py-3 border-2 border-border rounded focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent bg-bg text-text" + @input="filterArticles($el.value)" + /> + </form> + <div id="search-results" class="mt-4 text-left space-y-3" x-show="filteredArticles.length > 0"> + <template x-for="article in filteredArticles" :key="article.title"> + <div class="p-4 border-l-4 border-accent bg-bg/50 hover:bg-bg/70 transition-colors"> + <a :href="article.url" class="block text-left"> + <h4 class="font-bold text-accent hover:underline" x-text="article.title"></h4> + <p class="text-sm text-text-dim mt-1" x-text="article.date"></p> + </a> + </div> + </template> + </div> + <div x-show="searchQuery && filteredArticles.length === 0" class="mt-4 text-text-dim"> + {{ i18n "noSearchResults" }} + </div> + </div> + + <!-- Recent Articles Section --> + <div class="mb-12"> + <h3 class="text-2xl font-bold mb-6">{{ i18n "recentArticles" }}</h3> + <div class="space-y-4"> + {{ range first 5 (where .Site.RegularPages "Section" "articles") }} + <div class="p-4 border-l-4 border-accent bg-bg/50 hover:bg-bg/70 transition-colors"> + <a href="{{ .Permalink }}" class="block text-left"> + <h4 class="font-bold text-accent hover:underline">{{ .Title }}</h4> + <p class="text-sm text-text-dim mt-1"> + {{ .Date.Format "Jan 02, 2006" }} + </p> + </a> + </div> + {{ end }} + </div> + </div> + + <!-- Navigation Links --> + <div class="space-y-4 flex flex-col items-center mb-12"> + <a href="/it/" class="btn btn-primary"> + {{ i18n "goHome" }} + </a> + <a href="/it/articles/" class="btn btn-secondary"> + {{ i18n "browseArticles" }} + </a> + <a href="/it/is/here/" class="btn btn-outline"> + {{ i18n "contactSupport" }} + </a> + </div> + + <!-- Easter Egg Trigger --> + <div class="mt-12 pt-8 border-t border-border"> + <button + type="button" + @click="toggleEasterEgg()" + class="text-sm text-text-dim hover:text-accent transition-colors underline" + > + {{ i18n "followWhiteRabbit" }} + </button> + </div> + + <!-- Easter Egg Modal (Hidden by default) --> + <div + class="fixed inset-0 z-50" + :class="{ 'flex items-center justify-center': showEasterEgg, 'hidden': !showEasterEgg }" + x-show="showEasterEgg" + x-cloak + > + <!-- Overlay --> + <div + class="absolute inset-0 bg-black/50" + @click="showEasterEgg = false" + ></div> + + <!-- Modal Content --> + <div class="relative bg-bg border-2 border-accent p-8 rounded-lg shadow-xl max-w-md mx-4"> + <h2 class="text-2xl font-bold mb-6 text-accent">{{ i18n "easterEggTitle" }}</h2> + + <div class="space-y-4"> + <button + type="button" + @click="showEasterEgg = false; window.location.href = '{{ .Site.BaseURL }}it/'" + class="w-full btn btn-primary" + > + 💊 {{ i18n "bluePill" }} + </button> + + <button + type="button" + @click="goToRandomArticle()" + class="w-full btn btn-secondary" + > + 🐰 {{ i18n "redPill" }} + </button> + </div> + + <button + type="button" + @click="showEasterEgg = false" + class="absolute top-4 right-4 text-text-dim hover:text-text dark:hover:text-text transition-colors" + aria-label="Close modal" + > + ✕ + </button> + </div> + </div> + </div> + </div> +</main> + +{{ end }} |
