parent
bbdbae2ea2
commit
53061710a9
@ -636,7 +636,33 @@ describe('config', () => {
|
|||||||
).toEqual({ structure: 'multiple_folders', locales: ['en', 'fr'], default_locale: 'fr' });
|
).toEqual({ structure: 'multiple_folders', locales: ['en', 'fr'], default_locale: 'fr' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when i18n is set on files collection', () => {
|
it('should throw when i18n structure is not single_file on files collection', () => {
|
||||||
|
expect(() =>
|
||||||
|
applyDefaults(
|
||||||
|
fromJS({
|
||||||
|
i18n: {
|
||||||
|
structure: 'multiple_folders',
|
||||||
|
locales: ['en', 'de'],
|
||||||
|
},
|
||||||
|
collections: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
name: 'file',
|
||||||
|
file: 'file',
|
||||||
|
i18n: true,
|
||||||
|
fields: [{ name: 'title', widget: 'string', i18n: true }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
i18n: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toThrow('i18n configuration for files collections is limited to single_file structure');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw when i18n structure is set to multiple_folders and contains a single file collection', () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
applyDefaults(
|
applyDefaults(
|
||||||
fromJS({
|
fromJS({
|
||||||
@ -654,7 +680,56 @@ describe('config', () => {
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).toThrow('i18n configuration is not supported for files collection');
|
).toThrow('i18n configuration for files collections is limited to single_file structure');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw when i18n structure is set to multiple_files and contains a single file collection', () => {
|
||||||
|
expect(() =>
|
||||||
|
applyDefaults(
|
||||||
|
fromJS({
|
||||||
|
i18n: {
|
||||||
|
structure: 'multiple_files',
|
||||||
|
locales: ['en', 'de'],
|
||||||
|
},
|
||||||
|
collections: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
{ name: 'file', file: 'file', fields: [{ name: 'title', widget: 'string' }] },
|
||||||
|
],
|
||||||
|
i18n: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).toThrow('i18n configuration for files collections is limited to single_file structure');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set i18n value to translate on field when i18n=true for field in files collection', () => {
|
||||||
|
expect(
|
||||||
|
applyDefaults(
|
||||||
|
fromJS({
|
||||||
|
i18n: {
|
||||||
|
structure: 'multiple_folders',
|
||||||
|
locales: ['en', 'de'],
|
||||||
|
},
|
||||||
|
collections: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
name: 'file',
|
||||||
|
file: 'file',
|
||||||
|
i18n: true,
|
||||||
|
fields: [{ name: 'title', widget: 'string', i18n: true }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
i18n: {
|
||||||
|
structure: 'single_file',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
).getIn(['collections', 0, 'files', 0, 'fields', 0, 'i18n']),
|
||||||
|
).toEqual('translate');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set i18n value to translate on field when i18n=true for field', () => {
|
it('should set i18n value to translate on field when i18n=true for field', () => {
|
||||||
|
@ -6,7 +6,7 @@ import * as publishModes from 'Constants/publishModes';
|
|||||||
import { validateConfig } from 'Constants/configSchema';
|
import { validateConfig } from 'Constants/configSchema';
|
||||||
import { selectDefaultSortableFields, traverseFields } from '../reducers/collections';
|
import { selectDefaultSortableFields, traverseFields } from '../reducers/collections';
|
||||||
import { resolveBackend } from 'coreSrc/backend';
|
import { resolveBackend } from 'coreSrc/backend';
|
||||||
import { I18N, I18N_FIELD } from '../lib/i18n';
|
import { I18N, I18N_FIELD, I18N_STRUCTURE } from '../lib/i18n';
|
||||||
|
|
||||||
export const CONFIG_REQUEST = 'CONFIG_REQUEST';
|
export const CONFIG_REQUEST = 'CONFIG_REQUEST';
|
||||||
export const CONFIG_SUCCESS = 'CONFIG_SUCCESS';
|
export const CONFIG_SUCCESS = 'CONFIG_SUCCESS';
|
||||||
@ -68,38 +68,53 @@ const setI18nField = field => {
|
|||||||
return field;
|
return field;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setI18nDefaults = (i18n, collection) => {
|
const setI18nDefaults = (defaultI18n, collectionOrFile) => {
|
||||||
if (i18n && collection.has(I18N)) {
|
if (defaultI18n && collectionOrFile.has(I18N)) {
|
||||||
const collectionI18n = collection.get(I18N);
|
const collectionOrFileI18n = collectionOrFile.get(I18N);
|
||||||
if (collectionI18n === true) {
|
if (collectionOrFileI18n === true) {
|
||||||
collection = collection.set(I18N, i18n);
|
collectionOrFile = collectionOrFile.set(I18N, defaultI18n);
|
||||||
} else if (collectionI18n === false) {
|
} else if (collectionOrFileI18n === false) {
|
||||||
collection = collection.delete(I18N);
|
collectionOrFile = collectionOrFile.delete(I18N);
|
||||||
} else {
|
} else {
|
||||||
const locales = collectionI18n.get('locales', i18n.get('locales'));
|
const locales = collectionOrFileI18n.get('locales', defaultI18n.get('locales'));
|
||||||
const defaultLocale = collectionI18n.get(
|
const defaultLocale = collectionOrFileI18n.get(
|
||||||
'default_locale',
|
'default_locale',
|
||||||
collectionI18n.has('locales') ? locales.first() : i18n.get('default_locale'),
|
collectionOrFileI18n.has('locales') ? locales.first() : defaultI18n.get('default_locale'),
|
||||||
);
|
);
|
||||||
collection = collection.set(I18N, i18n.merge(collectionI18n));
|
collectionOrFile = collectionOrFile.set(I18N, defaultI18n.merge(collectionOrFileI18n));
|
||||||
collection = collection.setIn([I18N, 'locales'], locales);
|
collectionOrFile = collectionOrFile.setIn([I18N, 'locales'], locales);
|
||||||
collection = collection.setIn([I18N, 'default_locale'], defaultLocale);
|
collectionOrFile = collectionOrFile.setIn([I18N, 'default_locale'], defaultLocale);
|
||||||
|
|
||||||
throwOnMissingDefaultLocale(collection.get(I18N));
|
throwOnMissingDefaultLocale(collectionOrFile.get(I18N));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collectionI18n !== false) {
|
if (collectionOrFileI18n !== false) {
|
||||||
// set default values for i18n fields
|
// set default values for i18n fields
|
||||||
collection = collection.set('fields', traverseFields(collection.get('fields'), setI18nField));
|
if (collectionOrFile.has('fields')) {
|
||||||
|
collectionOrFile = collectionOrFile.set(
|
||||||
|
'fields',
|
||||||
|
traverseFields(collectionOrFile.get('fields'), setI18nField),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
collection = collection.delete(I18N);
|
collectionOrFile = collectionOrFile.delete(I18N);
|
||||||
collection = collection.set(
|
if (collectionOrFile.has('fields')) {
|
||||||
|
collectionOrFile = collectionOrFile.set(
|
||||||
'fields',
|
'fields',
|
||||||
traverseFields(collection.get('fields'), field => field.delete(I18N)),
|
traverseFields(collectionOrFile.get('fields'), field => field.delete(I18N)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return collectionOrFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
const throwOnInvalidFileCollectionStructure = i18n => {
|
||||||
|
if (i18n && i18n.get('structure') !== I18N_STRUCTURE.SINGLE_FILE) {
|
||||||
|
throw new Error(
|
||||||
|
`i18n configuration for files collections is limited to ${I18N_STRUCTURE.SINGLE_FILE} structure`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return collection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const throwOnMissingDefaultLocale = i18n => {
|
const throwOnMissingDefaultLocale = i18n => {
|
||||||
@ -211,6 +226,8 @@ export function applyDefaults(config) {
|
|||||||
collection = collection.set('publish', true);
|
collection = collection.set('publish', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collection = setI18nDefaults(i18n, collection);
|
||||||
|
|
||||||
const folder = collection.get('folder');
|
const folder = collection.get('folder');
|
||||||
if (folder) {
|
if (folder) {
|
||||||
if (collection.has('path') && !collection.has('media_folder')) {
|
if (collection.has('path') && !collection.has('media_folder')) {
|
||||||
@ -238,15 +255,13 @@ export function applyDefaults(config) {
|
|||||||
} else {
|
} else {
|
||||||
collection = collection.set('meta', Map());
|
collection = collection.set('meta', Map());
|
||||||
}
|
}
|
||||||
|
|
||||||
collection = setI18nDefaults(i18n, collection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const files = collection.get('files');
|
const files = collection.get('files');
|
||||||
if (files) {
|
if (files) {
|
||||||
if (i18n && collection.has(I18N)) {
|
const collectionI18n = collection.get(I18N);
|
||||||
throw new Error('i18n configuration is not supported for files collection');
|
throwOnInvalidFileCollectionStructure(collectionI18n);
|
||||||
}
|
|
||||||
collection = collection.delete('nested');
|
collection = collection.delete('nested');
|
||||||
collection = collection.delete('meta');
|
collection = collection.delete('meta');
|
||||||
collection = collection.set(
|
collection = collection.set(
|
||||||
@ -258,6 +273,8 @@ export function applyDefaults(config) {
|
|||||||
'fields',
|
'fields',
|
||||||
traverseFields(file.get('fields'), setDefaultPublicFolder),
|
traverseFields(file.get('fields'), setDefaultPublicFolder),
|
||||||
);
|
);
|
||||||
|
file = setI18nDefaults(collectionI18n, file);
|
||||||
|
throwOnInvalidFileCollectionStructure(file.get(I18N));
|
||||||
return file;
|
return file;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -400,6 +400,33 @@ describe('i18n', () => {
|
|||||||
raw: '',
|
raw: '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should default to empty data object when file is empty and structure is I18N_STRUCTURE.SINGLE_FILE', async () => {
|
||||||
|
const data = {
|
||||||
|
'src/content/index.md': {
|
||||||
|
slug: 'index',
|
||||||
|
path: 'src/content/index.md',
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const getEntryValue = jest.fn(path => Promise.resolve(data[path]));
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
i18n.getI18nEntry(
|
||||||
|
fromJS({
|
||||||
|
i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale },
|
||||||
|
}),
|
||||||
|
...args,
|
||||||
|
getEntryValue,
|
||||||
|
),
|
||||||
|
).resolves.toEqual({
|
||||||
|
slug: 'index',
|
||||||
|
path: 'src/content/index.md',
|
||||||
|
data: {},
|
||||||
|
i18n: {},
|
||||||
|
raw: '',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('groupEntries', () => {
|
describe('groupEntries', () => {
|
||||||
|
@ -244,7 +244,7 @@ const mergeValues = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mergeSingleFileValue = (entryValue: EntryValue, defaultLocale: string, locales: string[]) => {
|
const mergeSingleFileValue = (entryValue: EntryValue, defaultLocale: string, locales: string[]) => {
|
||||||
const data = entryValue.data[defaultLocale];
|
const data = entryValue.data[defaultLocale] || {};
|
||||||
const i18n = locales
|
const i18n = locales
|
||||||
.filter(l => l !== defaultLocale)
|
.filter(l => l !== defaultLocale)
|
||||||
.map(l => ({ locale: l, value: entryValue.data[l] }))
|
.map(l => ({ locale: l, value: entryValue.data[l] }))
|
||||||
|
@ -130,7 +130,7 @@ collections:
|
|||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
1. File collections are not supported.
|
1. File collections support only `structure: single_file`.
|
||||||
2. List widgets only support `i18n: true`. `i18n` configuration on sub fields is ignored.
|
2. List widgets only support `i18n: true`. `i18n` configuration on sub fields is ignored.
|
||||||
3. Object widgets only support `i18n: true` and `i18n` configuration should be done per field:
|
3. Object widgets only support `i18n: true` and `i18n` configuration should be done per field:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user