docs: filterAvailableLocales (#11031)
Adding documentation and tests missing in PR #11007 --------- Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com> Co-authored-by: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
This commit is contained in:
@@ -78,10 +78,11 @@ export default buildConfig({
|
|||||||
The following options are available:
|
The following options are available:
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
| -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| **`locales`** | Array of all the languages that you would like to support. [More details](#locales) |
|
| **`locales`** | Array of all the languages that you would like to support. [More details](#locales) |
|
||||||
| **`defaultLocale`** | Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale. |
|
| **`defaultLocale`** | Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale. |
|
||||||
| **`fallback`** | Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated unless a fallback is explicitly provided in the request. True by default. |
|
| **`fallback`** | Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated unless a fallback is explicitly provided in the request. True by default. |
|
||||||
|
| **`filterAvailableLocales`** | A function that is called with the array of `locales` and the `req`, it should return locales to show in admin UI selector. [See more](#filter-available-options). |
|
||||||
|
|
||||||
### Locales
|
### Locales
|
||||||
|
|
||||||
@@ -100,6 +101,35 @@ The locale codes do not need to be in any specific format. It's up to you to def
|
|||||||
|
|
||||||
_* An asterisk denotes that a property is required._
|
_* An asterisk denotes that a property is required._
|
||||||
|
|
||||||
|
#### Filter Available Options
|
||||||
|
In some projects you may want to filter the available locales shown in the admin UI selector. You can do this by providing a `filterAvailableLocales` function in your Payload Config. This is called on the server side and is passed the array of locales. This means that you can determine what locales are visible in the localizer selection menu at the top of the admin panel. You could do this per user, or implement a function that scopes these to tenants and more. Here is an example using request headers in a multi-tenant application:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// ... rest of payload config
|
||||||
|
localization: {
|
||||||
|
defaultLocale: 'en',
|
||||||
|
locales: ['en', 'es'],
|
||||||
|
filterAvailableLocales: async ({ req, locales }) => {
|
||||||
|
if (getTenantFromCookie(req.headers, 'text')) {
|
||||||
|
const fullTenant = await req.payload.findByID({
|
||||||
|
id: getTenantFromCookie(req.headers, 'text') as string,
|
||||||
|
collection: 'tenants',
|
||||||
|
req,
|
||||||
|
})
|
||||||
|
if (fullTenant && fullTenant.supportedLocales?.length) {
|
||||||
|
return locales.filter((locale) => {
|
||||||
|
return fullTenant.supportedLocales?.includes(locale.code as 'en' | 'es')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locales
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Since the filtering happens at the root level of the application and its result is not calculated every time you navigate to a new page, you may want to call `router.refresh` in a custom component that watches when values that affect the result change. In the example above, you would want to do this when `supportedLocales` changes on the tenant document.
|
||||||
|
|
||||||
|
|
||||||
## Field Localization
|
## Field Localization
|
||||||
|
|
||||||
Payload Localization works on a **field** level—not a document level. In addition to configuring the base Payload Config to support Localization, you need to specify each field that you would like to localize.
|
Payload Localization works on a **field** level—not a document level. In addition to configuring the base Payload Config to support Localization, you need to specify each field that you would like to localize.
|
||||||
|
|||||||
@@ -414,9 +414,16 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
localization: {
|
localization: {
|
||||||
|
filterAvailableLocales: ({ locales }) => {
|
||||||
|
return locales.filter((locale) => locale.code !== 'xx')
|
||||||
|
},
|
||||||
defaultLocale,
|
defaultLocale,
|
||||||
fallback: true,
|
fallback: true,
|
||||||
locales: [
|
locales: [
|
||||||
|
{
|
||||||
|
code: 'xx',
|
||||||
|
label: 'FILTERED',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
code: defaultLocale,
|
code: defaultLocale,
|
||||||
label: 'English',
|
label: 'English',
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ describe('Localization', () => {
|
|||||||
// })
|
// })
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('localizer', async () => {
|
describe('localizer', () => {
|
||||||
test('should show localizer controls', async () => {
|
test('should show localizer controls', async () => {
|
||||||
await page.goto(url.create)
|
await page.goto(url.create)
|
||||||
await expect(page.locator('.localizer.app-header__localizer')).toBeVisible()
|
await expect(page.locator('.localizer.app-header__localizer')).toBeVisible()
|
||||||
@@ -105,6 +105,13 @@ describe('Localization', () => {
|
|||||||
await expect(page.locator('.localizer .popup.popup--active')).toBeVisible()
|
await expect(page.locator('.localizer .popup.popup--active')).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should filter locale with filterAvailableLocales', async () => {
|
||||||
|
await page.goto(url.create)
|
||||||
|
await expect(page.locator('.localizer.app-header__localizer')).toBeVisible()
|
||||||
|
await page.locator('.localizer >> button').first().click()
|
||||||
|
await expect(page.locator('.localizer .popup.popup--active')).not.toContainText('FILTERED')
|
||||||
|
})
|
||||||
|
|
||||||
test('should disable control for active locale', async () => {
|
test('should disable control for active locale', async () => {
|
||||||
await page.goto(url.create)
|
await page.goto(url.create)
|
||||||
|
|
||||||
@@ -472,7 +479,7 @@ describe('Localization', () => {
|
|||||||
await runCopy(page)
|
await runCopy(page)
|
||||||
await expect(page.locator('#field-title')).toHaveValue(title)
|
await expect(page.locator('#field-title')).toHaveValue(title)
|
||||||
|
|
||||||
const regexPattern = new RegExp(`locale=es`)
|
const regexPattern = /locale=es/
|
||||||
await expect(page).toHaveURL(regexPattern)
|
await expect(page).toHaveURL(regexPattern)
|
||||||
|
|
||||||
await openCopyToLocaleDrawer(page)
|
await openCopyToLocaleDrawer(page)
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export interface Config {
|
|||||||
'global-array': GlobalArraySelect<false> | GlobalArraySelect<true>;
|
'global-array': GlobalArraySelect<false> | GlobalArraySelect<true>;
|
||||||
'global-text': GlobalTextSelect<false> | GlobalTextSelect<true>;
|
'global-text': GlobalTextSelect<false> | GlobalTextSelect<true>;
|
||||||
};
|
};
|
||||||
locale: 'en' | 'es' | 'pt' | 'ar' | 'hu';
|
locale: 'xx' | 'en' | 'es' | 'pt' | 'ar' | 'hu';
|
||||||
user: User & {
|
user: User & {
|
||||||
collection: 'users';
|
collection: 'users';
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user