diff --git a/eleventy.config.js b/eleventy.config.js index 0ed2bf1..2ff1236 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,5 +1,6 @@ import pluginWebc from '@11ty/eleventy-plugin-webc' import mdit from 'markdown-it' +import i18n from 'eleventy-plugin-i18n' import fs from 'fs/promises' const MD_REGEX = /\.[^/.]{1,4}$/i @@ -14,6 +15,13 @@ export default function (config) { config.setLibrary('md', markdownLib) + // i18n + config.addPlugin(i18n, { + fallbackLocales: { + '*': 'en' + } + }) + // webc templates config.addPlugin(pluginWebc, { components: 'src/layouts/components/*.webc', @@ -22,34 +30,39 @@ export default function (config) { config.addPassthroughCopy({ 'src/assets': '/', './node_modules/view-transitions-polyfill/dist/view-transitions-polyfill.js': '/scripts/vtpolyfill.js', - // 'src/admin': 'admin', + 'src/admin': '/admin', }) // add collection for pages config.addCollection('categories', async (collection) => { - const categoryNames = (await fs.readdir('src/content/')).filter((c) => !c.match(MD_REGEX)) + const locales = (await fs.readdir('src/content/')).filter((c) => !c.match(MD_REGEX)) + const categories = new Map() - let categories = new Map() + for (const locale of locales) { + const categoryNames = (await fs.readdir(`src/content/${locale}`)).filter((c) => !c.match(MD_REGEX)) - for (const catName of categoryNames) { - categories = collection.getFilteredByGlob(`src/content/${catName}/index.md`).reduce((accumulator, category) => { - accumulator.set(category, []) - return accumulator - }, categories) + categories.set(locale, new Map()) - categories = collection.getFilteredByGlob(`src/content/${catName}/*.md`).reduce((accumulator, category) => { - const categoryIsKey = accumulator.keys().find(key => category === key) - if (!categoryIsKey) { - const categoryKey = accumulator.keys().find(key => category.data.tags.includes(key.data.tags[0])) - const catAccum = accumulator.get(categoryKey) - catAccum.push(category) - } + for (const catName of categoryNames) { + categories.set(locale, collection.getFilteredByGlob(`src/content/${locale}/${catName}/index.md`).reduce((accumulator, category) => { + accumulator.set(category, []) + return accumulator + }, categories.get(locale))) - return accumulator - }, categories) + categories.set(locale, collection.getFilteredByGlob(`src/content/${locale}/${catName}/*.md`).reduce((accumulator, category) => { + const categoryIsKey = accumulator.keys().find(key => category === key) + if (!categoryIsKey) { + const categoryKey = accumulator.keys().find(key => category.data.tags.includes(key.data.tags[0])) + const catAccum = accumulator.get(categoryKey) + catAccum.push(category) + } + + return accumulator + }, categories.get(locale))) + } } - return map2arr(categories) + return { en: map2arr(categories.get('en')), fr: map2arr(categories.get('fr')) } }) config.addCollection('pages', (collection) => { diff --git a/package-lock.json b/package-lock.json index 4a6f632..c71d77f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@11ty/eleventy": "^3.0.0", "@11ty/eleventy-plugin-webc": "^0.11.2", - "markdown-it": "^14.1.0", - "view-transitions-polyfill": "^1.0.3" + "eleventy-plugin-i18n": "^0.1.3", + "markdown-it": "^14.1.0" } }, "node_modules/@11ty/dependency-tree": { @@ -611,6 +611,37 @@ "node": ">= 0.4" } }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/chardet": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.0.0.tgz", @@ -881,6 +912,17 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, + "node_modules/eleventy-plugin-i18n": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/eleventy-plugin-i18n/-/eleventy-plugin-i18n-0.1.3.tgz", + "integrity": "sha512-O4FtB4t7g0T3ujH3ciFGCyJ/r1CHzp33WYrDqgnX6s6KZ4R63CkN/RndRKU36ahWWUmF0BrLjQ+IDwj2ntsicw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.1", + "lodash.get": "^4.4.2", + "templite": "^1.1.0" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1295,6 +1337,15 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -1597,6 +1648,13 @@ "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==", "license": "MIT" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -2440,6 +2498,24 @@ "node": ">=0.10.0" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/templite": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/templite/-/templite-1.2.0.tgz", + "integrity": "sha512-O9BpPXF44a9Pg84Be6mjzlrqOtbP2I/B5PNLWu5hb1n9UQ1GTLsjdMg1z5ROCkF6NFXsO5LQfRXEpgTGrZ7Q0Q==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2482,12 +2558,6 @@ "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "license": "MIT" }, - "node_modules/view-transitions-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/view-transitions-polyfill/-/view-transitions-polyfill-1.0.3.tgz", - "integrity": "sha512-o7tiNKAsuqvL0u4Epo/jrSOx7qy1/KH3ajzHsY0GU4zWIOiiC6Pyczyf6QgJneyFKlu8QdcMeCQocUl94R+fvA==", - "license": "ISC" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index d5620fb..adb9b31 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@11ty/eleventy": "^3.0.0", "@11ty/eleventy-plugin-webc": "^0.11.2", + "eleventy-plugin-i18n": "^0.1.3", "markdown-it": "^14.1.0" } } diff --git a/src/admin/config.yml b/src/admin/config.yml new file mode 100644 index 0000000..6ae5bad --- /dev/null +++ b/src/admin/config.yml @@ -0,0 +1,51 @@ +backend: + name: gitea + repo: suroh/alex.portfolio # Path to your Gitea repository + app_id: 195e3617-71d0-4469-b936-b26c08528359 # The Client ID provided by Gitea + api_root: https://git.suroh.tk/api/v1 # API URL of your Gitea instance + base_url: https://git.suroh.tk # Root URL of your Gitea instance + # auth_endpoint: https://git.suroh.tk/login/oauth/authorize + # optional, defaults to master + branch: main + +media_folder: 'uploads' + +collections: + - name: "pages" + label: "Pages" + files: + - label: "Homepage" + name: "index" + file: "src/content/index.md" + fields: + - { label: "Title", name: "title", widget: "string" } + - { label: "Body", name: "body", widget: "markdown", required: false } + - label: "About" + name: "about" + file: "src/content/about.md" + fields: + - { label: "Title", name: "title", widget: "string" } + - { label: "Body", name: "body", widget: "markdown", required: false } + - name: 'art' + label: 'Art' + label_singluar: 'Art' + folder: 'art' + create: true + slug: "{{slug}}" + fields: + - { label: 'Title', name: 'title', widget: 'string' } + - { label: 'Location', name: 'location', widget: 'string' } + - { label: 'Year', name: 'year', widget: 'string' } + - { label: "Body", name: "body", widget: "markdown" } + - name: 'pedagogy' + label: 'Pedagogy' + label_singluar: 'Pedagogy' + folder: 'pedagogy' + create: true + slug: "{{slug}}" + fields: + - { label: 'Title', name: 'title', widget: 'string' } + - { label: 'Location', name: 'location', widget: 'string' } + - { label: 'Year', name: 'year', widget: 'string' } + - { label: "Body", name: "body", widget: "markdown" } + diff --git a/src/admin/index.html b/src/admin/index.html new file mode 100644 index 0000000..790f7a8 --- /dev/null +++ b/src/admin/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta name="robots" content="noindex" /> + <title>Content Manager</title> + </head> + <body> + <!-- Include the script that builds the page and powers Decap CMS --> + <script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script> + </body> +</html> diff --git a/src/assets/images/perception.1.webp b/src/assets/uploads/perception.1.webp similarity index 100% rename from src/assets/images/perception.1.webp rename to src/assets/uploads/perception.1.webp diff --git a/src/assets/images/perception.2.webp b/src/assets/uploads/perception.2.webp similarity index 100% rename from src/assets/images/perception.2.webp rename to src/assets/uploads/perception.2.webp diff --git a/src/content/about.md b/src/content/en/about.md similarity index 100% rename from src/content/about.md rename to src/content/en/about.md diff --git a/src/content/art/2-and-2-aint-22.md b/src/content/en/art/2-and-2-aint-22.md similarity index 100% rename from src/content/art/2-and-2-aint-22.md rename to src/content/en/art/2-and-2-aint-22.md diff --git a/src/content/art/art.json b/src/content/en/art/art.json similarity index 100% rename from src/content/art/art.json rename to src/content/en/art/art.json diff --git a/src/content/art/index.md b/src/content/en/art/index.md similarity index 100% rename from src/content/art/index.md rename to src/content/en/art/index.md diff --git a/src/content/art/let-my-baby-stay.md b/src/content/en/art/let-my-baby-stay.md similarity index 100% rename from src/content/art/let-my-baby-stay.md rename to src/content/en/art/let-my-baby-stay.md diff --git a/src/content/art/perception.md b/src/content/en/art/perception.md similarity index 92% rename from src/content/art/perception.md rename to src/content/en/art/perception.md index 59b27b0..9a0000b 100644 --- a/src/content/art/perception.md +++ b/src/content/en/art/perception.md @@ -3,9 +3,9 @@ title: percepción location: Paris year: 2016 imageGallery: - - src: /images/perception.1.webp + - src: /uploads/perception.1.webp alt: Girl wearing headphones next to a painted white wall and painted window listening to the audio work - - src: /images/perception.2.webp + - src: /uploads/perception.2.webp alt: Photo of the art gallery space with people, including Ricardo are walking aroud various installations --- diff --git a/src/content/en/en.json b/src/content/en/en.json new file mode 100644 index 0000000..7c5d03c --- /dev/null +++ b/src/content/en/en.json @@ -0,0 +1,5 @@ +{ + "dir": "ltr", + "locale": "en-GB", + "lang": "en" +} diff --git a/src/content/index.md b/src/content/en/index.md similarity index 100% rename from src/content/index.md rename to src/content/en/index.md diff --git a/src/content/pedagogy/cheesecake.md b/src/content/en/pedagogy/cheesecake.md similarity index 100% rename from src/content/pedagogy/cheesecake.md rename to src/content/en/pedagogy/cheesecake.md diff --git a/src/content/pedagogy/index.md b/src/content/en/pedagogy/index.md similarity index 100% rename from src/content/pedagogy/index.md rename to src/content/en/pedagogy/index.md diff --git a/src/content/pedagogy/pedagogy.json b/src/content/en/pedagogy/pedagogy.json similarity index 100% rename from src/content/pedagogy/pedagogy.json rename to src/content/en/pedagogy/pedagogy.json diff --git a/src/content/fr/fr.json b/src/content/fr/fr.json new file mode 100644 index 0000000..9623ce5 --- /dev/null +++ b/src/content/fr/fr.json @@ -0,0 +1,5 @@ +{ + "dir": "ltr", + "locale": "fr-FR", + "lang": "fr" +} diff --git a/src/data/eleventyComputed.js b/src/data/eleventyComputed.js deleted file mode 100644 index b1c6ea4..0000000 --- a/src/data/eleventyComputed.js +++ /dev/null @@ -1 +0,0 @@ -export default {} diff --git a/src/data/locales.js b/src/data/locales.js new file mode 100644 index 0000000..ae9acc1 --- /dev/null +++ b/src/data/locales.js @@ -0,0 +1,10 @@ +export default [ + { + "label": "English", + "code": "en" + }, + { + "label": "French", + "code": "fr" + }, +] diff --git a/src/layouts/base.webc b/src/layouts/base.webc index f9e55ab..acc5442 100644 --- a/src/layouts/base.webc +++ b/src/layouts/base.webc @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html lang="en"> +<html :lang="locale" :dir="dir"> <head> <meta charset="utf-8" /> <title>WebC Example</title> @@ -25,9 +25,9 @@ @nav-path=""> <ul> <li> - <a href="/">Home</a> + <a :href="'/' + lang + '/'">Home</a> </li> - <li webc:for="category of collections.categories" > + <li webc:for="category of collections.categories[lang]" > <a :href="category[0].url" @text="category[0].data.title"></a> </li> <li webc:for="page of collections.pages" > @@ -36,11 +36,11 @@ </ul> </alx-nav> <alx-nav - webc:for="category of collections.categories" + webc:for="category of collections.categories[lang]" webc:if="category[1].length" class="subNav" :data-test="" - :@active-nav="page.url.split('/')[1] === category[0].data.category" + :@active-nav="page.url.split('/')[2] === category[0].data.category" :class="page.url.split('/')[1] === category[0].data.category ? '' : 'hidden'" :style="(page.url.split('/').filter(n => n)[page.url.split('/').filter(n => n).length - 1] === category[0].data.category) ? `view-transition-name: --${category[0].data.category}-nav` : '' @@ -56,6 +56,5 @@ </nav> <template webc:nokeep @raw="content"></template> - </body> </html>