estruyf / vscode-front-matter

Front Matter is a CMS running straight in Visual Studio Code. Can be used with static site generators like Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...
https://frontmatter.codes
MIT License
1.85k stars 69 forks source link

Enhancement: Create a new `{{locale}}` placeholder for i18n content #812

Closed estruyf closed 3 weeks ago

estruyf commented 1 month ago

Create a new {{locale}} placeholder for i18n content and their preview paths.

And it might serve as a good groundwork for i18n improvements. Something like this would be beneficial: "previewPath": "{{localePath}}/{{pathToken.relPath}}".

{{locale}} should become its own placeholder which can be used in the preview path as well. Good feedback. I'll create a new issue for it to track it.

Originally posted by @estruyf in https://github.com/estruyf/vscode-front-matter/issues/806#issuecomment-2127741147

estruyf commented 1 month ago

New {{locale}} placeholder can be used in the previewPath. For example: "previewPath": "{{locale}}/blog".

You can also ignore locales, for instance, if you do not want to include the en locale in the preview path, but all others are fine. Examples:

@theinfinit feel free to give it a try.

To document

theinfinit commented 1 month ago

Tested with beta v10.2.9236459.

For now, I can't get it to work 🫣

1. Simple case

// πŸ‘οΈ β€” pages visible in the dashboard

$ tree content
src/
└── content/
    └── astro-content-collection/
        └── reference/
            └── πŸ‘οΈ index.md
            └── πŸ‘οΈ example.md
        └── de/
            └── reference/
                └── index.md // http://localhost:4321/de/reference/ βœ…
                └── example.md // http://localhost:4321/de/example/ -> Expected http://localhost:4321/de/reference/example/
            πŸ‘οΈ index.mdx // http://localhost:4321/de/ βœ…
        πŸ‘οΈ index.mdx
"frontMatter.content.i18n": [
    { "title": "English", "locale": "en", "path": "." },
    { "title": "Deutsch", "locale": "de", "path": "de" }
  ],
"frontMatter.content.pageFolders": [
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/docs/",
    "excludeSubdir": true,
    "previewPath": "{{locale}}",
    "defaultLocale": "en"
  },
  {
    "title": "Guides",
    "path": "[[workspace]]/src/content/docs/guides",
    "previewPath": "{{locale}}/guides",
    "defaultLocale": "en"
  },
  {
    "title": "Reference",
    "path": "[[workspace]]/src/content/docs/reference",
    "previewPath": "{{locale}}/reference",
    "defaultLocale": "en"
  }
],

2. Partially modified, complex configuration:

Under Showing: Docs filter in the dashboard, only English pages are visible. Pages from other languages aren't included in the dashboard at all.

"frontMatter.content.i18n": [
  { "title": "English", "locale": "en", "path": "." },
  { "title": "Deutsch", "locale": "de", "path": "de" },
  { "title": "EspaΓ±ol", "locale": "es", "path": "es" }
],
"frontMatter.content.pageFolders": [
  {
    "title": "Root",
    "path": "[[workspace]]/src/content/astro-content-collection/",
    "previewPath": "{{pathToken.relPath}}/",
    "excludeSubdir": true,
    "defaultLocale": "en",
  },
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/",
    "previewPath": "{{locale}}/docs/{{pathToken.relPath}}/", // πŸ‘ˆ added `{{locale}}`
    "excludeSubdir": true,
    "defaultLocale": "en",
    // Removed "locales": [...]
  },
  {
    "title": "Docs / Guides",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/guides",
    "previewPath": "/docs/guides/",
    "defaultLocale": "en",
    "locales": [
      { "title": "English", "locale": "en" },
      { "title": "Deutsch", "locale": "de",    "path": "../../../de/docs/guides/" },
      { "title": "EspaΓ±ol", "locale": "es",    "path": "../../../es/docs/guides/" },
    ],
  },
]

Preview path for localized page de/docs/manual-setup.md:

<!-- Received -->
http://localhost:4321/docs/manual-setup/

<!-- Expected -->
http://localhost:4321/de/docs/manual-setup/

Previous, working configuration:

