pruvious / pruvious

A reliable CMS for your Nuxt app.
https://pruvious.com
MIT License
442 stars 13 forks source link

Merge translatable strings from Nuxt Layers #49

Open BlitzBanana opened 4 weeks ago

BlitzBanana commented 4 weeks ago

Hey, firstly, thank you for your amazing work on this project.

I'm encountering a use case that I think was not planned. I have a base nuxt app used as a layer defining basic components, blocks and most importantly translations for the Pruvious dashboard.

When I set up a new Nuxt application using this layer, Pruvious does not let me enrich the dashboard translation (e.g. for new custom collections), as it consider the new content as duplicated.

Here is the setup :

/// layer/translatable-strings/dashboard.fr.ts

import { defineTranslatableStrings } from '#pruvious'

export default defineTranslatableStrings({
  domain: 'pruvious-dashboard',
  language: 'fr',
  strings: {
    '(current)': '(actuel)',
    /// [...]
    // Standard collection labels
    'ID': 'Identifiant',
    'Page title': 'Titre de la page',
    'URL path': 'Adresse',
    'Translations': 'Traductions',
    /// [...]
  },
})
/// new-app/translatable-strings/dashboard.fr.ts

import { defineTranslatableStrings } from '#pruvious'

export default defineTranslatableStrings({
  domain: 'pruvious-dashboard',
  language: 'fr',
  strings: {
    // Standard collection labels overriding layer translation
    'Page title': 'Titre',
    // Custom collection labels
    'Content': 'Contenu',
    'Approved': 'Approuvé',
    /// [...]
  },
})

Current behavior :

[pruvious 3:18:24 PM]  ERROR  Cannot register duplicate translatable strings pruvious-dashboard (fr) in /home/blitz/dev/new-app/node_modules/.c12/github_org_FIJfowifjFOWJ/translatable-strings/dashboard.fr.ts

Proposed behavior :

/// Merge Layer(s) + New app
/// It would be interpreted as :

import { defineTranslatableStrings } from '#pruvious'

export default defineTranslatableStrings({
  domain: 'pruvious-dashboard',
  language: 'fr',
  strings: {
    '(current)': '(actuel)',
    /// [...]
    // Standard collection labels
    'ID': 'Identifiant',
    'Page title': 'Titre',
    'URL path': 'Adresse',
    'Translations': 'Traductions',
    /// [...]
    // Custom collection labels
    'Content': 'Contenu',
    'Approved': 'Approuvé',
    /// [...]
  },
})

I don't know if it's technically doable, applying the layers in the correct order. Before digging into it, would you be open to a pull request on the matter ?

murisceman commented 4 weeks ago

Hey, thank you for your kind word! Here's an example of how to extend prebuilt translatable strings:

import { defineTranslatableStrings } from '#previous'
import { standardTranslatableStringsDefinition } from '#previous/standard'

export default defineTranslatableStrings({
  ...standardTranslatableStringsDefinition.dashboard.en,
  strings: {
    ...standardTranslatableStringsDefinition.dashboard.en.strings,
    // Add or override translatable strings here
  },
})

The DX here is not the best, but I'll try to improve this in v4 🙈

murisceman commented 4 weeks ago

Actually, I think I got your question wrong. Let me try this quickly with a layers setup.

murisceman commented 4 weeks ago

So, there were actually two problematic issues:

  1. I forgot to use ignoreDuplicate in the translatable strings resolver when resolving duplicate files from layers (intended behavior). This is now fixed with https://github.com/pruvious/pruvious/commit/be9a9d4202c373f46084a40cf66829a49902ceb4.

  2. By defining the same translatable strings in an upper layer, it will override all the definitions from the extended layers, except for the module itself where an error will be thrown if you're trying to override it. In your case, the error will no longer be shown (from v3.12.6), but you also won't get the intended behavior. Here's what you could do:

// new-app/translatable-strings/dashboard.fr.ts

import { defineTranslatableStrings } from '#pruvious'
import baseDefinition from '../../layer/translatable-strings/dashboard.fr' // or just 'layer' if possible in monorepo

export default defineTranslatableStrings({
  ...baseDefinition,
  strings: {
    ...baseDefinition.strings,
    // Add or override translatable strings here
  },
})
BlitzBanana commented 4 weeks ago

Wow, you're fast. Your solution (2) works perfectly as intended, thank you very much.