This commit is contained in:
parent
cdd46e34a4
commit
ecd7081098
3 changed files with 86 additions and 27 deletions
|
@ -19,7 +19,7 @@ for (const [lang, langData] of Object.entries(blog_list.languages)) {
|
||||||
// Remove the file extension (e.g. "page.md" becomes "page")
|
// Remove the file extension (e.g. "page.md" becomes "page")
|
||||||
const postSlug = canonicalId.replace(/\.md$/, '');
|
const postSlug = canonicalId.replace(/\.md$/, '');
|
||||||
// Build the localized route (e.g. "/en/article/page")
|
// Build the localized route (e.g. "/en/article/page")
|
||||||
blog_nitro_routes.push(`/${lang}/article/${postSlug}`);
|
blog_nitro_routes.push(`/${lang}/article/${lang}/${categoryName.toLowerCase()}/${postSlug}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,9 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
routeRules: {
|
routeRules: {
|
||||||
"/article/:category:/:id": {
|
"/article/:lang/:category:/:id": {
|
||||||
redirect: "/article/:category:/:id/index.html",
|
redirect: "/article/:lang/:category:/:id/index.html",
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
pageTransition: {
|
pageTransition: {
|
||||||
|
@ -54,7 +54,10 @@ export default defineNuxtConfig({
|
||||||
"@nuxtjs/i18n",
|
"@nuxtjs/i18n",
|
||||||
],
|
],
|
||||||
i18n: {
|
i18n: {
|
||||||
|
strategy: 'prefix_and_default',
|
||||||
|
defaultLocale: 'en',
|
||||||
vueI18n: './i18n.config.ts',
|
vueI18n: './i18n.config.ts',
|
||||||
|
baseUrl: process.env.SITE_BASE_URL,
|
||||||
locales: [
|
locales: [
|
||||||
{
|
{
|
||||||
code: 'en',
|
code: 'en',
|
||||||
|
@ -62,7 +65,7 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: 'tp',
|
code: 'tp',
|
||||||
name: 'Toki Pona'
|
name: 'toki pona'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,9 @@ const background: Ref<string> = ref('');
|
||||||
const next: Ref<string> = ref('');
|
const next: Ref<string> = ref('');
|
||||||
const previous: Ref<string> = ref('');
|
const previous: Ref<string> = ref('');
|
||||||
|
|
||||||
|
import page_list_Data from "~/assets/meta/post_list.json"
|
||||||
|
const page_list = page.PageList.fromJSON(JSON.stringify(await page_list_Data))
|
||||||
|
|
||||||
function tagsToString(tags: String[]): string {
|
function tagsToString(tags: String[]): string {
|
||||||
var tagString = '';
|
var tagString = '';
|
||||||
for (let i = 0; i < tags.length; i++) {
|
for (let i = 0; i < tags.length; i++) {
|
||||||
|
@ -62,6 +65,7 @@ watch(route, async () => {
|
||||||
}, {
|
}, {
|
||||||
immediate: true
|
immediate: true
|
||||||
});
|
});
|
||||||
|
import * as page from "~/utils/page_updater/update_pagelist"
|
||||||
|
|
||||||
async function fetchArticle(url: string, region?: string): Promise<any> {
|
async function fetchArticle(url: string, region?: string): Promise<any> {
|
||||||
if (!url) {
|
if (!url) {
|
||||||
|
@ -70,19 +74,30 @@ async function fetchArticle(url: string, region?: string): Promise<any> {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Trim the .md extension
|
// Trim the .md extension
|
||||||
var trimmedUrl = url.replace(/\.md$/, '');
|
const trimmedUrl = url.replace(/^\//, '').replace(/\.md$/, '');
|
||||||
console.log('[id].vue - Fetching article: ' + trimmedUrl);
|
console.log('[id].vue - Fetching article: ' + trimmedUrl);
|
||||||
|
|
||||||
// Define the available languages in the order of preference (falling back on the next if one fails)
|
// Define the available languages in the order of preference (falling back on the next if one fails)
|
||||||
const languages = [region ? region : locale.value, 'en', 'fr', 'de']; // Add all available languages in order of preference
|
const languages = [region ? region : locale.value, 'en', 'fr', 'de']; // Add all available languages in order of preference
|
||||||
console.log(languages)
|
console.log(languages);
|
||||||
let dataFound = false;
|
let dataFound = false;
|
||||||
let data: any = null;
|
let data: any = null;
|
||||||
|
|
||||||
|
// Check the presence of the article in each language using page utility
|
||||||
for (let lang of languages) {
|
for (let lang of languages) {
|
||||||
console.log(`Querying ${lang}${trimmedUrl}`)
|
// Check if the page exists in the specified language
|
||||||
|
const pageExists = page_list.pageExistsInLang(lang, trimmedUrl);
|
||||||
|
console.log(`Checking if article exists for language ${lang}: ${pageExists}`);
|
||||||
|
|
||||||
|
if (!pageExists) {
|
||||||
|
console.warn(`Article does not exist for language ${lang}`);
|
||||||
|
continue; // Skip this language and try the next one
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the page exists, fetch its content
|
||||||
|
console.log(`Querying /${lang}/${trimmedUrl}`);
|
||||||
const { data: languageData, error } = await useAsyncData(`${lang}/${trimmedUrl}`, () =>
|
const { data: languageData, error } = await useAsyncData(`${lang}/${trimmedUrl}`, () =>
|
||||||
queryContent(`${lang}${trimmedUrl}`).findOne()
|
queryContent(`/${lang}/${trimmedUrl}`).findOne()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (error.value) {
|
if (error.value) {
|
||||||
|
@ -138,13 +153,8 @@ const data = await fetchArticle(url.value);
|
||||||
updateMetadata(data);
|
updateMetadata(data);
|
||||||
|
|
||||||
console.log('Prefetching article');
|
console.log('Prefetching article');
|
||||||
onMounted(async () => {
|
|
||||||
console.log('Fetching article :3');
|
|
||||||
await fetchArticle(url.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const temp_url = route.query.post as string;
|
const temp_url = route.query.post as string;
|
||||||
await fetchArticle(temp_url);
|
|
||||||
|
|
||||||
const fullTitle = data.title + ' | ' + siteConfig.siteTitle;
|
const fullTitle = data.title + ' | ' + siteConfig.siteTitle;
|
||||||
|
|
||||||
|
@ -211,14 +221,14 @@ useSeoMeta({
|
||||||
<div>
|
<div>
|
||||||
<!-- Next/Prev controls, on the left and right side using PostCards -->
|
<!-- Next/Prev controls, on the left and right side using PostCards -->
|
||||||
<div class="flex max-w-4xl max-md:w-screen">
|
<div class="flex max-w-4xl max-md:w-screen">
|
||||||
<div class="justify-start">
|
<!--<div class="justify-start">
|
||||||
<NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous"
|
<NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous"
|
||||||
class="m-2 text-white">Previous</NuxtLink>
|
class="m-2 text-white">Previous</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="justify-end">
|
<div class="justify-end">
|
||||||
<NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next"
|
<NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next"
|
||||||
class="m-2 text-white">Next</NuxtLink>
|
class="m-2 text-white">Next</NuxtLink>
|
||||||
</div>
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Article Content -->
|
<!-- Article Content -->
|
||||||
|
@ -230,12 +240,12 @@ useSeoMeta({
|
||||||
<!-- Aligned next/prev controls -->
|
<!-- Aligned next/prev controls -->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="justify-start">
|
<div class="justify-start">
|
||||||
<NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous"
|
<!--<NuxtLink v-if="previous" :onclick="resetReadingPosition" :to="previous"
|
||||||
class="m-2 text-white">Previous</NuxtLink>
|
class="m-2 text-white">Previous</NuxtLink>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="justify-end">
|
<div class="justify-end">
|
||||||
<NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next"
|
<!--<NuxtLink v-if="next" :onclick="resetReadingPosition" :to="next"
|
||||||
class="m-2 text-white">Next</NuxtLink>
|
class="m-2 text-white">Next</NuxtLink>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import * as pages from "./pages.ts";
|
import * as pages from "./pages.ts";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
|
||||||
|
@ -196,6 +195,51 @@ export class PageList {
|
||||||
pages: data.pages,
|
pages: data.pages,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a page exists in any language.
|
||||||
|
* @param canonicalId - The canonical ID of the page (language prefix removed)
|
||||||
|
* @returns True if the page exists in any language, otherwise false.
|
||||||
|
*/
|
||||||
|
pageExists(canonicalId: string): boolean {
|
||||||
|
for (const lang of Object.keys(this.languages)) {
|
||||||
|
const categories = this.languages[lang].categories;
|
||||||
|
for (const categoryName of Object.keys(categories)) {
|
||||||
|
const page = categories[categoryName].posts.find(
|
||||||
|
(p) => PageList.getCanonicalId(p.id) === canonicalId,
|
||||||
|
);
|
||||||
|
if (page) {
|
||||||
|
return true; // Page found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // Page not found in any language
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a page exists in a specific language.
|
||||||
|
* @param lang - The language code (e.g., "en")
|
||||||
|
* @param canonicalId - The canonical ID of the page (language prefix removed)
|
||||||
|
* @returns True if the page exists in the specified language, otherwise false.
|
||||||
|
*/
|
||||||
|
pageExistsInLang(lang: string, canonicalId: string): boolean {
|
||||||
|
const categories = this.languages[lang]?.categories;
|
||||||
|
if (!categories) {
|
||||||
|
return false; // Language not found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each category for the page with the given canonical ID
|
||||||
|
for (const categoryName of Object.keys(categories)) {
|
||||||
|
const page = categories[categoryName].posts.find(
|
||||||
|
p => p.id == canonicalId
|
||||||
|
);
|
||||||
|
if (page) {
|
||||||
|
return true; // Page found in this language
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // Page not found in the specified language
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,7 +248,9 @@ export class PageList {
|
||||||
* @param pagesInfo - An object where keys are paths (e.g., "content/[lang]/...") and values are page data.
|
* @param pagesInfo - An object where keys are paths (e.g., "content/[lang]/...") and values are page data.
|
||||||
* @returns A PageCategory object containing an array of Page objects.
|
* @returns A PageCategory object containing an array of Page objects.
|
||||||
*/
|
*/
|
||||||
export function generatePageCategory(pagesInfo: Record<string, any>): PageCategory {
|
export function generatePageCategory(
|
||||||
|
pagesInfo: Record<string, any>,
|
||||||
|
): PageCategory {
|
||||||
const pageList: Page[] = [];
|
const pageList: Page[] = [];
|
||||||
|
|
||||||
for (const [filePath, page] of Object.entries(pagesInfo)) {
|
for (const [filePath, page] of Object.entries(pagesInfo)) {
|
||||||
|
@ -236,7 +282,7 @@ export function generatePageCategory(pagesInfo: Record<string, any>): PageCatego
|
||||||
title: "",
|
title: "",
|
||||||
description: "",
|
description: "",
|
||||||
tags: [],
|
tags: [],
|
||||||
show: true
|
show: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +305,7 @@ export const postDirectories: pages.PageLocation[] = [
|
||||||
tags: ["site"],
|
tags: ["site"],
|
||||||
map: "site",
|
map: "site",
|
||||||
root: "", // Not used in the new structure
|
root: "", // Not used in the new structure
|
||||||
show: false
|
show: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Collections",
|
title: "Collections",
|
||||||
|
@ -268,7 +314,7 @@ export const postDirectories: pages.PageLocation[] = [
|
||||||
tags: ["collection"],
|
tags: ["collection"],
|
||||||
map: "collections",
|
map: "collections",
|
||||||
root: "",
|
root: "",
|
||||||
show: true
|
show: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Guides",
|
title: "Guides",
|
||||||
|
@ -276,6 +322,6 @@ export const postDirectories: pages.PageLocation[] = [
|
||||||
tags: ["guide"],
|
tags: ["guide"],
|
||||||
map: "guides",
|
map: "guides",
|
||||||
root: "",
|
root: "",
|
||||||
show: true
|
show: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
Loading…
Add table
Reference in a new issue