"frontMatter.content.pageFolders": [
  {
    "title": "Root",
    "path": "[[workspace]]/src/content/astro-content-collection/",
    "previewPath": "{{pathToken.relPath}}/",
    "excludeSubdir": true,
    "defaultLocale": "en",
  },
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/",
    "previewPath": "/docs/{{pathToken.relPath}}/",
    "excludeSubdir": true,
    "defaultLocale": "en",
    "locales": [
      { "title": "English",              "locale": "en" },
      { "title": "Deutsch",              "locale": "de",    "path": "../../de/docs/" },
      { "title": "EspaΓ±ol",              "locale": "es",    "path": "../../es/docs/" }
    ],
  },
  {
    "title": "Docs / Guides",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/guides",
    "previewPath": "/docs/guides/",
    "defaultLocale": "en",
    "locales": [
      { "title": "English",              "locale": "en" },
      { "title": "Deutsch",              "locale": "de",    "path": "../../../de/docs/guides/" },
      { "title": "EspaΓ±ol",              "locale": "es",    "path": "../../../es/docs/guides/" },
    ],
  },
]

3. {{locale}} added to every pageFolders entry

Localized pages are not visible in the dashboard too. The only visible, localized page was from "Root" pageFolder.

Because of that, I tested preview for that page (de/index.md), and got http://localhost:4321/316/de/ (notice strange 316 subpath, which is not present anywhere).

"frontMatter.content.i18n": [
  { "title": "English", "locale": "en", "path": "." },
  { "title": "Deutsch", "locale": "de", "path": "de" },
  { "title": "EspaΓ±ol", "locale": "es", "path": "es" }
],
"frontMatter.content.pageFolders": [
  {
    "title": "Root",
    "path": "[[workspace]]/src/content/astro-content-collection/",
    "previewPath": "{{locale}}/{{pathToken.relPath}}/",
    "excludeSubdir": true,
    "defaultLocale": "en",
  },
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/",
    "previewPath": "{{locale}}/docs/{{pathToken.relPath}}/", 
    /* Also tested with: 
     * "previewPath": "{{locale}}/docs", 
     * but got the same "316" preview path: `http://localhost:4321/316/de/`
     */
    "excludeSubdir": true,
    "defaultLocale": "en",
  },
  {
    "title": "Docs / Guides",
    "path": "[[workspace]]/src/content/astro-content-collection/docs/guides",
    "previewPath": "{{locale}}/docs/guides/",
    "defaultLocale": "en",
  },
]
estruyf commented 1 month ago

1. Simple case

There is a config issue with the folder paths. Your DE content should be located in src/content/astro-content-collection/reference/de/, not in src/content/astro-content-collection/reference/de/reference.

The results should all be as expected when configured like the first path.

2. Partially modified, complex configuration

Same issue as the first one. Your i18n content should be in src/content/astro-content-collection/docs/de/manual-setup.md, instead of src/content/astro-content-collection/docs/de/docs/manual-setup.md

3. {{locale}} added to every pageFolders entry

Fix coming up, this has to do with the date formatting on the pathname, but replaced the logic.

theinfinit commented 3 weeks ago

Hi Elio! I found some time to test beta v10.3.9501641.

This is the folder structure I worked with:

astro-content-collection: docs/ # root
β”œβ”€β”€ pl/ # locale
β”‚   β”œβ”€β”€ reference/
β”‚   β”‚   β”œβ”€β”€ example.md # Expected: http://localhost:4321/pl/reference/example/
β”‚   β”‚   └── index.md   # Expected: http://localhost:4321/pl/reference/
β”‚   └── index.mdx      # Expected: http://localhost:4321/pl/
β”œβ”€β”€ guides/
β”‚   └── example.md # Expected: http://localhost:4321/guides/example
β”œβ”€β”€ reference/
β”‚   β”œβ”€β”€ example.md # Expected: http://localhost:4321/reference/example
β”‚   └── index.md   # Expected: http://localhost:4321/reference/
└── index.mdx      # Expected: http://localhost:4321/

Case 1: One pageFolders entry and global i18n configuration with default content in the root

Configuration:

"frontMatter.preview.trailingSlash": true,
"frontMatter.content.i18n": [
  { "title": "English", "locale": "en", "path": "." },
  { "title": "Polish", "locale": "pl", "path": "pl" }
],
"frontMatter.content.pageFolders": [
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/docs/",
    "defaultLocale": "en",
    "previewPath": "/{{locale}}/{{pathToken.relPath}}/"
  }
],

