Comments (20)
I installed FilePond yesterday but needed to translate it, so I made translation in brazilian portuguese. Maybe it is useful for someone. And congratulations for the library, it is very nice.
Best regards.
const labels_pt_BR = {
// labelIdle: 'Drag & Drop your files or <span class="filepond--label-action"> Browse </span>'
labelIdle: 'Arraste e solte os arquivos ou <span class="filepond--label-action"> Clique aqui </span>',
// labelInvalidField: 'Field contains invalid files',
labelInvalidField: 'Arquivos inválidos',
// labelFileWaitingForSize: 'Waiting for size',
labelFileWaitingForSize: 'Calculando o tamanho do arquivo',
// labelFileSizeNotAvailable: 'Size not available',
labelFileSizeNotAvailable: 'Tamanho do arquivo indisponível',
// labelFileLoading: 'Loading',
labelFileLoading: 'Carregando',
// labelFileLoadError: 'Error during load',
labelFileLoadError: 'Erro durante o carregamento',
// labelFileProcessing: 'Uploading',
labelFileProcessing: 'Enviando',
// labelFileProcessingComplete: 'Upload complete',
labelFileProcessingComplete: 'Envio finalizado',
// labelFileProcessingAborted: 'Upload cancelled',
labelFileProcessingAborted: 'Envio cancelado',
// labelFileProcessingError: 'Error during upload',
labelFileProcessingError: 'Erro durante o envio',
// labelFileProcessingRevertError: 'Error during revert',
labelFileProcessingRevertError: 'Erro ao reverter o envio',
// labelFileRemoveError: 'Error during remove',
labelFileRemoveError: 'Erro ao remover o arquivo',
// labelTapToCancel: 'tap to cancel',
labelTapToCancel: 'clique para cancelar',
// labelTapToRetry: 'tap to retry',
labelTapToRetry: 'clique para reenviar',
// labelTapToUndo: 'tap to undo',
labelTapToUndo: 'clique para desfazer',
// labelButtonRemoveItem: 'Remove',
labelButtonRemoveItem: 'Remover',
// labelButtonAbortItemLoad: 'Abort',
labelButtonAbortItemLoad: 'Abortar',
// labelButtonRetryItemLoad: 'Retry',
labelButtonRetryItemLoad: 'Reenviar',
// labelButtonAbortItemProcessing: 'Cancel',
labelButtonAbortItemProcessing: 'Cancelar',
// labelButtonUndoItemProcessing: 'Undo',
labelButtonUndoItemProcessing: 'Desfazer',
// labelButtonRetryItemProcessing: 'Retry',
labelButtonRetryItemProcessing: 'Reenviar',
// labelButtonProcessItem: 'Upload',
labelButtonProcessItem: 'Enviar',
// labelMaxFileSizeExceeded: 'File is too large',
labelMaxFileSizeExceeded: 'Arquivo é muito grande',
// labelMaxFileSize: 'Maximum file size is {filesize}',
labelMaxFileSize: 'O tamanho máximo permitido: {filesize}',
// labelMaxTotalFileSizeExceeded: 'Maximum total size exceeded',
labelMaxTotalFileSizeExceeded: 'Tamanho total dos arquivos excedido',
// labelMaxTotalFileSize: 'Maximum total file size is {filesize}',
labelMaxTotalFileSize: 'Tamanho total permitido: {filesize}',
// labelFileTypeNotAllowed: 'File of invalid type',
labelFileTypeNotAllowed: 'Tipo de arquivo inválido',
// fileValidateTypeLabelExpectedTypes: 'Expects {allButLastType} or {lastType}',
fileValidateTypeLabelExpectedTypes: 'Tipos de arquivo suportados são {allButLastType} ou {lastType}',
// imageValidateSizeLabelFormatError: 'Image type not supported',
imageValidateSizeLabelFormatError: 'Tipo de imagem inválida',
// imageValidateSizeLabelImageSizeTooSmall: 'Image is too small',
imageValidateSizeLabelImageSizeTooSmall: 'Imagem muito pequena',
// imageValidateSizeLabelImageSizeTooBig: 'Image is too big',
imageValidateSizeLabelImageSizeTooBig: 'Imagem muito grande',
// imageValidateSizeLabelExpectedMinSize: 'Minimum size is {minWidth} × {minHeight}',
imageValidateSizeLabelExpectedMinSize: 'Tamanho mínimo permitida: {minWidth} × {minHeight}',
// imageValidateSizeLabelExpectedMaxSize: 'Maximum size is {maxWidth} × {maxHeight}',
imageValidateSizeLabelExpectedMaxSize: 'Tamanho máximo permitido: {maxWidth} × {maxHeight}',
// imageValidateSizeLabelImageResolutionTooLow: 'Resolution is too low',
imageValidateSizeLabelImageResolutionTooLow: 'Resolução muito baixa',
// imageValidateSizeLabelImageResolutionTooHigh: 'Resolution is too high',
imageValidateSizeLabelImageResolutionTooHigh: 'Resolução muito alta',
// imageValidateSizeLabelExpectedMinResolution: 'Minimum resolution is {minResolution}',
imageValidateSizeLabelExpectedMinResolution: 'Resolução mínima permitida: {minResolution}',
// imageValidateSizeLabelExpectedMaxResolution: 'Maximum resolution is {maxResolution}'
imageValidateSizeLabelExpectedMaxResolution: 'Resolução máxima permitida: {maxResolution}'
};
from filepond.
You can pass translations to FilePond using options parameters.
FilePond.setOptions({
labelFileWaitingForSize: 'Waiting for filesize',
labelFileSizeNotAvailable: 'Filesize not available'
});
That's not what you're looking for?
from filepond.
Hello everyone, these are the german translations:
const labels_de_DE {
// labelIdle: 'Drag & Drop your files or <span class="filepond--label-action"> Browse </span>'
labelIdle: 'Dateien ablegen oder <span class="filepond--label-action"> auswählen </span>',
// labelInvalidField: 'Field contains invalid files',
labelInvalidField: 'Feld beinhaltet ungültige Dateien',
// labelFileWaitingForSize: 'Waiting for size',
labelFileWaitingForSize: 'Dateigröße berechnen',
// labelFileSizeNotAvailable: 'Size not available',
labelFileSizeNotAvailable: 'Dateigröße nicht verfügbar',
// labelFileLoading: 'Loading',
labelFileLoading: 'Laden',
// labelFileLoadError: 'Error during load',
labelFileLoadError: 'Fehler beim Laden',
// labelFileProcessing: 'Uploading',
labelFileProcessing: 'Upload läuft',
// labelFileProcessingComplete: 'Upload complete',
labelFileProcessingComplete: 'Upload abgeschlossen',
// labelFileProcessingAborted: 'Upload cancelled',
labelFileProcessingAborted: 'Upload abgebrochen',
// labelFileProcessingError: 'Error during upload',
labelFileProcessingError: 'Fehler beim Upload',
// labelFileProcessingRevertError: 'Error during revert',
labelFileProcessingRevertError: 'Fehler beim Wiederherstellen',
// labelFileRemoveError: 'Error during remove',
labelFileRemoveError: 'Fehler beim Löschen',
// labelTapToCancel: 'tap to cancel',
labelTapToCancel: 'abbrechen',
// labelTapToRetry: 'tap to retry',
labelTapToRetry: 'erneut versuchen',
// labelTapToUndo: 'tap to undo',
labelTapToUndo: 'rückgängig',
// labelButtonRemoveItem: 'Remove',
labelButtonRemoveItem: 'Entfernen',
// labelButtonAbortItemLoad: 'Abort',
labelButtonAbortItemLoad: 'Verwerfen',
// labelButtonRetryItemLoad: 'Retry',
labelButtonRetryItemLoad: 'Erneut versuchen',
// labelButtonAbortItemProcessing: 'Cancel',
labelButtonAbortItemProcessing: 'Abbrechen',
// labelButtonUndoItemProcessing: 'Undo',
labelButtonUndoItemProcessing: 'Rückgängig',
// labelButtonRetryItemProcessing: 'Retry',
labelButtonRetryItemProcessing: 'Erneut versuchen',
// labelButtonProcessItem: 'Upload',
labelButtonProcessItem: 'Upload',
// labelMaxFileSizeExceeded: 'File is too large',
labelMaxFileSizeExceeded: 'Datei ist zu groß',
// labelMaxFileSize: 'Maximum file size is {filesize}',
labelMaxFileSize: 'Maximale Dateigröße: {filesize}',
// labelMaxTotalFileSizeExceeded: 'Maximum total size exceeded',
labelMaxTotalFileSizeExceeded: 'Maximale gesamte Dateigröße überschritten',
// labelMaxTotalFileSize: 'Maximum total file size is {filesize}',
labelMaxTotalFileSize: 'Maximale gesamte Dateigröße: {filesize}',
// labelFileTypeNotAllowed: 'File of invalid type',
labelFileTypeNotAllowed: 'Dateityp ungültig',
// fileValidateTypeLabelExpectedTypes: 'Expects {allButLastType} or {lastType}',
fileValidateTypeLabelExpectedTypes: 'Erwartet {allButLastType} oder {lastType}',
// imageValidateSizeLabelFormatError: 'Image type not supported',
imageValidateSizeLabelFormatError: 'Bildtyp nicht unterstützt',
// imageValidateSizeLabelImageSizeTooSmall: 'Image is too small',
imageValidateSizeLabelImageSizeTooSmall: 'Bild ist zu klein',
// imageValidateSizeLabelImageSizeTooBig: 'Image is too big',
imageValidateSizeLabelImageSizeTooBig: 'Bild ist zu groß',
// imageValidateSizeLabelExpectedMinSize: 'Minimum size is {minWidth} × {minHeight}',
imageValidateSizeLabelExpectedMinSize: 'Mindestgröße: {minWidth} × {minHeight}',
// imageValidateSizeLabelExpectedMaxSize: 'Maximum size is {maxWidth} × {maxHeight}',
imageValidateSizeLabelExpectedMaxSize: 'Maximale Größe: {maxWidth} × {maxHeight}',
// imageValidateSizeLabelImageResolutionTooLow: 'Resolution is too low',
imageValidateSizeLabelImageResolutionTooLow: 'Auflösung ist zu niedrig',
// imageValidateSizeLabelImageResolutionTooHigh: 'Resolution is too high',
imageValidateSizeLabelImageResolutionTooHigh: 'Auflösung ist zu hoch',
// imageValidateSizeLabelExpectedMinResolution: 'Minimum resolution is {minResolution}',
imageValidateSizeLabelExpectedMinResolution: 'Mindestauflösung: {minResolution}',
// imageValidateSizeLabelExpectedMaxResolution: 'Maximum resolution is {maxResolution}'
imageValidateSizeLabelExpectedMaxResolution: 'Maximale Auflösung: {maxResolution}'
};
from filepond.
Thank you for the amazing library and thank you @leonardoarruda for the Portuguese translation. I also made a translation into Spanish. Maybe it is also useful for someone:
const labels_es_ES = {
labelIdle: 'Arrastra y suelta tus archivos o <span class = "filepond--label-action"> Examinar <span>',
labelInvalidField: "El campo contiene archivos inválidos",
labelFileWaitingForSize: "Esperando tamaño",
labelFileSizeNotAvailable: "Tamaño no disponible",
labelFileLoading: "Cargando",
labelFileLoadError: "Error durante la carga",
labelFileProcessing: "Cargando",
labelFileProcessingComplete: "Carga completa",
labelFileProcessingAborted: "Carga cancelada",
labelFileProcessingError: "Error durante la carga",
labelFileProcessingRevertError: "Error durante la reversión",
labelFileRemoveError: "Error durante la eliminación",
labelTapToCancel: "toca para cancelar",
labelTapToRetry: "tocar para volver a intentar",
labelTapToUndo: "tocar para deshacer",
labelButtonRemoveItem: "Eliminar",
labelButtonAbortItemLoad: "Abortar",
labelButtonRetryItemLoad: "Reintentar",
labelButtonAbortItemProcessing: "Cancelar",
labelButtonUndoItemProcessing: "Deshacer",
labelButtonRetryItemProcessing: "Reintentar",
labelButtonProcessItem: "Cargar",
labelMaxFileSizeExceeded: "El archivo es demasiado grande",
labelMaxFileSize: "El tamaño máximo del archivo es {filesize}",
labelMaxTotalFileSizeExceeded: "Tamaño total máximo excedido",
labelMaxTotalFileSize: "El tamaño total máximo del archivo es {filesize}",
labelFileTypeNotAllowed: "Archivo de tipo no válido",
fileValidateTypeLabelExpectedTypes: "Espera {allButLastType} o {lastType}",
imageValidateSizeLabelFormatError: "Tipo de imagen no compatible",
imageValidateSizeLabelImageSizeTooSmall: "La imagen es demasiado pequeña",
imageValidateSizeLabelImageSizeTooBig: "La imagen es demasiado grande",
imageValidateSizeLabelExpectedMinSize: "El tamaño mínimo es {minWidth} × {minHeight}",
imageValidateSizeLabelExpectedMaxSize: "El tamaño máximo es {maxWidth} × {maxHeight}",
imageValidateSizeLabelImageResolutionTooLow: "La resolución es demasiado baja",
imageValidateSizeLabelImageResolutionTooHigh: "La resolución es demasiado alta",
imageValidateSizeLabelExpectedMinResolution: "La resolución mínima es {minResolution}",
imageValidateSizeLabelExpectedMaxResolution: "La resolución máxima es {maxResolution}",
};
from filepond.
Hi Rik, that solution is a little naive. The interesting part is to choose the language. If the browser is in Spanish should be Spanish, but if the browser is in Italian should be English (or the default language). Moreover, we can have partial translation, because someone can contribute the Italian translation, but with the time we extend the Spanish and English translation, but not the Italian one. So with the browser in Italian exiting labels in Italian should be taken from Italian and the rest for English.
Anyways, I already have implemented it in OpenXava for FilePond, so I have the problem solved. But it would be nice to save two days of work. Including the translation for major languages and a very simple way (just to write the labes_it.js) to add a new language would be a good improvement for filepond.
from filepond.
For people looking for russian translation:
const labels_RU = {
// labelIdle: 'Drag & Drop your files or <span class="filepond--label-action"> Browse </span>'
labelIdle: 'Перетащите или выберите <span class="filepond--label-action"> Изображение </span>',
// labelInvalidField: 'Field contains invalid files',
labelInvalidField: 'Поле содержит недопустимые файлы',
// labelFileWaitingForSize: 'Waiting for size',
labelFileWaitingForSize: 'Укажите размер',
// labelFileSizeNotAvailable: 'Size not available',
labelFileSizeNotAvailable: 'Размер не поддерживается',
// labelFileLoading: 'Loading',
labelFileLoading: 'Ожидание',
// labelFileLoadError: 'Error during load',
labelFileLoadError: 'Ошибка при ожидании',
// labelFileProcessing: 'Uploading',
labelFileProcessing: 'Загрузка',
// labelFileProcessingComplete: 'Upload complete',
labelFileProcessingComplete: 'Загрузка завершена',
// labelFileProcessingAborted: 'Upload cancelled',
labelFileProcessingAborted: 'Загрузка отменена',
// labelFileProcessingError: 'Error during upload',
labelFileProcessingError: 'Ошибка при загрузке',
// labelFileProcessingRevertError: 'Error during revert',
labelFileProcessingRevertError: 'Ошибка при возврате',
// labelFileRemoveError: 'Error during remove',
labelFileRemoveError: 'Ошибка при удалении',
// labelTapToCancel: 'tap to cancel',
labelTapToCancel: 'нажмите для отмены',
// labelTapToRetry: 'tap to retry',
labelTapToRetry: 'нажмите, чтобы повторить попытку',
// labelTapToUndo: 'tap to undo',
labelTapToUndo: 'нажмите для отмены последнего действия',
// labelButtonRemoveItem: 'Remove',
labelButtonRemoveItem: 'Удалить',
// labelButtonAbortItemLoad: 'Abort',
labelButtonAbortItemLoad: 'Прекращено',
// labelButtonRetryItemLoad: 'Retry',
labelButtonRetryItemLoad: 'Повторите попытку',
// labelButtonAbortItemProcessing: 'Cancel',
labelButtonAbortItemProcessing: 'Отмена',
// labelButtonUndoItemProcessing: 'Undo',
labelButtonUndoItemProcessing: 'Отмена последнего действия',
// labelButtonRetryItemProcessing: 'Retry',
labelButtonRetryItemProcessing: 'Повторите попытку',
// labelButtonProcessItem: 'Upload',
labelButtonProcessItem: 'Загрузка',
// labelMaxFileSizeExceeded: 'File is too large',
labelMaxFileSizeExceeded: 'Файл слишком большой',
// labelMaxFileSize: 'Maximum file size is {filesize}',
labelMaxFileSize: 'Максимальный размер файла: {filesize}',
// labelMaxTotalFileSizeExceeded: 'Maximum total size exceeded',
labelMaxTotalFileSizeExceeded: 'Превышен максимальный размер',
// labelMaxTotalFileSize: 'Maximum total file size is {filesize}',
labelMaxTotalFileSize: 'Максимальный размер файла: {filesize}',
// labelFileTypeNotAllowed: 'File of invalid type',
labelFileTypeNotAllowed: 'Файл неверного типа',
// fileValidateTypeLabelExpectedTypes: 'Expects {allButLastType} or {lastType}',
fileValidateTypeLabelExpectedTypes: 'Tipos de arquivo suportados são {allButLastType} ou {lastType}',
// imageValidateSizeLabelFormatError: 'Image type not supported',
imageValidateSizeLabelFormatError: 'Тип изображения не поддерживается',
// imageValidateSizeLabelImageSizeTooSmall: 'Image is too small',
imageValidateSizeLabelImageSizeTooSmall: 'Изображение слишком маленькое',
// imageValidateSizeLabelImageSizeTooBig: 'Image is too big',
imageValidateSizeLabelImageSizeTooBig: 'Изображение слишком большое',
// imageValidateSizeLabelExpectedMinSize: 'Minimum size is {minWidth} × {minHeight}',
imageValidateSizeLabelExpectedMinSize: 'Минимальный размер: {minWidth} × {minHeight}',
// imageValidateSizeLabelExpectedMaxSize: 'Maximum size is {maxWidth} × {maxHeight}',
imageValidateSizeLabelExpectedMaxSize: 'Максимальный размер: {maxWidth} × {maxHeight}',
// imageValidateSizeLabelImageResolutionTooLow: 'Resolution is too low',
imageValidateSizeLabelImageResolutionTooLow: 'Разрешение слишком низкое',
// imageValidateSizeLabelImageResolutionTooHigh: 'Resolution is too high',
imageValidateSizeLabelImageResolutionTooHigh: 'Разрешение слишком высокое',
// imageValidateSizeLabelExpectedMinResolution: 'Minimum resolution is {minResolution}',
imageValidateSizeLabelExpectedMinResolution: 'Минимальное разрешение: {minResolution}',
// imageValidateSizeLabelExpectedMaxResolution: 'Maximum resolution is {maxResolution}'
imageValidateSizeLabelExpectedMaxResolution: 'Максимальное разрешение: {maxResolution}'
};
from filepond.
@Tofandel This is the advise I was looking for, thanks!
I've created a locale
directory and have added the Brazilian Portuguese translation file, PR's for other locales are very welcome.
import pt_BR from 'filepond/locale/pt-br.js';
FilePond.setOptions(pt_BR);
from filepond.
Hello there,
I made Japanese one as well.
const labels_ja_JA = {
labelIdle: '画像又はビデオをドラッグ&ドロップ又は <span class="filepond--label-action">ファイル選択</span>',
labelInvalidField: "アップロードできないファイルが含まれています",
labelFileWaitingForSize: "ファイルサイズを待っています",
labelFileSizeNotAvailable: "ファイルサイズがみつかりません",
labelFileLoading: "読込中...",
labelFileLoadError: "ロード中にエラーが発生",
labelFileProcessing: "読込中...",
labelFileProcessingComplete: "アップロード完了",
labelFileProcessingAborted: "アップロードがキャンセルしました",
labelFileProcessingError: "アップロード中にエラーが発生",
labelFileProcessingRevertError: "ロールバック中にエラーが発生",
labelFileRemoveError: "削除中にエラーが発生",
labelTapToCancel: "クリックしてキャンセル",
labelTapToRetry: "クリックしてもう一度お試し下さい",
labelTapToUndo: "元に戻すにはタップします",
labelButtonRemoveItem: "削除",
labelButtonAbortItemLoad: "中断",
labelButtonRetryItemLoad: "もう一度実行",
labelButtonAbortItemProcessing: "キャンセル",
labelButtonUndoItemProcessing: "元に戻す",
labelButtonRetryItemProcessing: "もう一度実行",
labelButtonProcessItem: "アップロード",
labelMaxFileSizeExceeded: "ファイルサイズが大きすぎます",
labelMaxFileSize: "最大ファイルサイズは {filesize} です",
labelMaxTotalFileSizeExceeded: "最大合計サイズを超えました",
labelMaxTotalFileSize: "最大合計ファイルサイズは {filesize} です",
labelFileTypeNotAllowed: "無効なファイルです",
fileValidateTypeLabelExpectedTypes: "サポートしているファイルは {allButLastType} 又は {lastType} です",
imageValidateSizeLabelFormatError: "サポートしていない画像です",
imageValidateSizeLabelImageSizeTooSmall: "画像が小さすぎます",
imageValidateSizeLabelImageSizeTooBig: "画像が大きすぎます",
imageValidateSizeLabelExpectedMinSize: "画像の最小サイズは{minWidth}×{minHeight}です",
imageValidateSizeLabelExpectedMaxSize: "画像の最大サイズは{maxWidth} × {maxHeight}です",
imageValidateSizeLabelImageResolutionTooLow: "画像の解像度が低すぎます",
imageValidateSizeLabelImageResolutionTooHigh: "画像の解像度が高すぎます",
imageValidateSizeLabelExpectedMinResolution: "画像の最小解像度は{minResolution}です",
imageValidateSizeLabelExpectedMaxResolution: "画像の最大解像度は{minResolution}です",
};
from filepond.
@cooldesigns It's not clear what you're getting at. I need more information than this. Pro's, con's, good practises, examples.
from filepond.
if we keep the translations in JavaScript code, our code will looks like spaghetti.
if we make translations in our config, not in the library. Peoples which use this library make translations by ourself, but actually we can share our translations and we can save someones time.
The important part is a big question about how we can use it international web apps.
I think it can be done with a 'locales' folder which contains javascript files for each language
from filepond.
FilePond.setOptions is NOT a good way to do the application multilanguage, because we have to do a lot of programming for that.
The usual solution is to have several properties files, one by each locale, for example:
labels_en.properties:
labelFileWaitingForSize=Waiting for filesize
labelFileSizeNotAvailable=Filesize not available
labels_es.properties:
labelFileWaitingForSize=Esperando el tamaño del archivo
labelFileSizeNotAvailable=Tamaño del archivo no disponible
And then if the browser is in English use the labels of first file and if in Spanish the ones of the second file. In this way, an Italian can do a translation to Italian just copy the labels_en.properties to labels_it.properties and making the translation.
Indeed should be nice that Filepond would include the translation to some main languages. In fact, I used the above technique for my open source project (OpenXava) and it has the labels and messages translated by default to English, Spanish, German, French, Chinese, Russian, Japanese, Catalan, Indonesian, Italian, Polish, Serbian and Swedish, most of them contributed by the community.
from filepond.
@javierpaniza What's holding you back from creating a file like that and then passing it to FilePond.setOptions
? I'm interested to learn but I guess something like this works?
// in labels_en.js
const labels_en = {
labelFileWaitingForSize: "Waiting for filesize"
labelFileSizeNotAvailable: "Filesize not available"
};
// in labels_es.js
const labels_es = {
labelFileWaitingForSize: "Esperando el tamaño del archivo"
labelFileSizeNotAvailable: "Tamaño del archivo no disponible"
};
// in page
FilePond.setOptions(labels_es);
from filepond.
Would be so much easier indeed if those locales could be added to a locales folder in .json in this library and then imported into filepond as needed with a better API.. Instead of all the users having to create new translations every time
Eg:
// Overriding default locale without lazy loading
import { ru_RU } from 'filepond/locales'
FilePond.setOptions({
locale: ru_RU
});
// Or multiple locales lazy loaded (all could be included lazy loaded by default, but keys and full translations can be overridden with the following api), this is what all localizable libraries use
FilePond.setOptions({
locales: {
es: () => import('filepond/locales/es_ES.json'),
ru: () => import('filepond/locales/ru_RU.json')
},
locale: 'ru'
});
// Switch locale
FilePond.setOptions({ locale: 'es' })
That was the point of the author of this issue, and if some translations are not correct they can still be overwritten
import { es_ES } from 'filepond/locales'
es_ES.InvalidField = 'El campo tiene archivos inválidos';
FilePond.setOptions({
locale: es_ES
});
If that feature is included, the 'label' part should be removed from the json object's keys as they are super redundant
from filepond.
Okay that's already a first step 👍 now adding the API as I described would be good, I already made one externally so I can do a PR without too much work in a few weeks
from filepond.
@Tofandel I'm not sold yet on the idea of having locale handling inside FilePond, a lot of projects don't need it, and with setOptions
it seems that loading a new locale is as straightforward as calling setOptions(newLocale)
from filepond.
This API is not something huge, it would take less than 1Kb in the build as files are lazy loaded on demand. You can also make it available as an exported method in the lib non bundled in the build that could be imported and so treeshaked by default, because let's be honest, if you're not willing to include localization in your api, you're handicaping the not so minor portion of developers that will need it by making them have to rewrite a localization logic.
If you're still resilient then you should consider making the options nested, that is having all labels under a "label" options, at least when exposed trough the set options externally, it's really not a good idea to mix labels and options all at the same level, it also makes the translation files unnecessarily big and painful to write when they could look like this
{
"ButtonProcessItem": "Upload",
"imageValidateSize": {
"ImageSizeTooSmall": "Image is too small"
}
}
Where plugin translations are nested under their name and without the label in the name of each property
You can do so with this function
const recursiveFlattenOptions = (out, options, infix = '', prefix = '') => {
Object.keys(options).forEach((k) => {
if (typeof options[k] === 'object' && options[k] !== null) {
recursiveFlattenOptions(out, options[k], prefix.charAt(0).toUpperCase() + prefix.slice(1) + infix, k);
} else {
out[prefix + infix + k] = options[k];
}
});
};
//Usage
const out = {};
recursiveOptions(out, { someOption: 'test', label:{
"ButtonProcessItem": "Upload",
"imageValidateSize": {
"ImageSizeTooSmall": "Image is too small"
}
}
});
console.log(out);
{"someOption":"test","labelButtonProcessItem":"Upload","imageValidateSizeLabelImageSizeTooSmall":"Image is too small"}
Or without the infix logic if you want to separate plugins options under their own path
A lot of other options could be grouped under their own path as well IMO (Eg: icon, style, allow, hooks, events) and I would argue that you could save quite some space by removing type checking in options logic that's here even on production code when you could use typescript but that's another discussion
Also with setOptions when switching locale if not all properties are defined (which may be the case with incomplete translations, which will happen when adding a plugin or a string) you may have leftovers of the previous used locale not getting overridden instead of the fallback locale that the locale API could normally handle
from filepond.
it's really not a good idea to mix labels and options all at the same level
Why not?
it also makes the translation files unnecessarily big and painful to write
IMHO gzip takes care of all that duplication, it's a decision I made at the start of the project, maybe I'll change this in a new major release but it hasn't been a deal breaker so far. It might be a bit tedious, but once a translation file is written it's pretty much done.
Also, I guess plugin translations should be in the plugins instead of in the core as it's a bit wasteful to get all kinds of plugin translations (what about third party plugins) when not using any related plugins. I'll probably edit and remove plugin labels from the core translation files before pushing to npm. Then I'll add locale
folders to each plugin.
you could save quite some space by removing type checking in options logic that's here even on production code when you could use typescript but that's another discussion
For sure this can be improved, but I'd rather release a new major version further down the line than change this now.
Also with
setOptions
when switching locale if not all properties are defined you may have leftovers of the previous used locale not getting overridden
I guess we can solve this by adding an en_en
locale as fallback. Something like
FilePond.setOptions({...en_EN, ...pt_BR})
from filepond.
it's really not a good idea to mix labels and options all at the same level
Why not?
Just for the sake of readability and keeping a clearer separation between the options that will actually have an incidence on the behavior of the widget (server, allowed files, size etc) and the ones that are there only for appearance/style/localization
Plugins translations is exactly where a locale api would be useful, as you'd have to import the locale for each plugin separately (Already importing multiple plugins and setting them up is such a pain, I'm using more than 7 and it took me more than a day to set it all up because I'm lazy loading them and lazy loading filepond as well) So if you also need to manage and import translations for each plugin separately, you'll just want to dig a hole and cry in it...
What do you think about having a separate plugin for the localization api?
Then each plugin and the default filepond can all expose their own translation in their /locales folder
Filepond.setOptions({
locale: 'es', //Can support short and long version
fallbackLocale: 'en'
})
And the plugin gives the localization api so it's not there by default, the only thing I'd add by default is the en_EN.json file and import the default strings from it in filepond rather than hardcoding them in the default options, only a change in structure and nothing breaking, so at least when you want to create a translation you just copy this file
If you want to do a breaking change you'd normally force users to import the default locale themselves and add it in the options, so that if your fallback locale is not 'en' you don't get a lot of english translations in your bundle that are never gonna be shown, this is what some libs do
I'll add vuetify and veevalidate as a localization api reference as they have a good one
https://vuetifyjs.com/en/customization/internationalization/
https://vee-validate.logaretm.com/v2/guide/localization.html#using-the-dictionary-api
from filepond.
I'm on a short vacation, will get back to you in a couple weeks.
from filepond.
If you've created a new translations file, please add it to the locale
folder and submit a Pull Request 👍
from filepond.
Related Issues (20)
- [Feature] Customize Animation Duration
- [Bug] [react-filepond] State update in onremovefile event handler triggers file re-upload HOT 2
- [Bug] url.split is not a function when attempting to load "local" images (React 18) HOT 6
- Converting Headers key to CamelCase? HOT 1
- Bootstrap 5 image preview as gallery [Feature] HOT 2
- [Feature] How to show file limits to a custom html area with a selector HOT 5
- filepond--list-scroller overlays other elements [Bug] HOT 5
- Display a custom message on Upload complete, including data from the server response HOT 3
- I'm not able to drag an attachment from Outlook or Gmail HOT 3
- [Bug?] HOT 1
- [Bug] typings missing processfiles event HOT 1
- Upload of a large file (100s Mb) restarted each time a response received from back-end HOT 3
- Foreign character failure - unescape(encodeURIComponent(options.headers[key])); [Bug] HOT 3
- Filepond not working HOT 2
- [Bug] Method 'onupdatefiles' doesn't recognize states updates HOT 1
- [Bug] Safari click on custom idleLabel prop requires 2 clicks to trigger file upload dialog
- how to handle custom error message on maxFilesLimit HOT 2
- [Feature] is it possible to create custom file preview HOT 5
- Accessing the transformed image HOT 2
- Struggle with formData append HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from filepond.