运行时如何在Form-generator中结合I18n与JSON Schema实现表单国际化?
Hey there! Let's work through this dynamic JSON Schema internationalization issue you're hitting with Form-generator. I’ve dealt with similar dynamic form i18n challenges before, so here’s a practical, step-by-step approach to solve it:
Core Idea
Instead of relying on template-based $t() calls (which don’t work for dynamic schema), we’ll recursively traverse the raw JSON Schema from your server, map each field’s path to a corresponding key in your translation files, and inject the translated values directly into the schema before passing it to Form-generator.
Step 1: Align Your Translation File Structure
First, make sure your translation files (like en.json) mirror the path structure of your JSON Schema. For your example, your en.json should look like either of these (I18n libraries like Vue I18n support both nested and flattened keys):
Nested structure (cleaner for complex schemas):
{ "instance": { "specification": { "label": "this is label", "title": "this is title" } } }
Flattened structure (good for simple schemas):
{ "instance.specification.label": "this is label", "instance.specification.title": "this is title" }
Step 2: Write a Recursive Schema Translation Function
We’ll create a function that walks through every node in your schema, tracks the full path of each field, and uses that path to fetch the correct translation. Here’s a JavaScript example (works with Vue I18n, React i18next, or any I18n library with a translation function like $t()):
// Adjust the translator function to match your I18n setup (e.g., i18next.t() for React) function translateDynamicSchema(schema, translator, currentPath = '') { // Handle array elements (common in schemas with repeated fields) if (Array.isArray(schema)) { schema.forEach((item, index) => { const newPath = currentPath ? `${currentPath}[${index}]` : `[${index}]`; translateDynamicSchema(item, translator, newPath); }); return schema; } // Handle nested objects if (typeof schema === 'object' && schema !== null) { for (const key in schema) { const newPath = currentPath ? `${currentPath}.${key}` : key; translateDynamicSchema(schema[key], translator, newPath); } // Inject translations for label/title fields if (schema.label !== undefined) { const translationKey = currentPath ? `${currentPath}.label` : 'label'; schema.label = translator(translationKey); } if (schema.title !== undefined) { const translationKey = currentPath ? `${currentPath}.title` : 'title'; schema.title = translator(translationKey); } return schema; } return schema; }
Step 3: Use the Function to Prepare Your Schema
Once you’ve fetched the raw schema from your server and loaded your translation file, process the schema before passing it to Form-generator:
// Example with Vue I18n (adjust for your framework/library) import { useI18n } from 'vue-i18n'; const { t: translator } = useI18n(); // Raw schema from your server const rawServerSchema = { "instance": { "specification": { "label": "", "title": "" } } }; // Translate the schema const translatedSchema = translateDynamicSchema(rawServerSchema, translator); // Pass the translated schema to Form-generator formGeneratorInstance.setSchema(translatedSchema);
Key Notes to Avoid Issues
- Wait for translations to load: If your translation files are loaded asynchronously (e.g., fetched from a CDN), make sure you run the translation function only after the translations are fully loaded.
- Customize translatable fields: If your schema uses other fields that need translation (like
description), add them to the checks forschema.label/schema.title. - Handle edge cases: If some fields shouldn’t be translated, add a condition (e.g., skip fields with a
noI18n: trueflag in the schema).
This approach ensures every dynamic field in your schema gets the correct translation before the form is generated, just like you would with template-based $t() calls!
内容的提问来源于stack exchange,提问作者SeyyedKhandon