Dashboard

With this setup, all seven pages are visible in the dashboard, but only index.mdx and pl/index.mdx have properly assigned locale. Other pages are listed without detected locale.

Preview paths

.
β”œβ”€β”€ pl/ # locale
β”‚   β”œβ”€β”€ reference/
β”‚   β”‚   β”œβ”€β”€ example.md # Received: βœ… http://localhost:4321/pl/reference/example/
β”‚   β”‚   └── index.md   # Received: βœ… http://localhost:4321/pl/reference/
β”‚   └── index.mdx      # Received: βœ… http://localhost:4321/pl/
β”œβ”€β”€ guides/
β”‚   └── example.md # Received: ❌ http://localhost:4321/en/guides/example/
β”œβ”€β”€ reference/
β”‚   β”œβ”€β”€ example.md # Received: ❌ http://localhost:4321/en/reference/example/
β”‚   └── index.md   # Received: ❌ http://localhost:4321/en/reference/
└── index.mdx      # Received: ❌ http://localhost:4321/en/docs/   πŸ’¬ Here, the root folder name leaked into the preview path

Here, I think, users might expect to have one source of truth. The global i18n configuration. If path is set to "path": ".", it should be enough to generate correct preview path for setups with default content in the root.

Unless, there are some use cases for such granularity?


Case 2: Tweaked previewPath to include |ignore:en as described in the docs

Configuration:

"frontMatter.preview.trailingSlash": true,
"frontMatter.content.i18n": [
  { "title": "English", "locale": "en", "path": "." },
  { "title": "Polish", "locale": "pl", "path": "pl" }
],
"frontMatter.content.pageFolders": [
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/docs/",
    "defaultLocale": "en",
    "previewPath": "/{{locale|ignore:en}}/{{pathToken.relPath}}/"
  }
],

Dashboard

Pages in the dashboard are displayed in the same way as in Case 1.

Preview paths

.
β”œβ”€β”€ pl/ # locale
β”‚   β”œβ”€β”€ reference/
β”‚   β”‚   β”œβ”€β”€ example.md # Received: βœ… http://localhost:4321/pl/reference/example/
β”‚   β”‚   └── index.md   # Received: βœ… http://localhost:4321/pl/reference/
β”‚   └── index.mdx      # Received: βœ… http://localhost:4321/pl/
β”œβ”€β”€ guides/
β”‚   └── example.md # Received: ❌ http://localhost:4321//guides/example/   πŸ’¬ double slashes
β”œβ”€β”€ reference/
β”‚   β”œβ”€β”€ example.md # Received: ❌ http://localhost:4321//reference/example/   πŸ’¬ double slashes
β”‚   └── index.md   # Received: βœ… http://localhost:4321/reference/
└── index.mdx      # Received: ❌ http://localhost:4321/docs/   πŸ’¬ the root folder name leaked into the preview path

Locale is not parsed when "defaultLocale" config is missing.

https://beta.frontmatter.codes/docs/content-creation/placeholders#example-5-using-the-locale-placeholder

I would suggest to add the "defaultLocale": "en", to the examples in the documentation, because without it, {{locale}} doesn't seem to be parsed at all.

Received preview path for index.mdx: http://localhost:4321/{{locale|ignore:en}}/docs/.

Used configuration (I removed the "defaultLocale": "en",):

"frontMatter.preview.trailingSlash": true,
"frontMatter.content.i18n": [
  { "title": "English", "locale": "en", "path": "." },
  { "title": "Polish", "locale": "pl", "path": "pl" }
],
"frontMatter.content.pageFolders": [
  {
    "title": "Docs",
    "path": "[[workspace]]/src/content/docs/",
    "previewPath": "/{{locale|ignore:en}}/{{pathToken.relPath}}/"
  }
],

Hope it helps! Cheers πŸ‘‹

estruyf commented 3 weeks ago

Docs have been updated! Thanks for the suggestion.

I will have to verify both of your cases how we can support these.

estruyf commented 3 weeks ago

@theinfinit implemented a change to fix the double slash issue and the root folder reference, which is mentioned in case 2. It will be released in the beta version.

About case 1, it is expected when you use {{locale}} always to include a locale in the URL, that is why I've added the ignore property.