@plone/volto 17.0.0-alpha.6 → 17.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/packages/volto-slate/package.json +1 -1
- package/src/actions/language/language.js +8 -8
- package/src/components/manage/Add/Add.jsx +2 -2
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
- package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
- package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
- package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
- package/src/components/manage/Toolbar/Types.jsx +2 -2
- package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
- package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +7 -2
- package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
- package/src/components/theme/Footer/Footer.jsx +2 -13
- package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
- package/src/components/theme/Logo/Logo.jsx +2 -1
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
- package/src/components/theme/Navigation/NavItem.jsx +4 -2
- package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
- package/src/components/theme/View/EventDatesInfo.jsx +2 -1
- package/src/components/theme/Widgets/DateWidget.jsx +2 -1
- package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
- package/src/helpers/Utils/Utils.js +21 -9
- package/src/helpers/Utils/Utils.test.js +4 -4
- package/src/helpers/index.js +5 -2
- package/src/middleware/api.js +7 -3
- package/src/server.jsx +28 -23
- package/.changelog.draft +0 -33
- package/.editorconfig +0 -36
- package/.storybook/main.js +0 -127
- package/.storybook/manager.js +0 -15
- package/.storybook/preview.js +0 -21
- package/.storybook/static/previewImage.svg +0 -48
- package/.vale.ini +0 -10
- package/.yarnrc.yml +0 -5
- package/jsdoc.json +0 -16
- package/netlify.toml +0 -5
- package/pyvenv.cfg +0 -3
- package/share/man/man1/ttx.1 +0 -225
- package/styles/Vocab/Base/accept.txt +0 -0
- package/styles/Vocab/Base/reject.txt +0 -0
- package/styles/Vocab/Plone/accept.txt +0 -10
- package/styles/Vocab/Plone/reject.txt +0 -5
- package/towncrier.toml +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 17.0.0-alpha.7 (2023-05-11)
|
|
12
|
+
|
|
13
|
+
### Bugfix
|
|
14
|
+
|
|
15
|
+
- Fix language negotiation for language codes that include a region (e.g. `pt-br`). @davisagli [#4644](https://github.com/plone/volto/issues/4644)
|
|
16
|
+
|
|
17
|
+
|
|
11
18
|
## 17.0.0-alpha.6 (2023-05-11)
|
|
12
19
|
|
|
13
20
|
### Feature
|
package/package.json
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { updateIntl } from 'react-intl-redux';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
toGettextLang,
|
|
4
|
+
toReactIntlLang,
|
|
5
|
+
getCookieOptions,
|
|
6
|
+
} from '@plone/volto/helpers';
|
|
3
7
|
import Cookies from 'universal-cookie';
|
|
4
8
|
|
|
5
9
|
export function changeLanguageCookies(language, req) {
|
|
@@ -11,15 +15,11 @@ export function changeLanguageCookies(language, req) {
|
|
|
11
15
|
});
|
|
12
16
|
|
|
13
17
|
if (!req) {
|
|
14
|
-
cookies.set(
|
|
15
|
-
'I18N_LANGUAGE',
|
|
16
|
-
normalizeLanguageName(language) || '',
|
|
17
|
-
cookieOptions,
|
|
18
|
-
);
|
|
18
|
+
cookies.set('I18N_LANGUAGE', toGettextLang(language) || '', cookieOptions);
|
|
19
19
|
} else {
|
|
20
20
|
req.universalCookies.set(
|
|
21
21
|
'I18N_LANGUAGE',
|
|
22
|
-
|
|
22
|
+
toGettextLang(language) || '',
|
|
23
23
|
cookieOptions,
|
|
24
24
|
);
|
|
25
25
|
}
|
|
@@ -36,7 +36,7 @@ export function changeLanguage(language, locale, req) {
|
|
|
36
36
|
changeLanguageCookies(language, req);
|
|
37
37
|
|
|
38
38
|
return updateIntl({
|
|
39
|
-
locale: language,
|
|
39
|
+
locale: toReactIntlLang(language),
|
|
40
40
|
messages: locale,
|
|
41
41
|
});
|
|
42
42
|
}
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
getBlocksLayoutFieldname,
|
|
34
34
|
getLanguageIndependentFields,
|
|
35
35
|
langmap,
|
|
36
|
-
|
|
36
|
+
toGettextLang,
|
|
37
37
|
} from '@plone/volto/helpers';
|
|
38
38
|
|
|
39
39
|
import { preloadLazyLibs } from '@plone/volto/helpers/Loadable';
|
|
@@ -219,7 +219,7 @@ class Add extends Component {
|
|
|
219
219
|
onCancel() {
|
|
220
220
|
if (this.props.location?.state?.translationOf) {
|
|
221
221
|
const language = this.props.location.state.languageFrom;
|
|
222
|
-
const langFileName =
|
|
222
|
+
const langFileName = toGettextLang(language);
|
|
223
223
|
import('@root/../locales/' + langFileName + '.json').then((locale) => {
|
|
224
224
|
this.props.changeLanguage(language, locale.default);
|
|
225
225
|
});
|
|
@@ -4,6 +4,7 @@ import { defineMessages, injectIntl } from 'react-intl';
|
|
|
4
4
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
5
5
|
import { compose } from 'redux';
|
|
6
6
|
import { Icon } from '@plone/volto/components';
|
|
7
|
+
import { toBackendLang } from '@plone/volto/helpers/Utils/Utils';
|
|
7
8
|
import { connect } from 'react-redux';
|
|
8
9
|
|
|
9
10
|
import leftKey from '@plone/volto/icons/left-key.svg';
|
|
@@ -82,7 +83,9 @@ const DateRangeFacet = (props) => {
|
|
|
82
83
|
noBorder
|
|
83
84
|
showClearDates
|
|
84
85
|
customCloseIcon={<CloseIcon />}
|
|
85
|
-
displayFormat={moment
|
|
86
|
+
displayFormat={moment
|
|
87
|
+
.localeData(toBackendLang(lang))
|
|
88
|
+
.longDateFormat('L')}
|
|
86
89
|
focusedInput={focused}
|
|
87
90
|
onFocusChange={(focusedInput) => setFocused(focusedInput)}
|
|
88
91
|
onDatesChange={({ startDate, endDate }) => {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getTranslationLocator,
|
|
7
7
|
getContent,
|
|
8
8
|
} from '@plone/volto/actions';
|
|
9
|
-
import { flattenToAppURL,
|
|
9
|
+
import { flattenToAppURL, toGettextLang } from '@plone/volto/helpers';
|
|
10
10
|
import config from '@plone/volto/registry';
|
|
11
11
|
|
|
12
12
|
const CreateTranslation = (props) => {
|
|
@@ -33,7 +33,7 @@ const CreateTranslation = (props) => {
|
|
|
33
33
|
return () => {
|
|
34
34
|
// We change the interface language
|
|
35
35
|
if (config.settings.supportedLanguages.includes(language)) {
|
|
36
|
-
const langFileName =
|
|
36
|
+
const langFileName = toGettextLang(language);
|
|
37
37
|
import('@root/../locales/' + langFileName + '.json').then((locale) => {
|
|
38
38
|
dispatch(changeLanguage(language, locale.default));
|
|
39
39
|
});
|
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
Api,
|
|
16
16
|
flattenToAppURL,
|
|
17
17
|
langmap,
|
|
18
|
-
|
|
18
|
+
toGettextLang,
|
|
19
|
+
toReactIntlLang,
|
|
19
20
|
} from '@plone/volto/helpers';
|
|
20
21
|
import { createBrowserHistory } from 'history';
|
|
21
22
|
const messages = defineMessages({
|
|
@@ -55,9 +56,9 @@ const TranslationObject = ({
|
|
|
55
56
|
setLoadingLocale(true);
|
|
56
57
|
let lang =
|
|
57
58
|
config.settings.supportedLanguages[Object.keys(locales).length];
|
|
58
|
-
const langFileName =
|
|
59
|
+
const langFileName = toGettextLang(lang);
|
|
59
60
|
import('@root/../locales/' + langFileName + '.json').then((locale) => {
|
|
60
|
-
setLocales({ ...locales, [lang]: locale.default });
|
|
61
|
+
setLocales({ ...locales, [toReactIntlLang(lang)]: locale.default });
|
|
61
62
|
setLoadingLocale(false);
|
|
62
63
|
});
|
|
63
64
|
}
|
|
@@ -15,7 +15,7 @@ import { toast } from 'react-toastify';
|
|
|
15
15
|
import { Form, Toast } from '@plone/volto/components';
|
|
16
16
|
import languages from '@plone/volto/constants/Languages';
|
|
17
17
|
import { changeLanguage } from '@plone/volto/actions';
|
|
18
|
-
import {
|
|
18
|
+
import { toGettextLang } from '@plone/volto/helpers';
|
|
19
19
|
import config from '@plone/volto/registry';
|
|
20
20
|
|
|
21
21
|
const messages = defineMessages({
|
|
@@ -86,7 +86,7 @@ class PersonalPreferences extends Component {
|
|
|
86
86
|
onSubmit(data) {
|
|
87
87
|
let language = data.language || 'en';
|
|
88
88
|
if (config.settings.supportedLanguages.includes(language)) {
|
|
89
|
-
const langFileName =
|
|
89
|
+
const langFileName = toGettextLang(language);
|
|
90
90
|
import('@root/../locales/' + langFileName + '.json').then((locale) => {
|
|
91
91
|
this.props.changeLanguage(language, locale.default);
|
|
92
92
|
});
|
|
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { filter, find, isEmpty, map } from 'lodash';
|
|
6
6
|
import { FormattedMessage } from 'react-intl';
|
|
7
|
-
import { flattenToAppURL, langmap } from '@plone/volto/helpers';
|
|
7
|
+
import { flattenToAppURL, langmap, toBackendLang } from '@plone/volto/helpers';
|
|
8
8
|
import config from '@plone/volto/registry';
|
|
9
9
|
|
|
10
10
|
const Types = ({ types, pathname, content, currentLanguage }) => {
|
|
@@ -59,7 +59,7 @@ const Types = ({ types, pathname, content, currentLanguage }) => {
|
|
|
59
59
|
find(content['@components'].translations.items, {
|
|
60
60
|
language: lang,
|
|
61
61
|
}),
|
|
62
|
-
) && currentLanguage !== lang,
|
|
62
|
+
) && toBackendLang(currentLanguage) !== lang,
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
return (
|
|
@@ -10,7 +10,7 @@ import { connect } from 'react-redux';
|
|
|
10
10
|
import loadable from '@loadable/component';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { Icon, FormFieldWrapper } from '@plone/volto/components';
|
|
13
|
-
import { parseDateTime } from '@plone/volto/helpers';
|
|
13
|
+
import { parseDateTime, toBackendLang } from '@plone/volto/helpers';
|
|
14
14
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
15
15
|
|
|
16
16
|
import leftKey from '@plone/volto/icons/left-key.svg';
|
|
@@ -101,7 +101,7 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
101
101
|
// if passed value matches the construction time, we guess it's a default
|
|
102
102
|
isDefault:
|
|
103
103
|
parseDateTime(
|
|
104
|
-
this.props.lang,
|
|
104
|
+
toBackendLang(this.props.lang),
|
|
105
105
|
this.props.value,
|
|
106
106
|
undefined,
|
|
107
107
|
this.moment,
|
|
@@ -111,7 +111,7 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
111
111
|
|
|
112
112
|
getInternalValue() {
|
|
113
113
|
return parseDateTime(
|
|
114
|
-
this.props.lang,
|
|
114
|
+
toBackendLang(this.props.lang),
|
|
115
115
|
this.props.value,
|
|
116
116
|
undefined,
|
|
117
117
|
this.moment,
|
|
@@ -211,7 +211,9 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
211
211
|
{...(noPastDates ? {} : { isOutsideRange: () => false })}
|
|
212
212
|
onFocusChange={this.onFocusChange}
|
|
213
213
|
noBorder
|
|
214
|
-
displayFormat={moment
|
|
214
|
+
displayFormat={moment
|
|
215
|
+
.localeData(toBackendLang(lang))
|
|
216
|
+
.longDateFormat('L')}
|
|
215
217
|
navPrev={<PrevIcon />}
|
|
216
218
|
navNext={<NextIcon />}
|
|
217
219
|
id={`${id}-date`}
|
|
@@ -233,7 +235,9 @@ export class DatetimeWidgetComponent extends Component {
|
|
|
233
235
|
showSecond={false}
|
|
234
236
|
use12Hours={lang === 'en'}
|
|
235
237
|
id={`${id}-time`}
|
|
236
|
-
format={moment
|
|
238
|
+
format={moment
|
|
239
|
+
.localeData(toBackendLang(lang))
|
|
240
|
+
.longDateFormat('LT')}
|
|
237
241
|
placeholder={intl.formatMessage(messages.time)}
|
|
238
242
|
focusOnOpen
|
|
239
243
|
placement="bottomRight"
|
|
@@ -7,6 +7,7 @@ import React from 'react';
|
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { Form, Grid, Button } from 'semantic-ui-react';
|
|
9
9
|
import { Days } from './Utils';
|
|
10
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
10
11
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
11
12
|
import { useSelector } from 'react-redux';
|
|
12
13
|
|
|
@@ -18,7 +19,7 @@ import { useSelector } from 'react-redux';
|
|
|
18
19
|
const ByDayField = ({ label, value, onChange, moment: momentlib }) => {
|
|
19
20
|
const lang = useSelector((state) => state.intl.locale);
|
|
20
21
|
const moment = momentlib.default;
|
|
21
|
-
moment.locale(lang);
|
|
22
|
+
moment.locale(toBackendLang(lang));
|
|
22
23
|
|
|
23
24
|
const toggleWeekDay = (dayName) => {
|
|
24
25
|
var day = Days[dayName];
|
|
@@ -8,6 +8,7 @@ import PropTypes from 'prop-types';
|
|
|
8
8
|
import { map } from 'lodash';
|
|
9
9
|
import { Form } from 'semantic-ui-react';
|
|
10
10
|
import SelectInput from './SelectInput';
|
|
11
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
11
12
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
12
13
|
import { useSelector } from 'react-redux';
|
|
13
14
|
|
|
@@ -25,7 +26,7 @@ const MonthOfTheYearField = ({
|
|
|
25
26
|
}) => {
|
|
26
27
|
const moment = momentlib.default;
|
|
27
28
|
const lang = useSelector((state) => state.intl.locale);
|
|
28
|
-
moment.locale(lang);
|
|
29
|
+
moment.locale(toBackendLang(lang));
|
|
29
30
|
const monthList = [
|
|
30
31
|
...map(moment.months(), (m, i) => ({
|
|
31
32
|
value: i + 1,
|
|
@@ -11,6 +11,7 @@ import { List, Button, Header, Label } from 'semantic-ui-react';
|
|
|
11
11
|
import { Icon } from '@plone/volto/components';
|
|
12
12
|
import addSVG from '@plone/volto/icons/circle-plus.svg';
|
|
13
13
|
import trashSVG from '@plone/volto/icons/delete.svg';
|
|
14
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
14
15
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
15
16
|
|
|
16
17
|
import { useSelector } from 'react-redux';
|
|
@@ -68,7 +69,7 @@ const Occurences_ = ({
|
|
|
68
69
|
}) => {
|
|
69
70
|
const moment = momentlib.default;
|
|
70
71
|
const lang = useSelector((state) => state.intl.locale);
|
|
71
|
-
moment.locale(lang);
|
|
72
|
+
moment.locale(toBackendLang(lang));
|
|
72
73
|
let all = [];
|
|
73
74
|
const isExcluded = (date) => {
|
|
74
75
|
var dateISO = toISOString(date);
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from 'semantic-ui-react';
|
|
24
24
|
|
|
25
25
|
import { SelectWidget, Icon, DatetimeWidget } from '@plone/volto/components';
|
|
26
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
26
27
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
27
28
|
|
|
28
29
|
import saveSVG from '@plone/volto/icons/save.svg';
|
|
@@ -183,7 +184,7 @@ class RecurrenceWidget extends Component {
|
|
|
183
184
|
const { RRuleSet, rrulestr } = props.rrule;
|
|
184
185
|
|
|
185
186
|
this.moment = this.props.moment.default;
|
|
186
|
-
this.moment.locale(this.props.lang);
|
|
187
|
+
this.moment.locale(toBackendLang(this.props.lang));
|
|
187
188
|
|
|
188
189
|
let rruleSet = this.props.value
|
|
189
190
|
? rrulestr(props.value, {
|
|
@@ -201,7 +202,11 @@ class RecurrenceWidget extends Component {
|
|
|
201
202
|
open: false,
|
|
202
203
|
rruleSet: rruleSet,
|
|
203
204
|
formValues: this.getFormValues(rruleSet),
|
|
204
|
-
RRULE_LANGUAGE: rrulei18n(
|
|
205
|
+
RRULE_LANGUAGE: rrulei18n(
|
|
206
|
+
this.props.intl,
|
|
207
|
+
this.moment,
|
|
208
|
+
toBackendLang(this.props.lang),
|
|
209
|
+
),
|
|
205
210
|
};
|
|
206
211
|
}
|
|
207
212
|
|
|
@@ -8,6 +8,7 @@ import { map } from 'lodash';
|
|
|
8
8
|
import { Days } from './Utils';
|
|
9
9
|
import SelectInput from './SelectInput';
|
|
10
10
|
import { Form } from 'semantic-ui-react';
|
|
11
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
11
12
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
12
13
|
import { useSelector } from 'react-redux';
|
|
13
14
|
|
|
@@ -22,7 +23,7 @@ const WeekdayOfTheMonthField = (props) => {
|
|
|
22
23
|
const lang = useSelector((state) => state.intl.locale);
|
|
23
24
|
|
|
24
25
|
const moment = momentlib.default;
|
|
25
|
-
moment.locale(lang);
|
|
26
|
+
moment.locale(toBackendLang(lang));
|
|
26
27
|
|
|
27
28
|
const weekdayOfTheMonthList = [
|
|
28
29
|
...map(Object.keys(Days), (d) => ({
|
|
@@ -9,7 +9,6 @@ import { map } from 'lodash';
|
|
|
9
9
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
10
10
|
import { useSelector, shallowEqual } from 'react-redux';
|
|
11
11
|
import { UniversalLink } from '@plone/volto/components';
|
|
12
|
-
import config from '@plone/volto/registry';
|
|
13
12
|
import { flattenToAppURL, addAppURL } from '@plone/volto/helpers';
|
|
14
13
|
|
|
15
14
|
const messages = defineMessages({
|
|
@@ -26,10 +25,8 @@ const messages = defineMessages({
|
|
|
26
25
|
* @returns {string} Markup of the component
|
|
27
26
|
*/
|
|
28
27
|
const Footer = ({ intl }) => {
|
|
29
|
-
const {
|
|
30
|
-
const { lang, siteActions = [] } = useSelector(
|
|
28
|
+
const { siteActions = [] } = useSelector(
|
|
31
29
|
(state) => ({
|
|
32
|
-
lang: state.intl.locale,
|
|
33
30
|
siteActions: state.actions?.actions?.site_actions,
|
|
34
31
|
}),
|
|
35
32
|
shallowEqual,
|
|
@@ -97,15 +94,7 @@ const Footer = ({ intl }) => {
|
|
|
97
94
|
<UniversalLink
|
|
98
95
|
className="item"
|
|
99
96
|
href={
|
|
100
|
-
|
|
101
|
-
? `/${lang}/${
|
|
102
|
-
item.url
|
|
103
|
-
? flattenToAppURL(item.url)
|
|
104
|
-
: addAppURL(item.id)
|
|
105
|
-
}`
|
|
106
|
-
: item.url
|
|
107
|
-
? flattenToAppURL(item.url)
|
|
108
|
-
: addAppURL(item.id)
|
|
97
|
+
item.url ? flattenToAppURL(item.url) : addAppURL(item.id)
|
|
109
98
|
}
|
|
110
99
|
>
|
|
111
100
|
{item?.title}
|
|
@@ -11,7 +11,12 @@ import { useSelector } from 'react-redux';
|
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { find, map } from 'lodash';
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Helmet,
|
|
16
|
+
langmap,
|
|
17
|
+
flattenToAppURL,
|
|
18
|
+
toReactIntlLang,
|
|
19
|
+
} from '@plone/volto/helpers';
|
|
15
20
|
|
|
16
21
|
import config from '@plone/volto/registry';
|
|
17
22
|
|
|
@@ -42,7 +47,7 @@ const LanguageSelector = (props) => {
|
|
|
42
47
|
aria-label={`${intl.formatMessage(
|
|
43
48
|
messages.switchLanguageTo,
|
|
44
49
|
)} ${langmap[lang].nativeName.toLowerCase()}`}
|
|
45
|
-
className={cx({ selected: lang === currentLang })}
|
|
50
|
+
className={cx({ selected: toReactIntlLang(lang) === currentLang })}
|
|
46
51
|
to={translation ? flattenToAppURL(translation['@id']) : `/${lang}`}
|
|
47
52
|
title={langmap[lang].nativeName}
|
|
48
53
|
onClick={() => {
|
|
@@ -57,7 +62,7 @@ const LanguageSelector = (props) => {
|
|
|
57
62
|
</div>
|
|
58
63
|
) : (
|
|
59
64
|
<Helmet>
|
|
60
|
-
<html lang={settings.defaultLanguage} />
|
|
65
|
+
<html lang={toReactIntlLang(settings.defaultLanguage)} />
|
|
61
66
|
</Helmet>
|
|
62
67
|
);
|
|
63
68
|
};
|
|
@@ -8,6 +8,7 @@ import { Image } from 'semantic-ui-react';
|
|
|
8
8
|
import { useSelector } from 'react-redux';
|
|
9
9
|
import config from '@plone/volto/registry';
|
|
10
10
|
import { UniversalLink } from '@plone/volto/components';
|
|
11
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
11
12
|
import LogoImage from '@plone/volto/components/theme/Logo/Logo.svg';
|
|
12
13
|
|
|
13
14
|
const messages = defineMessages({
|
|
@@ -34,7 +35,7 @@ const Logo = () => {
|
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
37
|
<UniversalLink
|
|
37
|
-
href={settings.isMultilingual ? `/${lang}` : '/'}
|
|
38
|
+
href={settings.isMultilingual ? `/${toBackendLang(lang)}` : '/'}
|
|
38
39
|
title={intl.formatMessage(messages.site)}
|
|
39
40
|
>
|
|
40
41
|
<Image
|
|
@@ -4,7 +4,7 @@ import { useDispatch } from 'react-redux';
|
|
|
4
4
|
import { useCookies } from 'react-cookie';
|
|
5
5
|
import config from '@plone/volto/registry';
|
|
6
6
|
import { changeLanguage } from '@plone/volto/actions';
|
|
7
|
-
import {
|
|
7
|
+
import { toGettextLang } from '@plone/volto/helpers';
|
|
8
8
|
|
|
9
9
|
const MultilingualRedirector = (props) => {
|
|
10
10
|
const { settings } = config;
|
|
@@ -23,7 +23,7 @@ const MultilingualRedirector = (props) => {
|
|
|
23
23
|
// const detectedLang = (navigator.language || navigator.userLanguage).substring(0, 2);
|
|
24
24
|
let mounted = true;
|
|
25
25
|
if (settings.isMultilingual && pathname === '/') {
|
|
26
|
-
const langFileName =
|
|
26
|
+
const langFileName = toGettextLang(redirectToLanguage);
|
|
27
27
|
import('@root/../locales/' + langFileName + '.json').then((locale) => {
|
|
28
28
|
if (mounted) {
|
|
29
29
|
dispatch(changeLanguage(redirectToLanguage, locale.default));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { NavLink } from 'react-router-dom';
|
|
3
|
-
import { isInternalURL } from '@plone/volto/helpers';
|
|
3
|
+
import { isInternalURL, toBackendLang } from '@plone/volto/helpers';
|
|
4
4
|
import config from '@plone/volto/registry';
|
|
5
5
|
|
|
6
6
|
const NavItem = ({ item, lang }) => {
|
|
@@ -15,7 +15,9 @@ const NavItem = ({ item, lang }) => {
|
|
|
15
15
|
className="item"
|
|
16
16
|
activeClassName="active"
|
|
17
17
|
exact={
|
|
18
|
-
settings.isMultilingual
|
|
18
|
+
settings.isMultilingual
|
|
19
|
+
? item.url === `/${toBackendLang(lang)}`
|
|
20
|
+
: item.url === ''
|
|
19
21
|
}
|
|
20
22
|
>
|
|
21
23
|
{item.title}
|
|
@@ -10,7 +10,7 @@ import { connect } from 'react-redux';
|
|
|
10
10
|
import { asyncConnect } from '@plone/volto/helpers';
|
|
11
11
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
12
12
|
import { Container } from 'semantic-ui-react';
|
|
13
|
-
import { Helmet } from '@plone/volto/helpers';
|
|
13
|
+
import { Helmet, toBackendLang } from '@plone/volto/helpers';
|
|
14
14
|
import { Link } from 'react-router-dom';
|
|
15
15
|
import config from '@plone/volto/registry';
|
|
16
16
|
|
|
@@ -40,7 +40,7 @@ class Sitemap extends Component {
|
|
|
40
40
|
componentDidMount() {
|
|
41
41
|
const { settings } = config;
|
|
42
42
|
if (settings.isMultilingual) {
|
|
43
|
-
this.props.getNavigation(`${this.props.lang}`, 4);
|
|
43
|
+
this.props.getNavigation(`${toBackendLang(this.props.lang)}`, 4);
|
|
44
44
|
} else {
|
|
45
45
|
this.props.getNavigation('', 4);
|
|
46
46
|
}
|
|
@@ -108,7 +108,9 @@ export default compose(
|
|
|
108
108
|
const { settings } = config;
|
|
109
109
|
const lang = getState().intl.locale;
|
|
110
110
|
if (settings.isMultilingual) {
|
|
111
|
-
return
|
|
111
|
+
return (
|
|
112
|
+
__SERVER__ && dispatch(getNavigation(`${toBackendLang(lang)}`, 4))
|
|
113
|
+
);
|
|
112
114
|
} else {
|
|
113
115
|
return __SERVER__ && dispatch(getNavigation('', 4));
|
|
114
116
|
}
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { List } from 'semantic-ui-react';
|
|
4
4
|
import cx from 'classnames';
|
|
5
5
|
|
|
6
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
6
7
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
7
8
|
import { useSelector } from 'react-redux';
|
|
8
9
|
|
|
@@ -28,7 +29,7 @@ const When_ = ({ start, end, whole_day, open_end, moment: momentlib }) => {
|
|
|
28
29
|
const lang = useSelector((state) => state.intl.locale);
|
|
29
30
|
|
|
30
31
|
const moment = momentlib.default;
|
|
31
|
-
moment.locale(lang);
|
|
32
|
+
moment.locale(toBackendLang(lang));
|
|
32
33
|
|
|
33
34
|
const datesInfo = datesForDisplay(start, end, moment);
|
|
34
35
|
if (!datesInfo) {
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
import { useSelector } from 'react-redux';
|
|
5
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
5
6
|
|
|
6
7
|
const DateWidget = ({ value, children, className, format = 'll' }) => {
|
|
7
8
|
const lang = useSelector((state) => state.intl.locale);
|
|
8
|
-
moment.locale(lang);
|
|
9
|
+
moment.locale(toBackendLang(lang));
|
|
9
10
|
return value ? (
|
|
10
11
|
<span className={cx(className, 'date', 'widget')}>
|
|
11
12
|
{children
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
import { useSelector } from 'react-redux';
|
|
5
|
+
import { toBackendLang } from '@plone/volto/helpers';
|
|
5
6
|
|
|
6
7
|
const DatetimeWidget = ({ value, children, className, format = 'lll' }) => {
|
|
7
8
|
const lang = useSelector((state) => state.intl.locale);
|
|
8
|
-
moment.locale(lang);
|
|
9
|
+
moment.locale(toBackendLang(lang));
|
|
9
10
|
return value ? (
|
|
10
11
|
<span className={cx(className, 'datetime', 'widget')}>
|
|
11
12
|
{children
|
|
@@ -174,13 +174,13 @@ export const parseDateTime = (locale, value, format, moment) => {
|
|
|
174
174
|
};
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
|
-
* Converts a language code to the format `lang_region`
|
|
177
|
+
* Converts a language code like pt-br to the format `pt_BR` (`lang_region`)
|
|
178
178
|
* Useful for passing from Plone's i18n lang names to Xnix locale names
|
|
179
|
-
* eg. LC_MESSAGES/lang_region.po filenames
|
|
179
|
+
* eg. LC_MESSAGES/lang_region.po filenames. Also used in the I18N_LANGUAGE cookie.
|
|
180
180
|
* @param {string} language Language to be converted
|
|
181
181
|
* @returns {string} Language converted
|
|
182
182
|
*/
|
|
183
|
-
export const
|
|
183
|
+
export const toGettextLang = (language) => {
|
|
184
184
|
if (language.includes('-')) {
|
|
185
185
|
let normalizedLang = language.split('-');
|
|
186
186
|
normalizedLang = `${normalizedLang[0]}_${normalizedLang[1].toUpperCase()}`;
|
|
@@ -189,23 +189,35 @@ export const normalizeLanguageName = (language) => {
|
|
|
189
189
|
|
|
190
190
|
return language;
|
|
191
191
|
};
|
|
192
|
+
export const normalizeLanguageName = toGettextLang;
|
|
192
193
|
|
|
193
194
|
/**
|
|
194
|
-
* Converts a language code to the format `
|
|
195
|
-
* `react-intl` only supports this syntax
|
|
196
|
-
*
|
|
195
|
+
* Converts a language code like pt-br or pt_BR to the format `pt-BR`.
|
|
196
|
+
* `react-intl` only supports this syntax. We also use it for the locales
|
|
197
|
+
* in the volto Redux store.
|
|
197
198
|
* @param {string} language Language to be converted
|
|
198
199
|
* @returns {string} Language converted
|
|
199
200
|
*/
|
|
200
|
-
export const
|
|
201
|
-
if (language.includes('_')) {
|
|
202
|
-
let langCode = language.split(
|
|
201
|
+
export const toReactIntlLang = (language) => {
|
|
202
|
+
if (language.includes('_') || language.includes('-')) {
|
|
203
|
+
let langCode = language.split(/[-_]/);
|
|
203
204
|
langCode = `${langCode[0]}-${langCode[1].toUpperCase()}`;
|
|
204
205
|
return langCode;
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
return language;
|
|
208
209
|
};
|
|
210
|
+
export const toLangUnderscoreRegion = toReactIntlLang; // old name for backwards-compat
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Converts a language code like pt_BR or pt-BR to the format `pt-br`.
|
|
214
|
+
* This format is used on the backend and in volto config settings.
|
|
215
|
+
* @param {string} language Language to be converted
|
|
216
|
+
* @returns {string} Language converted
|
|
217
|
+
*/
|
|
218
|
+
export const toBackendLang = (language) => {
|
|
219
|
+
return toReactIntlLang(language).toLowerCase();
|
|
220
|
+
};
|
|
209
221
|
|
|
210
222
|
/**
|
|
211
223
|
* Lookup if a given expander is set in apiExpanders for the given path and action type
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getColor,
|
|
7
7
|
getInitials,
|
|
8
8
|
hasApiExpander,
|
|
9
|
-
|
|
9
|
+
toGettextLang,
|
|
10
10
|
parseDateTime,
|
|
11
11
|
removeFromArray,
|
|
12
12
|
reorderArray,
|
|
@@ -284,12 +284,12 @@ describe('Utils tests', () => {
|
|
|
284
284
|
});
|
|
285
285
|
});
|
|
286
286
|
|
|
287
|
-
describe('
|
|
287
|
+
describe('toGettextLang', () => {
|
|
288
288
|
it('Normalizes an extended language (pt_BR)', () => {
|
|
289
|
-
expect(
|
|
289
|
+
expect(toGettextLang('pt-br')).toStrictEqual('pt_BR');
|
|
290
290
|
});
|
|
291
291
|
it('Normalizes a simple language (ca)', () => {
|
|
292
|
-
expect(
|
|
292
|
+
expect(toGettextLang('ca')).toStrictEqual('ca');
|
|
293
293
|
});
|
|
294
294
|
});
|
|
295
295
|
|
package/src/helpers/index.js
CHANGED
|
@@ -80,8 +80,11 @@ export {
|
|
|
80
80
|
applyConfig,
|
|
81
81
|
withServerErrorCode,
|
|
82
82
|
parseDateTime,
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
toGettextLang,
|
|
84
|
+
normalizeLanguageName, // old name for toGettextLang
|
|
85
|
+
toReactIntlLang,
|
|
86
|
+
toLangUnderscoreRegion, // old name for toReactIntlLang
|
|
87
|
+
toBackendLang,
|
|
85
88
|
hasApiExpander,
|
|
86
89
|
replaceItemOfArray,
|
|
87
90
|
cloneDeepSchema,
|