mirror of
https://github.com/strapi/strapi.git
synced 2025-09-24 07:50:33 +00:00
Implement i18n
This commit is contained in:
parent
ed4586ee7a
commit
6de2503b9c
@ -18,6 +18,7 @@ const store = configureStore(initialState, browserHistory);
|
|||||||
// Set up the router, wrapping all Routes in the App component
|
// Set up the router, wrapping all Routes in the App component
|
||||||
import App from 'containers/App';
|
import App from 'containers/App';
|
||||||
import createRoutes from './routes';
|
import createRoutes from './routes';
|
||||||
|
import { translationMessages } from './i18n';
|
||||||
|
|
||||||
// Plugin identifier based on the package.json `name` value
|
// Plugin identifier based on the package.json `name` value
|
||||||
const pluginId = require('../package.json').name.replace(/^strapi-/i, '');
|
const pluginId = require('../package.json').name.replace(/^strapi-/i, '');
|
||||||
@ -33,6 +34,22 @@ if (window.Strapi) {
|
|||||||
},
|
},
|
||||||
mainComponent: App,
|
mainComponent: App,
|
||||||
routes: createRoutes(store),
|
routes: createRoutes(store),
|
||||||
|
translationMessages,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hot reloadable translation json files
|
||||||
|
if (module.hot) {
|
||||||
|
// modules.hot.accept does not accept dynamic dependencies,
|
||||||
|
// have to be constants at compile-time
|
||||||
|
module.hot.accept('./i18n', () => {
|
||||||
|
if (window.Strapi) {
|
||||||
|
System.import('./i18n')
|
||||||
|
.then(result => {
|
||||||
|
const translationMessagesUpdated = result.translationMessages;
|
||||||
|
window.Strapi.refresh(pluginId).translationMessages(translationMessagesUpdated);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,27 +11,21 @@ import styles from './styles.scss';
|
|||||||
|
|
||||||
class LeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
class LeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
links = [{
|
links = [{
|
||||||
label: 'General',
|
|
||||||
value: 'general',
|
value: 'general',
|
||||||
to: '',
|
to: '',
|
||||||
}, {
|
}, {
|
||||||
label: 'Languages',
|
|
||||||
value: 'languages',
|
value: 'languages',
|
||||||
to: 'languages',
|
to: 'languages',
|
||||||
}, {
|
}, {
|
||||||
label: 'Databases',
|
|
||||||
value: 'databases',
|
value: 'databases',
|
||||||
to: 'databases',
|
to: 'databases',
|
||||||
}, {
|
}, {
|
||||||
label: 'Security',
|
|
||||||
value: 'security',
|
value: 'security',
|
||||||
to: 'security',
|
to: 'security',
|
||||||
}, {
|
}, {
|
||||||
label: 'Server',
|
|
||||||
value: 'server',
|
value: 'server',
|
||||||
to: 'server',
|
to: 'server',
|
||||||
}, {
|
}, {
|
||||||
label: 'Advanced',
|
|
||||||
value: 'advanced',
|
value: 'advanced',
|
||||||
to: 'advanced',
|
to: 'advanced',
|
||||||
}];
|
}];
|
||||||
|
@ -6,14 +6,22 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
console.log('styles', styles);
|
|
||||||
class LeftMenuLink extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
class LeftMenuLink extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
|
const messageKey = `${this.props.link.value}SectionTitle`;
|
||||||
return (
|
return (
|
||||||
<li className={styles.leftMenuLink}>
|
<li className={styles.leftMenuLink}>
|
||||||
<Link className={styles.leftMenuLinkDestination} activeClassName={styles.leftMenuLinkDestinationActive} to={`/plugins/settings-manager/${this.props.link.to}`}>{this.props.link.label}
|
<Link
|
||||||
|
className={styles.leftMenuLinkDestination}
|
||||||
|
activeClassName={styles.leftMenuLinkDestinationActive}
|
||||||
|
to={`/plugins/settings-manager/${this.props.link.to}`}
|
||||||
|
>
|
||||||
|
<FormattedMessage {...appMessages[messageKey]} />
|
||||||
<i className={`ion ion-arrow-right-c ${styles.leftMenuLinkIcon}`}></i>
|
<i className={`ion ion-arrow-right-c ${styles.leftMenuLinkIcon}`}></i>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import messages from './messages';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ class PluginHeaderActions extends React.Component { // eslint-disable-line react
|
|||||||
className={`${styles.pluginHeaderActionsButton} btn btn-secondary`}
|
className={`${styles.pluginHeaderActionsButton} btn btn-secondary`}
|
||||||
onClick={this.props.onCancel}
|
onClick={this.props.onCancel}
|
||||||
>
|
>
|
||||||
Cancel
|
<FormattedMessage {...messages.cancelLabel} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
@ -25,7 +27,7 @@ class PluginHeaderActions extends React.Component { // eslint-disable-line react
|
|||||||
disabled={this.props.loading}
|
disabled={this.props.loading}
|
||||||
onClick={this.props.onFormSubmit}
|
onClick={this.props.onFormSubmit}
|
||||||
>
|
>
|
||||||
Save
|
<FormattedMessage {...messages.saveLabel} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
17
public/app/components/PluginHeaderActions/messages.js
Normal file
17
public/app/components/PluginHeaderActions/messages.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* PluginHeaderActions Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the PluginHeaderActions component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
cancelLabel: {
|
||||||
|
id: 'settings-manager.components.PluginHeaderActions.cancelLabel',
|
||||||
|
defaultMessage: 'Cancel',
|
||||||
|
},
|
||||||
|
saveLabel: {
|
||||||
|
id: 'settings-manager.components.PluginHeaderActions.saveLabel',
|
||||||
|
defaultMessage: 'Save',
|
||||||
|
},
|
||||||
|
});
|
@ -5,15 +5,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import messages from './messages';
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.pluginHeaderTitle}>
|
<div className={styles.pluginHeaderTitle}>
|
||||||
<h1 className={styles.pluginHeaderTitleName}>Settings Manager</h1>
|
<h1 className={styles.pluginHeaderTitleName}>
|
||||||
<p className={styles.pluginHeaderTitleDescription}>Easily update your settings</p>
|
<FormattedMessage {...messages.title} />
|
||||||
|
</h1>
|
||||||
|
<p className={styles.pluginHeaderTitleDescription}>
|
||||||
|
<FormattedMessage {...messages.description} />
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
17
public/app/components/PluginHeaderTitle/messages.js
Normal file
17
public/app/components/PluginHeaderTitle/messages.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* PluginHeaderTitle Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the PluginHeaderTitle component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
title: {
|
||||||
|
id: 'settings-manager.components.PluginHeaderTitle.title',
|
||||||
|
defaultMessage: 'Settings Manager',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
id: 'settings-manager.components.PluginHeaderTitle.description',
|
||||||
|
defaultMessage: 'Easily configure your settings',
|
||||||
|
},
|
||||||
|
});
|
@ -10,26 +10,44 @@ import PluginHeader from 'components/PluginHeader';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import RightContentTitle from 'components/RightContentTitle';
|
import RightContentTitle from 'components/RightContentTitle';
|
||||||
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
||||||
|
import { injectIntl, intlShape } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
export default class AdvancedPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class AdvancedPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.advancedPage}>
|
<div className={styles.advancedPage}>
|
||||||
<Helmet
|
<Helmet
|
||||||
title="Settings Manager - Advanced"
|
title="Settings Manager - Advanced"
|
||||||
meta={[
|
meta={[
|
||||||
{ name: 'description', content: 'Configure your Advanced settings.' },
|
{ name: 'description', content: formatMessage(messages.rightSectionDescription) },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader></PluginHeader>
|
<PluginHeader />
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="Advanced" description="Configure your advanced settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Coming soon" description=""></RightContentSectionTitle>
|
title={formatMessage(appMessages.advancedSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(appMessages.comingSoon)}
|
||||||
|
description=""
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AdvancedPage.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(AdvancedPage);
|
||||||
|
13
public/app/containers/AdvancedPage/messages.js
Normal file
13
public/app/containers/AdvancedPage/messages.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* LanguagesPage Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the LanguagesPage component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
rightSectionDescription: {
|
||||||
|
id: 'settings-manager.components.AdvancedPage.rightSectionDescription',
|
||||||
|
defaultMessage: 'Configure your advanced settings',
|
||||||
|
},
|
||||||
|
});
|
37
public/app/containers/App/messages.js
Normal file
37
public/app/containers/App/messages.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* App Messages
|
||||||
|
*
|
||||||
|
* This contains all the text use across the plugin.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
generalSectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.generalSectionTitle',
|
||||||
|
defaultMessage: 'General',
|
||||||
|
},
|
||||||
|
languagesSectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.languagesSectionTitle',
|
||||||
|
defaultMessage: 'Languages',
|
||||||
|
},
|
||||||
|
databasesSectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.databasesSectionTitle',
|
||||||
|
defaultMessage: 'Databases',
|
||||||
|
},
|
||||||
|
securitySectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.securitySectionTitle',
|
||||||
|
defaultMessage: 'Security',
|
||||||
|
},
|
||||||
|
serverSectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.serverSectionTitle',
|
||||||
|
defaultMessage: 'Server',
|
||||||
|
},
|
||||||
|
advancedSectionTitle: {
|
||||||
|
id: 'settings-manager.components.App.advancedSectionTitle',
|
||||||
|
defaultMessage: 'Advanced',
|
||||||
|
},
|
||||||
|
comingSoon: {
|
||||||
|
id: 'settings-manager.components.App.comingSoon',
|
||||||
|
defaultMessage: 'Coming soon',
|
||||||
|
},
|
||||||
|
});
|
@ -8,28 +8,45 @@ import PluginHeader from 'components/PluginHeader';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import RightContentTitle from 'components/RightContentTitle';
|
import RightContentTitle from 'components/RightContentTitle';
|
||||||
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
||||||
|
import { injectIntl, intlShape } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
export default class DatabasesPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class DatabasesPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.databasesPage}>
|
<div className={styles.databasesPage}>
|
||||||
<Helmet
|
<Helmet
|
||||||
title="Settings Manager - Databases"
|
title="Settings Manager - Databases"
|
||||||
meta={[
|
meta={[
|
||||||
{ name: 'description', content: 'Configure your Databases settings.' },
|
{ name: 'description', content: formatMessage(messages.rightSectionDescription) },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader></PluginHeader>
|
<PluginHeader />
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="Databases" description="Configure your databases settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Coming soon" description=""></RightContentSectionTitle>
|
title={formatMessage(appMessages.databasesSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(appMessages.comingSoon)}
|
||||||
|
description=""
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabasesPage.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(DatabasesPage);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* DatabasesPage Messages
|
* LanguagesPage Messages
|
||||||
*
|
*
|
||||||
* This contains all the text for the DatabasesPage component.
|
* This contains all the text for the LanguagesPage component.
|
||||||
*/
|
*/
|
||||||
import { defineMessages } from 'react-intl';
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
export default defineMessages({
|
export default defineMessages({
|
||||||
header: {
|
rightSectionDescription: {
|
||||||
id: 'app.components.DatabasesPage.header',
|
id: 'settings-manager.components.DatabasesPage.rightSectionDescription',
|
||||||
defaultMessage: 'This is the Databases page of the Settings Manager plugin!',
|
defaultMessage: 'Configure your databases settings',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -31,6 +31,9 @@ import {
|
|||||||
updateGeneralSettings,
|
updateGeneralSettings,
|
||||||
cancelGeneralSettings,
|
cancelGeneralSettings,
|
||||||
} from 'containers/HomePage/actions';
|
} from 'containers/HomePage/actions';
|
||||||
|
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
@ -41,21 +44,31 @@ export class HomePage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader {...this.props}></PluginHeader>
|
<PluginHeader {...this.props}></PluginHeader>
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="General" description="Configure your general settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Application" description="The general settings of your Strapi application."></RightContentSectionTitle>
|
title={formatMessage(appMessages.generalSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(messages.rightContentSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightContentSectionDescription)}
|
||||||
|
/>
|
||||||
<form onSubmit={this.props.onFormSubmit}>
|
<form onSubmit={this.props.onFormSubmit}>
|
||||||
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
||||||
<label htmlFor="applicationName" className="col-xs-7 col-form-label">Name</label>
|
<label htmlFor="applicationName" className="col-xs-7 col-form-label">
|
||||||
|
<FormattedMessage {...messages.nameLabel} />
|
||||||
|
</label>
|
||||||
<div className="col-xs-5">
|
<div className="col-xs-5">
|
||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="My Application"
|
placeholder={formatMessage(messages.namePlaceholder)}
|
||||||
id="applicationName"
|
id="applicationName"
|
||||||
value={this.props.name || ''}
|
value={this.props.name || ''}
|
||||||
onChange={this.props.onChangeName}
|
onChange={this.props.onChangeName}
|
||||||
@ -64,12 +77,14 @@ export class HomePage extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
||||||
<label htmlFor="applicationDescription" className="col-xs-7 col-form-label">Description</label>
|
<label htmlFor="applicationDescription" className="col-xs-7 col-form-label">
|
||||||
|
<FormattedMessage {...messages.descriptionLabel} />
|
||||||
|
</label>
|
||||||
<div className="col-xs-5">
|
<div className="col-xs-5">
|
||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="A Strapi application"
|
placeholder={formatMessage(messages.descriptionPlaceholder)}
|
||||||
id="applicationDescription"
|
id="applicationDescription"
|
||||||
value={this.props.description || ''}
|
value={this.props.description || ''}
|
||||||
onChange={this.props.onChangeDescription}
|
onChange={this.props.onChangeDescription}
|
||||||
@ -77,12 +92,14 @@ export class HomePage extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
<div className={`form-group row ${styles.homePageRightContentFormGroup}`}>
|
||||||
<label htmlFor="applicationVersion" className="col-xs-7 col-form-label">Version</label>
|
<label htmlFor="applicationVersion" className="col-xs-7 col-form-label">
|
||||||
|
<FormattedMessage {...messages.versionLabel} />
|
||||||
|
</label>
|
||||||
<div className="col-xs-5">
|
<div className="col-xs-5">
|
||||||
<input
|
<input
|
||||||
className="form-control"
|
className="form-control"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="0.0.1"
|
placeholder={formatMessage(messages.versionPlaceholder)}
|
||||||
id="applicationVersion"
|
id="applicationVersion"
|
||||||
value={this.props.version || ''}
|
value={this.props.version || ''}
|
||||||
onChange={this.props.onChangeVersion}
|
onChange={this.props.onChangeVersion}
|
||||||
@ -108,6 +125,7 @@ HomePage.propTypes = {
|
|||||||
React.PropTypes.object,
|
React.PropTypes.object,
|
||||||
React.PropTypes.bool,
|
React.PropTypes.bool,
|
||||||
]),
|
]),
|
||||||
|
intl: intlShape.isRequired,
|
||||||
loading: React.PropTypes.bool,
|
loading: React.PropTypes.bool,
|
||||||
name: React.PropTypes.oneOfType([
|
name: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.string,
|
React.PropTypes.string,
|
||||||
@ -123,7 +141,6 @@ HomePage.propTypes = {
|
|||||||
React.PropTypes.string,
|
React.PropTypes.string,
|
||||||
React.PropTypes.bool,
|
React.PropTypes.bool,
|
||||||
]),
|
]),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function mapDispatchToProps(dispatch) {
|
export function mapDispatchToProps(dispatch) {
|
||||||
@ -153,4 +170,4 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Wrap the component to inject dispatch and state into it
|
// Wrap the component to inject dispatch and state into it
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(HomePage);
|
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(HomePage));
|
||||||
|
49
public/app/containers/HomePage/messages.js
Normal file
49
public/app/containers/HomePage/messages.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* HomePage Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the HomePage component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
rightSectionDescription: {
|
||||||
|
id: 'settings-manager.components.HomePage.rightSectionDescription',
|
||||||
|
defaultMessage: 'Configure your general settings',
|
||||||
|
},
|
||||||
|
rightContentSectionTitle: {
|
||||||
|
id: 'settings-manager.components.HomePage.rightContentSectionTitle',
|
||||||
|
defaultMessage: 'Application',
|
||||||
|
},
|
||||||
|
rightContentSectionDescription: {
|
||||||
|
id: 'settings-manager.components.HomePage.rightContentSectionDescription',
|
||||||
|
defaultMessage: 'The general settings of your Strapi application.',
|
||||||
|
},
|
||||||
|
nameLabel: {
|
||||||
|
id: 'settings-manager.components.HomePage.nameLabel',
|
||||||
|
defaultMessage: 'Name',
|
||||||
|
},
|
||||||
|
namePlaceholder: {
|
||||||
|
id: 'settings-manager.components.HomePage.namePlaceholder',
|
||||||
|
defaultMessage: 'My Application',
|
||||||
|
},
|
||||||
|
descriptionLabel: {
|
||||||
|
id: 'settings-manager.components.HomePage.descriptionLabel',
|
||||||
|
defaultMessage: 'Description',
|
||||||
|
},
|
||||||
|
descriptionPlaceholder: {
|
||||||
|
id: 'settings-manager.components.HomePage.descriptionPlaceholder',
|
||||||
|
defaultMessage: 'A Strapi application',
|
||||||
|
},
|
||||||
|
versionLabel: {
|
||||||
|
id: 'settings-manager.components.HomePage.versionLabel',
|
||||||
|
defaultMessage: 'Version',
|
||||||
|
},
|
||||||
|
versionPlaceholder: {
|
||||||
|
id: 'settings-manager.components.HomePage.versionPlaceholder',
|
||||||
|
defaultMessage: '0.0.1',
|
||||||
|
},
|
||||||
|
submit: {
|
||||||
|
id: 'settings-manager.components.HomePage.submit',
|
||||||
|
defaultMessage: 'Submit',
|
||||||
|
},
|
||||||
|
});
|
@ -8,27 +8,45 @@ import PluginHeader from 'components/PluginHeader';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import RightContentTitle from 'components/RightContentTitle';
|
import RightContentTitle from 'components/RightContentTitle';
|
||||||
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
||||||
|
import { injectIntl, intlShape } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
export default class LanguagesPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class LanguagesPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.languagesPage}>
|
<div className={styles.languagesPage}>
|
||||||
<Helmet
|
<Helmet
|
||||||
title="Settings Manager - Languages"
|
title="Settings Manager - Languages"
|
||||||
meta={[
|
meta={[
|
||||||
{ name: 'description', content: 'Configure your Languages settings.' },
|
{ name: 'description', content: formatMessage(messages.rightSectionDescription) },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader></PluginHeader>
|
<PluginHeader />
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="Languages" description="Configure your languages settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Coming soon" description=""></RightContentSectionTitle>
|
title={formatMessage(appMessages.languagesSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(appMessages.comingSoon)}
|
||||||
|
description=""
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LanguagesPage.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(LanguagesPage);
|
||||||
|
13
public/app/containers/LanguagesPage/messages.js
Normal file
13
public/app/containers/LanguagesPage/messages.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* LanguagesPage Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the LanguagesPage component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
rightSectionDescription: {
|
||||||
|
id: 'settings-manager.components.LanguagesPage.rightSectionDescription',
|
||||||
|
defaultMessage: 'Configure your languages settings',
|
||||||
|
},
|
||||||
|
});
|
@ -8,27 +8,44 @@ import PluginHeader from 'components/PluginHeader';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import RightContentTitle from 'components/RightContentTitle';
|
import RightContentTitle from 'components/RightContentTitle';
|
||||||
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
||||||
|
import { injectIntl, intlShape } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
export default class SecurityPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class SecurityPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.securityPage}>
|
<div className={styles.securityPage}>
|
||||||
<Helmet
|
<Helmet
|
||||||
title="Settings Manager - Security"
|
title="Settings Manager - Security"
|
||||||
meta={[
|
meta={[
|
||||||
{ name: 'description', content: 'Configure your security settings.' },
|
{ name: 'description', content: formatMessage(messages.rightSectionDescription) },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader></PluginHeader>
|
<PluginHeader />
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="Security" description="Configure your security settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Coming soon" description=""></RightContentSectionTitle>
|
title={formatMessage(appMessages.securitySectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(appMessages.comingSoon)}
|
||||||
|
description=""
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SecurityPage.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(SecurityPage);
|
||||||
|
13
public/app/containers/SecurityPage/messages.js
Normal file
13
public/app/containers/SecurityPage/messages.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* LanguagesPage Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the LanguagesPage component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
rightSectionDescription: {
|
||||||
|
id: 'settings-manager.components.SecurityPage.rightSectionDescription',
|
||||||
|
defaultMessage: 'Configure your security settings',
|
||||||
|
},
|
||||||
|
});
|
@ -8,27 +8,44 @@ import PluginHeader from 'components/PluginHeader';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import RightContentTitle from 'components/RightContentTitle';
|
import RightContentTitle from 'components/RightContentTitle';
|
||||||
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
import RightContentSectionTitle from 'components/RightContentSectionTitle';
|
||||||
|
import { injectIntl, intlShape } from 'react-intl';
|
||||||
|
import appMessages from 'containers/App/messages';
|
||||||
|
import messages from './messages';
|
||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
export default class ServerPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class ServerPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
render() {
|
render() {
|
||||||
|
const { formatMessage } = this.props.intl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.serverPage}>
|
<div className={styles.serverPage}>
|
||||||
<Helmet
|
<Helmet
|
||||||
title="Settings Manager - Server"
|
title="Settings Manager - Server"
|
||||||
meta={[
|
meta={[
|
||||||
{ name: 'description', content: 'Configure your Server settings.' },
|
{ name: 'description', content: formatMessage(messages.rightSectionDescription) },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<PluginHeader></PluginHeader>
|
<PluginHeader />
|
||||||
<Container>
|
<Container>
|
||||||
<RightContentTitle title="Server" description="Configure your server settings."></RightContentTitle>
|
<RightContentTitle
|
||||||
<RightContentSectionTitle title="Coming soon" description=""></RightContentSectionTitle>
|
title={formatMessage(appMessages.serverSectionTitle)}
|
||||||
|
description={formatMessage(messages.rightSectionDescription)}
|
||||||
|
/>
|
||||||
|
<RightContentSectionTitle
|
||||||
|
title={formatMessage(appMessages.comingSoon)}
|
||||||
|
description=""
|
||||||
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerPage.propTypes = {
|
||||||
|
intl: intlShape.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(ServerPage);
|
||||||
|
13
public/app/containers/ServerPage/messages.js
Normal file
13
public/app/containers/ServerPage/messages.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* LanguagesPage Messages
|
||||||
|
*
|
||||||
|
* This contains all the text for the LanguagesPage component.
|
||||||
|
*/
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
export default defineMessages({
|
||||||
|
rightSectionDescription: {
|
||||||
|
id: 'settings-manager.components.ServerPage.rightSectionDescription',
|
||||||
|
defaultMessage: 'Configure your server settings',
|
||||||
|
},
|
||||||
|
});
|
@ -4,17 +4,22 @@
|
|||||||
* This will setup the i18n language files and locale data for your plugin.
|
* This will setup the i18n language files and locale data for your plugin.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import { addLocaleData } from 'react-intl';
|
// import { addLocaleData } from 'react-intl';
|
||||||
|
|
||||||
import enLocaleData from 'react-intl/locale-data/en';
|
// import enLocaleData from 'react-intl/locale-data/en';
|
||||||
|
// import frLocaleData from 'react-intl/locale-data/fr';
|
||||||
|
|
||||||
export const appLocales = [
|
// export const appLocales = [
|
||||||
'en',
|
// 'en',
|
||||||
];
|
// 'fr',
|
||||||
|
//
|
||||||
|
// ];
|
||||||
|
|
||||||
import enTranslationMessages from './translations/en.json';
|
import enTranslationMessages from './translations/en.json';
|
||||||
|
import frTranslationMessages from './translations/fr.json';
|
||||||
|
|
||||||
addLocaleData(enLocaleData);
|
// addLocaleData(enLocaleData);
|
||||||
|
// addLocaleData(frLocaleData);
|
||||||
|
|
||||||
const formatTranslationMessages = (messages) => {
|
const formatTranslationMessages = (messages) => {
|
||||||
const formattedMessages = {};
|
const formattedMessages = {};
|
||||||
@ -27,4 +32,5 @@ const formatTranslationMessages = (messages) => {
|
|||||||
|
|
||||||
export const translationMessages = {
|
export const translationMessages = {
|
||||||
en: formatTranslationMessages(enTranslationMessages),
|
en: formatTranslationMessages(enTranslationMessages),
|
||||||
|
fr: formatTranslationMessages(frTranslationMessages),
|
||||||
};
|
};
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
// Import variables
|
// Import variables
|
||||||
@import "variables/variables";
|
@import 'variables/variables';
|
||||||
|
@ -1 +1,16 @@
|
|||||||
[]
|
[
|
||||||
|
{
|
||||||
|
"id": "app.components.DatabasesPage.header",
|
||||||
|
"defaultMessage": "This is the Databases page of the Settings Manager plugin!",
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.components.NotFoundPage.pageNotFound",
|
||||||
|
"defaultMessage": "Page not found.",
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "settings-manager.components.HomePage.header",
|
||||||
|
"defaultMessage": "This is HomePage components !"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
16
public/app/translations/fr.json
Normal file
16
public/app/translations/fr.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "app.components.DatabasesPage.header",
|
||||||
|
"defaultMessage": "This is the Databases page of the Settings Manager plugin!",
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "app.components.NotFoundPage.pageNotFound",
|
||||||
|
"defaultMessage": "Page not found.",
|
||||||
|
"message": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "settings-manager.components.HomePage.header",
|
||||||
|
"defaultMessage": "Ceci est la page d'accueil!"
|
||||||
|
}
|
||||||
|
]
|
@ -11,7 +11,7 @@ import { FormattedMessage } from 'react-intl';
|
|||||||
import messages from './messages';
|
import messages from './messages';
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if wantCSS}}
|
{{#if wantCSS}}
|
||||||
import styles from './styles.scss';
|
import styles from './styles.css';
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
|
@ -49,12 +49,12 @@ module.exports = {
|
|||||||
abortOnFail: true,
|
abortOnFail: true,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// If they want a CSS file, add styles.scss
|
// If they want a CSS file, add styles.css
|
||||||
if (data.wantCSS) {
|
if (data.wantCSS) {
|
||||||
actions.push({
|
actions.push({
|
||||||
type: 'add',
|
type: 'add',
|
||||||
path: '../../app/components/{{properCase name}}/styles.scss',
|
path: '../../app/components/{{properCase name}}/styles.css',
|
||||||
templateFile: './component/styles.scss.hbs',
|
templateFile: './component/styles.css.hbs',
|
||||||
abortOnFail: true,
|
abortOnFail: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import messages from './messages';
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if wantCSS}}
|
{{#if wantCSS}}
|
||||||
import styles from './styles.scss';
|
import styles from './styles.css';
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
function {{ properCase name }}() {
|
function {{ properCase name }}() {
|
||||||
|
@ -58,12 +58,12 @@ module.exports = {
|
|||||||
abortOnFail: true,
|
abortOnFail: true,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// If they want a CSS file, add styles.scss
|
// If they want a CSS file, add styles.css
|
||||||
if (data.wantCSS) {
|
if (data.wantCSS) {
|
||||||
actions.push({
|
actions.push({
|
||||||
type: 'add',
|
type: 'add',
|
||||||
path: '../../app/containers/{{properCase name}}/styles.scss',
|
path: '../../app/containers/{{properCase name}}/styles.css',
|
||||||
templateFile: './container/styles.scss.hbs',
|
templateFile: './container/styles.css.hbs',
|
||||||
abortOnFail: true,
|
abortOnFail: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import { FormattedMessage } from 'react-intl';
|
|||||||
import messages from './messages';
|
import messages from './messages';
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if wantCSS}}
|
{{#if wantCSS}}
|
||||||
import styles from './styles.scss';
|
import styles from './styles.css';
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
export class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
export class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
|
@ -8,11 +8,13 @@ const fs = require('fs');
|
|||||||
const componentGenerator = require('./component/index.js');
|
const componentGenerator = require('./component/index.js');
|
||||||
const containerGenerator = require('./container/index.js');
|
const containerGenerator = require('./container/index.js');
|
||||||
const routeGenerator = require('./route/index.js');
|
const routeGenerator = require('./route/index.js');
|
||||||
|
const languageGenerator = require('./language/index.js');
|
||||||
|
|
||||||
module.exports = (plop) => {
|
module.exports = (plop) => {
|
||||||
plop.setGenerator('component', componentGenerator);
|
plop.setGenerator('component', componentGenerator);
|
||||||
plop.setGenerator('container', containerGenerator);
|
plop.setGenerator('container', containerGenerator);
|
||||||
plop.setGenerator('route', routeGenerator);
|
plop.setGenerator('route', routeGenerator);
|
||||||
|
plop.setGenerator('language', languageGenerator);
|
||||||
plop.addHelper('directory', (comp) => {
|
plop.addHelper('directory', (comp) => {
|
||||||
try {
|
try {
|
||||||
fs.accessSync(`app/containers/${comp}`, fs.F_OK);
|
fs.accessSync(`app/containers/${comp}`, fs.F_OK);
|
||||||
|
1
public/internals/generators/language/add-locale-data.hbs
Normal file
1
public/internals/generators/language/add-locale-data.hbs
Normal file
@ -0,0 +1 @@
|
|||||||
|
$1addLocaleData({{language}}LocaleData);
|
2
public/internals/generators/language/app-locale.hbs
Normal file
2
public/internals/generators/language/app-locale.hbs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
$1
|
||||||
|
'{{language}}',
|
@ -0,0 +1 @@
|
|||||||
|
$1 {{language}}: formatTranslationMessages({{language}}TranslationMessages),
|
80
public/internals/generators/language/index.js
Normal file
80
public/internals/generators/language/index.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* Language Generator
|
||||||
|
*/
|
||||||
|
const exec = require('child_process').exec;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
description: 'Add a langauge',
|
||||||
|
prompts: [{
|
||||||
|
type: 'input',
|
||||||
|
name: 'language',
|
||||||
|
message: 'What is the language you want to add i18n support for (e.g. "fr", "de")?',
|
||||||
|
default: 'fr',
|
||||||
|
validate: value => {
|
||||||
|
if ((/.+/).test(value) && value.length === 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '2 character language specifier is required';
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
|
||||||
|
actions: () => {
|
||||||
|
const actions = [];
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/i18n.js',
|
||||||
|
pattern: /('react-intl\/locale-data\/[a-z]+';\n)(?!.*'react-intl\/locale-data\/[a-z]+';)/g,
|
||||||
|
templateFile: './language/intl-locale-data.hbs',
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/i18n.js',
|
||||||
|
pattern: /([\n\s'[a-z]+',)(?!.*[\n\s'[a-z]+',)/g,
|
||||||
|
templateFile: './language/app-locale.hbs',
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/i18n.js',
|
||||||
|
pattern: /(from\s'.\/translations\/[a-z]+.json';\n)(?!.*from\s'.\/translations\/[a-z]+.json';)/g,
|
||||||
|
templateFile: './language/translation-messages.hbs',
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/i18n.js',
|
||||||
|
pattern: /(addLocaleData\([a-z]+LocaleData\);\n)(?!.*addLocaleData\([a-z]+LocaleData\);)/g,
|
||||||
|
templateFile: './language/add-locale-data.hbs',
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/i18n.js',
|
||||||
|
pattern: /([a-z]+:\sformatTranslationMessages\([a-z]+TranslationMessages\),\n)(?!.*[a-z]+:\sformatTranslationMessages\([a-z]+TranslationMessages\),)/g,
|
||||||
|
templateFile: './language/format-translation-messages.hbs',
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'add',
|
||||||
|
path: '../../app/translations/{{language}}.json',
|
||||||
|
templateFile: './language/translations-json.hbs',
|
||||||
|
abortOnFail: true,
|
||||||
|
});
|
||||||
|
actions.push({
|
||||||
|
type: 'modify',
|
||||||
|
path: '../../app/app.js',
|
||||||
|
pattern: /(System\.import\('intl\/locale-data\/jsonp\/[a-z]+\.js'\),\n)(?!.*System\.import\('intl\/locale-data\/jsonp\/[a-z]+\.js'\),)/g,
|
||||||
|
templateFile: './language/polyfill-intl-locale.hbs',
|
||||||
|
});
|
||||||
|
actions.push(
|
||||||
|
() => {
|
||||||
|
const cmd = 'npm run extract-intl';
|
||||||
|
exec(cmd, (err, result, stderr) => {
|
||||||
|
if (err || stderr) {
|
||||||
|
throw err || stderr;
|
||||||
|
}
|
||||||
|
process.stdout.write(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1 @@
|
|||||||
|
$1import {{language}}LocaleData from 'react-intl/locale-data/{{language}}';
|
@ -0,0 +1 @@
|
|||||||
|
$1 System.import('intl/locale-data/jsonp/{{language}}.js'),
|
@ -0,0 +1 @@
|
|||||||
|
$1import {{language}}TranslationMessages from './translations/{{language}}.json';
|
@ -0,0 +1 @@
|
|||||||
|
[]
|
@ -28,10 +28,10 @@
|
|||||||
"start:production": "npm run build && npm run start:prod",
|
"start:production": "npm run build && npm run start:prod",
|
||||||
"start:prod": "cross-env NODE_ENV=production node server",
|
"start:prod": "cross-env NODE_ENV=production node server",
|
||||||
"generate": "plop --plopfile internals/generators/index.js",
|
"generate": "plop --plopfile internals/generators/index.js",
|
||||||
"lint": "npm run lint:js && npm run lint:css",
|
"lint": "npm run lint:js && npm run lint:scss",
|
||||||
"lint:eslint": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts",
|
"lint:eslint": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts",
|
||||||
"lint:js": "npm run lint:eslint -- . ",
|
"lint:js": "npm run lint:eslint -- . ",
|
||||||
"lint:css": "stylelint ./app/**/*.css",
|
"lint:scss": "stylelint ./app/**/*.scss",
|
||||||
"lint:staged": "lint-staged",
|
"lint:staged": "lint-staged",
|
||||||
"pretest": "npm run test:clean && npm run lint",
|
"pretest": "npm run test:clean && npm run lint",
|
||||||
"test:clean": "rimraf ./coverage",
|
"test:clean": "rimraf ./coverage",
|
||||||
@ -44,7 +44,7 @@
|
|||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.js": "lint:eslint",
|
"*.js": "lint:eslint",
|
||||||
"*.css": "stylelint"
|
"*.scss": "stylelint"
|
||||||
},
|
},
|
||||||
"pre-commit": "lint:staged",
|
"pre-commit": "lint:staged",
|
||||||
"babel": {
|
"babel": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user