Feature/post media translations (#42)
* chore: updated todo with translation ideas * feat: first take at the implementation of translations * fix: small addition for the translation feature * feat: support language switching in the editor and preview * feat: better handling of long bodies by not running them through a json envelope * fix: unknown macros have better fallback * feat: api for python to get translations * fix: strip dumb prefix of content in translation * feat: extend meta diff for translations * feat: hook up translations to rebuild-from-disk * feat: generation of the website prefers project language, falling back to canonical language * fix: crashes during rendering * feat: translation validation report * fix: made the translation validation actually work * chore: reorganization of menu * fix: some topics cleanup * chore: updated doc * feat: translations for media * feat: more aligned in UI/UX * feat: edit translations possible * chore: added full multi-language todo * chore: updated todo for clarity * feat: implementation of full multi-linguality * fix: page creation creates pages * fix: flags on every page * fix: better prompt * feat: made MCP server aware of language content * feat: python tools for translations * fix: better fill-in-translations * fix: better prompt for translation. maybe. * fix: losing posts from search due to translation process * fix: translation validation handles in-db content and fill-in of missing translations fixed to flush * fix: faster scanning for infilling of missing translations * chore: updated agent instructions * feat: calendar and tag cloud respect current language now * fix: retries going up * fix: got metadata-diff and rebuild into sync * fix: extended meta-diff for timestamps * fix: made website validation look at translated content, too * fix: multi-lingual search * chore: refactor Editor.tsx into two separate editors * feat: do language detection when no explicit language given --------- Co-authored-by: hugo <hugoms@me.com>
This commit is contained in:
@@ -54,6 +54,33 @@
|
||||
"siteValidation.error.validate": "La validación del sitio falló",
|
||||
"siteValidation.error.apply": "La aplicación de la validación falló",
|
||||
"siteValidation.toast.applySuccess": "Validación aplicada: {rendered} renderizadas, {deleted} eliminadas",
|
||||
"menu.item.validateTranslations": "Validar traducciones",
|
||||
"translationValidation.tabTitle": "Validación de traducciones",
|
||||
"translationValidation.title": "Validar traducciones",
|
||||
"translationValidation.summary": "Filas de BD revisadas: {dbRows} · Archivos revisados: {files} · Filas de BD inválidas: {invalidDb} · Archivos inválidos: {invalidFiles}",
|
||||
"translationValidation.loading": "Validando traducciones...",
|
||||
"translationValidation.empty": "Ejecuta Blog -> Validar traducciones para inspeccionar la integridad de las traducciones.",
|
||||
"translationValidation.databaseTitle": "Filas de traducción inválidas en la base de datos",
|
||||
"translationValidation.filesystemTitle": "Archivos de traducción inválidos en disco",
|
||||
"translationValidation.noneDatabase": "No se encontraron filas de traducción inválidas.",
|
||||
"translationValidation.noneFilesystem": "No se encontraron archivos de traducción inválidos.",
|
||||
"translationValidation.error.validate": "La validación de traducciones falló",
|
||||
"translationValidation.issue.sameLanguage": "El idioma de la traducción coincide con el idioma canónico de la entrada",
|
||||
"translationValidation.issue.missingSource": "La traducción apunta a una entrada de origen inexistente",
|
||||
"translationValidation.issue.doNotTranslate": "La entrada está marcada como no-traducir pero tiene traducciones",
|
||||
"translationValidation.issue.contentInDatabase": "Traducción publicada con contenido en la BD en lugar del sistema de archivos",
|
||||
"translationValidation.field.translationFor": "Entrada de origen",
|
||||
"translationValidation.field.translationId": "Fila de traducción",
|
||||
"translationValidation.field.title": "Título",
|
||||
"translationValidation.field.languages": "Idiomas",
|
||||
"translationValidation.field.filePath": "Archivo",
|
||||
"translationValidation.languagesWithCanonical": "{canonical} = {translation}",
|
||||
"translationValidation.revalidate": "Revalidar",
|
||||
"translationValidation.revalidating": "Revalidando…",
|
||||
"translationValidation.fix": "Corregir problemas",
|
||||
"translationValidation.fixing": "Corrigiendo…",
|
||||
"translationValidation.toast.fixSuccess": "{dbRows} filas de BD y {files} archivos eliminados, {flushed} traducciones escritas a disco",
|
||||
"translationValidation.error.fix": "Error al corregir traducciones inválidas",
|
||||
"menuEditor.tabTitle": "Menú del blog",
|
||||
"menuEditor.title": "Editor del menú del blog",
|
||||
"menuEditor.description": "Gestiona la estructura central de navegación del blog y guárdala en meta/menu.opml.",
|
||||
@@ -412,7 +439,7 @@
|
||||
"metadataDiff.fieldFilter.toggle": "Filtrar por {field}",
|
||||
"metadataDiff.sync.failed": "falló",
|
||||
"metadataDiff.sync.dbToFile.title": "Actualizar archivos con valores de la base de datos",
|
||||
"metadataDiff.sync.dbToFile.short": "BD\u2192A",
|
||||
"metadataDiff.sync.dbToFile.short": "BD→A",
|
||||
"metadataDiff.sync.dbToFile.success": "Se sincronizaron {success} entradas a archivos{falló}",
|
||||
"metadataDiff.sync.dbToFile.error": "No se pudo sincronizar a archivos",
|
||||
"metadataDiff.sync.fileToDb.title": "Actualizar base de datos con valores de archivos",
|
||||
@@ -433,7 +460,7 @@
|
||||
"metadataDiff.orphanFiles.badge": "Archivo huérfano",
|
||||
"metadataDiff.orphanFiles.slug": "Slug",
|
||||
"metadataDiff.orphanFiles.path": "Ruta",
|
||||
"metadataDiff.orphanFiles.importButton": "D \u2192 BD",
|
||||
"metadataDiff.orphanFiles.importButton": "D → BD",
|
||||
"metadataDiff.orphanFiles.importTitle": "Importar todos los archivos huérfanos a la base de datos",
|
||||
"metadataDiff.orphanFiles.importing": "Importando…",
|
||||
"metadataDiff.orphanFiles.importSuccess": "{success} archivos huérfanos importados{failed}",
|
||||
@@ -461,6 +488,7 @@
|
||||
"sidebar.published": "Publicadas",
|
||||
"sidebar.archived": "Archivadas",
|
||||
"sidebar.untitled": "Sin título",
|
||||
"sidebar.languagesAvailable": "{count} idiomas disponibles",
|
||||
"sidebar.noMatchingPosts": "No hay entradas coincidentes",
|
||||
"sidebar.createFirstPost": "Crea tu primera entrada",
|
||||
"sidebar.loadMore": "Cargar más ({loaded} de {total})",
|
||||
@@ -525,6 +553,8 @@
|
||||
"settings.project.publicUrlPlaceholder": "https://example.com",
|
||||
"settings.project.mainLanguageLabel": "Idioma principal",
|
||||
"settings.project.mainLanguageDescription": "Idioma principal del contenido del blog. Los títulos, textos alternativos y pies generados por IA usarán este idioma.",
|
||||
"settings.project.blogLanguagesLabel": "Idiomas del blog",
|
||||
"settings.project.blogLanguagesDescription": "Idiomas en los que se genera el blog. El idioma principal siempre está incluido. Los idiomas adicionales generan subárboles traducidos.",
|
||||
"settings.project.defaultAuthorLabel": "Autor predeterminado",
|
||||
"settings.project.defaultAuthorDescription": "Nombre de autor predeterminado para nuevas entradas y medios. Se puede reemplazar por elemento.",
|
||||
"settings.project.defaultAuthorPlaceholder": "Nombre del autor",
|
||||
@@ -578,6 +608,27 @@
|
||||
"editor.previewFrameTitle": "Vista previa de la entrada",
|
||||
"editor.previewLoading": "Cargando vista previa...",
|
||||
"editor.metadata.toggle": "Metadatos",
|
||||
"editor.translations.title": "Traducciones",
|
||||
"editor.translations.currentLanguage": "Idioma actual: {language}",
|
||||
"editor.translations.none": "Todavía no hay traducciones.",
|
||||
"editor.translations.selectTarget": "Selecciona el idioma de destino",
|
||||
"editor.translations.translateButton": "Traducir a...",
|
||||
"editor.translations.translateTitle": "Crear o actualizar una traducción con IA",
|
||||
"editor.translations.translating": "Traduciendo...",
|
||||
"editor.translations.refresh": "Actualizar",
|
||||
"editor.translations.refreshTitle": "Regenerar esta traducción con IA",
|
||||
"editor.translations.publish": "Publicar",
|
||||
"editor.translations.publishTitle": "Publicar esta traducción en su archivo Markdown",
|
||||
"editor.translations.publishing": "Publicando...",
|
||||
"editor.translations.missing": "Faltan: {languages}",
|
||||
"editor.translations.complete": "Todos los idiomas de traducción compatibles están disponibles.",
|
||||
"editor.translations.translateSuccess": "Traducción actualizada para {language}",
|
||||
"editor.translations.translateFailed": "La traducción falló",
|
||||
"editor.translations.publishSuccess": "Traducción publicada para {language}",
|
||||
"editor.translations.publishFailed": "No se pudo publicar la traducción",
|
||||
"editor.translations.status.draft": "Borrador",
|
||||
"editor.translations.status.published": "Publicada",
|
||||
"editor.translations.status.archived": "Archivada",
|
||||
"editor.excerpt.toggle": "Extracto",
|
||||
"editor.footer.created": "Creado",
|
||||
"editor.footer.updated": "Actualizado",
|
||||
@@ -927,6 +978,12 @@
|
||||
"editor.media.quickActions.button": "✨ Analizar con IA",
|
||||
"editor.media.quickActions.aiTitle": "Título sugerido por IA",
|
||||
"editor.media.quickActions.aiDescription": "Genera automáticamente título, texto alternativo y pie de foto.",
|
||||
"editor.media.quickActions.detectLanguageTitle": "Detectar idioma",
|
||||
"editor.media.quickActions.detectLanguageDescription": "Detectar el idioma de los metadatos con IA",
|
||||
"editor.media.quickActions.translateTitle": "Traducir a…",
|
||||
"editor.media.quickActions.translateDescription": "Crear o actualizar una traducción con IA",
|
||||
"editor.media.translations.currentLanguage": "Idioma actual: {language}",
|
||||
"editor.media.translations.selectTarget": "Seleccionar idioma de destino",
|
||||
"editor.post.quickActions.title": "Acciones rápidas",
|
||||
"editor.post.quickActions.analyzing": "⏳ Analizando…",
|
||||
"editor.post.quickActions.button": "⚡ Acciones rápidas",
|
||||
@@ -949,6 +1006,24 @@
|
||||
"editor.media.field.caption": "Pie de foto",
|
||||
"editor.media.field.tags": "Etiquetas",
|
||||
"editor.media.field.author": "Autor",
|
||||
"editor.media.field.language": "Idioma",
|
||||
"editor.media.field.languageNone": "No definido",
|
||||
"editor.media.translations.title": "Traducciones",
|
||||
"editor.media.translations.none": "Aún no hay traducciones.",
|
||||
"editor.media.translations.translateButton": "Traducir a…",
|
||||
"editor.media.translations.translating": "Traduciendo…",
|
||||
"editor.media.translations.translateSuccess": "Traducción actualizada para {language}",
|
||||
"editor.media.translations.translateFailed": "Error en la traducción",
|
||||
"editor.media.translations.refresh": "Actualizar",
|
||||
"editor.media.translations.refreshTitle": "Regenerar esta traducción con IA",
|
||||
"editor.media.translations.deleteTitle": "Eliminar esta traducción",
|
||||
"editor.media.translations.deleted": "Traducción eliminada para {language}",
|
||||
"editor.media.translations.deleteFailed": "Error al eliminar la traducción",
|
||||
"editor.media.translations.editTitle": "Editar traducción — {language}",
|
||||
"editor.media.translations.saved": "Traducción guardada para {language}",
|
||||
"editor.media.translations.saveFailed": "Error al guardar la traducción",
|
||||
"editor.media.toast.languageDetected": "Idioma detectado: {language}",
|
||||
"editor.media.error.detectLanguage": "Error al detectar el idioma",
|
||||
"editor.media.placeholder.title": "Introduce un título",
|
||||
"editor.media.placeholder.altText": "Describe la imagen para accesibilidad",
|
||||
"editor.media.placeholder.caption": "Añadir pie de foto",
|
||||
@@ -1097,9 +1172,7 @@
|
||||
"importAnalysis.usedIn": "Usado en: {items}{more}",
|
||||
"importAnalysis.moreSuffix": ", +{count} más",
|
||||
"importAnalysis.noParameters": "(sin parámetros)",
|
||||
|
||||
"sidebar.nav.mcp": "Servidor MCP",
|
||||
|
||||
"settings.mcp.title": "Servidor MCP",
|
||||
"settings.mcp.description": "Configure el servidor Model Context Protocol que permite a los agentes de programación IA interactuar con su blog.",
|
||||
"settings.mcp.statusLabel": "Estado del servidor",
|
||||
@@ -1132,5 +1205,9 @@
|
||||
"duplicatesView.checkAll": "Seleccionar todo",
|
||||
"duplicatesView.uncheckAll": "Deseleccionar todo",
|
||||
"duplicatesView.dismissChecked": "Descartar seleccionados ({count})",
|
||||
"duplicatesView.notEnabled": "La similitud semántica no está activada. Actívela en Configuración → Tecnología."
|
||||
"duplicatesView.notEnabled": "La similitud semántica no está activada. Actívela en Configuración → Tecnología.",
|
||||
"editor.doNotTranslateLabel": "No traducir",
|
||||
"blog.fillMissing.nothingToDo": "Todas las traducciones están al día.",
|
||||
"blog.fillMissing.started": "Tarea de traducción iniciada. Consulte el panel de tareas para ver el progreso.",
|
||||
"blog.fillMissing.error": "Error al rellenar las traducciones faltantes."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user