diff --git a/public/app/app.js b/public/app/app.js index 01791d491b..8f2587e990 100644 --- a/public/app/app.js +++ b/public/app/app.js @@ -18,6 +18,7 @@ const store = configureStore(initialState, browserHistory); // Set up the router, wrapping all Routes in the App component import App from 'containers/App'; import createRoutes from './routes'; +import { translationMessages } from './i18n'; // Plugin identifier based on the package.json `name` value const pluginId = require('../package.json').name.replace(/^strapi-/i, ''); @@ -33,6 +34,22 @@ if (window.Strapi) { }, mainComponent: App, 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); + }); + } }); } diff --git a/public/app/components/LeftMenu/index.js b/public/app/components/LeftMenu/index.js index 1dca870ace..f83576b8bc 100644 --- a/public/app/components/LeftMenu/index.js +++ b/public/app/components/LeftMenu/index.js @@ -11,27 +11,21 @@ import styles from './styles.scss'; class LeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function links = [{ - label: 'General', value: 'general', to: '', }, { - label: 'Languages', value: 'languages', to: 'languages', }, { - label: 'Databases', value: 'databases', to: 'databases', }, { - label: 'Security', value: 'security', to: 'security', }, { - label: 'Server', value: 'server', to: 'server', }, { - label: 'Advanced', value: 'advanced', to: 'advanced', }]; diff --git a/public/app/components/LeftMenuLink/index.js b/public/app/components/LeftMenuLink/index.js index 949cb37a05..16fc0f6fa4 100644 --- a/public/app/components/LeftMenuLink/index.js +++ b/public/app/components/LeftMenuLink/index.js @@ -1,19 +1,27 @@ /** -* -* LeftMenuLink -* -*/ + * + * LeftMenuLink + * + */ import React from 'react'; import { Link } from 'react-router'; +import appMessages from 'containers/App/messages'; +import { FormattedMessage } from 'react-intl'; import styles from './styles.scss'; -console.log('styles', styles); + class LeftMenuLink extends React.Component { // eslint-disable-line react/prefer-stateless-function render() { + const messageKey = `${this.props.link.value}SectionTitle`; return (
  • - {this.props.link.label} + +
  • diff --git a/public/app/components/PluginHeaderActions/index.js b/public/app/components/PluginHeaderActions/index.js index f0fa12d0f9..70eafbe329 100644 --- a/public/app/components/PluginHeaderActions/index.js +++ b/public/app/components/PluginHeaderActions/index.js @@ -5,6 +5,8 @@ */ import React from 'react'; +import messages from './messages'; +import { FormattedMessage } from 'react-intl'; import styles from './styles.scss'; @@ -17,7 +19,7 @@ class PluginHeaderActions extends React.Component { // eslint-disable-line react className={`${styles.pluginHeaderActionsButton} btn btn-secondary`} onClick={this.props.onCancel} > - Cancel + ); diff --git a/public/app/components/PluginHeaderActions/messages.js b/public/app/components/PluginHeaderActions/messages.js new file mode 100644 index 0000000000..137a489e29 --- /dev/null +++ b/public/app/components/PluginHeaderActions/messages.js @@ -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', + }, +}); diff --git a/public/app/components/PluginHeaderTitle/index.js b/public/app/components/PluginHeaderTitle/index.js index f91bd21a55..8be44ef827 100644 --- a/public/app/components/PluginHeaderTitle/index.js +++ b/public/app/components/PluginHeaderTitle/index.js @@ -5,15 +5,21 @@ */ import React from 'react'; +import { FormattedMessage } from 'react-intl'; +import messages from './messages'; import styles from './styles.scss'; class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function render() { return (
    -

    Settings Manager

    -

    Easily update your settings

    +

    + +

    +

    + +

    ); } diff --git a/public/app/components/PluginHeaderTitle/messages.js b/public/app/components/PluginHeaderTitle/messages.js new file mode 100644 index 0000000000..fb3292cb57 --- /dev/null +++ b/public/app/components/PluginHeaderTitle/messages.js @@ -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', + }, +}); diff --git a/public/app/containers/AdvancedPage/index.js b/public/app/containers/AdvancedPage/index.js index fdd986fcf5..fa045104a5 100644 --- a/public/app/containers/AdvancedPage/index.js +++ b/public/app/containers/AdvancedPage/index.js @@ -10,26 +10,44 @@ import PluginHeader from 'components/PluginHeader'; import Container from 'components/Container'; import RightContentTitle from 'components/RightContentTitle'; 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'; -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() { + const { formatMessage } = this.props.intl; + return (
    - + - - + +
    ); } } + +AdvancedPage.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(AdvancedPage); diff --git a/public/app/containers/AdvancedPage/messages.js b/public/app/containers/AdvancedPage/messages.js new file mode 100644 index 0000000000..e6fb0b221a --- /dev/null +++ b/public/app/containers/AdvancedPage/messages.js @@ -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', + }, +}); diff --git a/public/app/containers/App/messages.js b/public/app/containers/App/messages.js new file mode 100644 index 0000000000..2e9cd562ad --- /dev/null +++ b/public/app/containers/App/messages.js @@ -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', + }, +}); diff --git a/public/app/containers/DatabasesPage/index.js b/public/app/containers/DatabasesPage/index.js index 7521b8b367..22decd0357 100644 --- a/public/app/containers/DatabasesPage/index.js +++ b/public/app/containers/DatabasesPage/index.js @@ -8,28 +8,45 @@ import PluginHeader from 'components/PluginHeader'; import Container from 'components/Container'; import RightContentTitle from 'components/RightContentTitle'; 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'; -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() { + const { formatMessage } = this.props.intl; + return (
    - + - - + +
    ); } } + +DatabasesPage.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(DatabasesPage); diff --git a/public/app/containers/DatabasesPage/messages.js b/public/app/containers/DatabasesPage/messages.js index a20595cc75..341d039200 100644 --- a/public/app/containers/DatabasesPage/messages.js +++ b/public/app/containers/DatabasesPage/messages.js @@ -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'; export default defineMessages({ - header: { - id: 'app.components.DatabasesPage.header', - defaultMessage: 'This is the Databases page of the Settings Manager plugin!', + rightSectionDescription: { + id: 'settings-manager.components.DatabasesPage.rightSectionDescription', + defaultMessage: 'Configure your databases settings', }, }); diff --git a/public/app/containers/HomePage/index.js b/public/app/containers/HomePage/index.js index c1338a2cdf..a22808a4a1 100644 --- a/public/app/containers/HomePage/index.js +++ b/public/app/containers/HomePage/index.js @@ -31,6 +31,9 @@ import { updateGeneralSettings, cancelGeneralSettings, } 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'; @@ -41,21 +44,31 @@ export class HomePage extends React.Component { } render() { + const { formatMessage } = this.props.intl; + return (
    - - + +
    - +
    - +
    - +
    - + - - + +
    ); } } + +LanguagesPage.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(LanguagesPage); diff --git a/public/app/containers/LanguagesPage/messages.js b/public/app/containers/LanguagesPage/messages.js new file mode 100644 index 0000000000..cb68409032 --- /dev/null +++ b/public/app/containers/LanguagesPage/messages.js @@ -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', + }, +}); diff --git a/public/app/containers/SecurityPage/index.js b/public/app/containers/SecurityPage/index.js index b46721f787..bdde2ff11a 100644 --- a/public/app/containers/SecurityPage/index.js +++ b/public/app/containers/SecurityPage/index.js @@ -8,27 +8,44 @@ import PluginHeader from 'components/PluginHeader'; import Container from 'components/Container'; import RightContentTitle from 'components/RightContentTitle'; 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'; -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() { + const { formatMessage } = this.props.intl; + return (
    - + - - + +
    ); } } + +SecurityPage.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(SecurityPage); diff --git a/public/app/containers/SecurityPage/messages.js b/public/app/containers/SecurityPage/messages.js new file mode 100644 index 0000000000..bb8a897a50 --- /dev/null +++ b/public/app/containers/SecurityPage/messages.js @@ -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', + }, +}); diff --git a/public/app/containers/ServerPage/index.js b/public/app/containers/ServerPage/index.js index f75ac97187..98d46be247 100644 --- a/public/app/containers/ServerPage/index.js +++ b/public/app/containers/ServerPage/index.js @@ -8,27 +8,44 @@ import PluginHeader from 'components/PluginHeader'; import Container from 'components/Container'; import RightContentTitle from 'components/RightContentTitle'; 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'; -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() { + const { formatMessage } = this.props.intl; + return (
    - + - - + +
    ); } } + +ServerPage.propTypes = { + intl: intlShape.isRequired, +}; + +export default injectIntl(ServerPage); diff --git a/public/app/containers/ServerPage/messages.js b/public/app/containers/ServerPage/messages.js new file mode 100644 index 0000000000..d7c7829a0d --- /dev/null +++ b/public/app/containers/ServerPage/messages.js @@ -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', + }, +}); diff --git a/public/app/i18n.js b/public/app/i18n.js index 73d1f94a81..9deb722dac 100644 --- a/public/app/i18n.js +++ b/public/app/i18n.js @@ -4,17 +4,22 @@ * 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 = [ - 'en', -]; +// export const appLocales = [ +// 'en', +// 'fr', +// +// ]; import enTranslationMessages from './translations/en.json'; +import frTranslationMessages from './translations/fr.json'; -addLocaleData(enLocaleData); +// addLocaleData(enLocaleData); +// addLocaleData(frLocaleData); const formatTranslationMessages = (messages) => { const formattedMessages = {}; @@ -27,4 +32,5 @@ const formatTranslationMessages = (messages) => { export const translationMessages = { en: formatTranslationMessages(enTranslationMessages), + fr: formatTranslationMessages(frTranslationMessages), }; diff --git a/public/app/styles/main.scss b/public/app/styles/main.scss index afcdcf8e3d..506854ddc0 100644 --- a/public/app/styles/main.scss +++ b/public/app/styles/main.scss @@ -1,2 +1,2 @@ // Import variables -@import "variables/variables"; +@import 'variables/variables'; diff --git a/public/app/translations/en.json b/public/app/translations/en.json index fe51488c70..3a6cbdca27 100644 --- a/public/app/translations/en.json +++ b/public/app/translations/en.json @@ -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 !" + } +] diff --git a/public/app/translations/fr.json b/public/app/translations/fr.json new file mode 100644 index 0000000000..52682d72cf --- /dev/null +++ b/public/app/translations/fr.json @@ -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!" + } +] diff --git a/public/internals/generators/component/es6.js.hbs b/public/internals/generators/component/es6.js.hbs index f94b3cd6bc..5a8b1ce481 100644 --- a/public/internals/generators/component/es6.js.hbs +++ b/public/internals/generators/component/es6.js.hbs @@ -11,7 +11,7 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; {{/if}} {{#if wantCSS}} -import styles from './styles.scss'; +import styles from './styles.css'; {{/if}} class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/public/internals/generators/component/index.js b/public/internals/generators/component/index.js index 117240b796..2b522711ce 100644 --- a/public/internals/generators/component/index.js +++ b/public/internals/generators/component/index.js @@ -49,12 +49,12 @@ module.exports = { abortOnFail: true, }]; - // If they want a CSS file, add styles.scss + // If they want a CSS file, add styles.css if (data.wantCSS) { actions.push({ type: 'add', - path: '../../app/components/{{properCase name}}/styles.scss', - templateFile: './component/styles.scss.hbs', + path: '../../app/components/{{properCase name}}/styles.css', + templateFile: './component/styles.css.hbs', abortOnFail: true, }); } diff --git a/public/internals/generators/component/stateless.js.hbs b/public/internals/generators/component/stateless.js.hbs index 2184b2ae2b..7ff8824f8a 100644 --- a/public/internals/generators/component/stateless.js.hbs +++ b/public/internals/generators/component/stateless.js.hbs @@ -12,7 +12,7 @@ import messages from './messages'; {{/if}} {{#if wantCSS}} -import styles from './styles.scss'; +import styles from './styles.css'; {{/if}} function {{ properCase name }}() { diff --git a/public/internals/generators/container/index.js b/public/internals/generators/container/index.js index cdcbd99fed..44dc4b4c34 100644 --- a/public/internals/generators/container/index.js +++ b/public/internals/generators/container/index.js @@ -58,12 +58,12 @@ module.exports = { abortOnFail: true, }]; - // If they want a CSS file, add styles.scss + // If they want a CSS file, add styles.css if (data.wantCSS) { actions.push({ type: 'add', - path: '../../app/containers/{{properCase name}}/styles.scss', - templateFile: './container/styles.scss.hbs', + path: '../../app/containers/{{properCase name}}/styles.css', + templateFile: './container/styles.css.hbs', abortOnFail: true, }); } diff --git a/public/internals/generators/container/index.js.hbs b/public/internals/generators/container/index.js.hbs index ff40b21d57..420ae1fc0b 100644 --- a/public/internals/generators/container/index.js.hbs +++ b/public/internals/generators/container/index.js.hbs @@ -17,7 +17,7 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; {{/if}} {{#if wantCSS}} -import styles from './styles.scss'; +import styles from './styles.css'; {{/if}} export class {{ properCase name }} extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/public/internals/generators/index.js b/public/internals/generators/index.js index 4fdd4c53ec..4bc7392ce4 100644 --- a/public/internals/generators/index.js +++ b/public/internals/generators/index.js @@ -8,11 +8,13 @@ const fs = require('fs'); const componentGenerator = require('./component/index.js'); const containerGenerator = require('./container/index.js'); const routeGenerator = require('./route/index.js'); +const languageGenerator = require('./language/index.js'); module.exports = (plop) => { plop.setGenerator('component', componentGenerator); plop.setGenerator('container', containerGenerator); plop.setGenerator('route', routeGenerator); + plop.setGenerator('language', languageGenerator); plop.addHelper('directory', (comp) => { try { fs.accessSync(`app/containers/${comp}`, fs.F_OK); diff --git a/public/internals/generators/language/add-locale-data.hbs b/public/internals/generators/language/add-locale-data.hbs new file mode 100644 index 0000000000..80727c73cd --- /dev/null +++ b/public/internals/generators/language/add-locale-data.hbs @@ -0,0 +1 @@ +$1addLocaleData({{language}}LocaleData); diff --git a/public/internals/generators/language/app-locale.hbs b/public/internals/generators/language/app-locale.hbs new file mode 100644 index 0000000000..9e99e845f8 --- /dev/null +++ b/public/internals/generators/language/app-locale.hbs @@ -0,0 +1,2 @@ +$1 + '{{language}}', diff --git a/public/internals/generators/language/format-translation-messages.hbs b/public/internals/generators/language/format-translation-messages.hbs new file mode 100644 index 0000000000..74c78b4632 --- /dev/null +++ b/public/internals/generators/language/format-translation-messages.hbs @@ -0,0 +1 @@ +$1 {{language}}: formatTranslationMessages({{language}}TranslationMessages), diff --git a/public/internals/generators/language/index.js b/public/internals/generators/language/index.js new file mode 100644 index 0000000000..83899c61a4 --- /dev/null +++ b/public/internals/generators/language/index.js @@ -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; + }, +}; diff --git a/public/internals/generators/language/intl-locale-data.hbs b/public/internals/generators/language/intl-locale-data.hbs new file mode 100644 index 0000000000..b790a1333f --- /dev/null +++ b/public/internals/generators/language/intl-locale-data.hbs @@ -0,0 +1 @@ +$1import {{language}}LocaleData from 'react-intl/locale-data/{{language}}'; diff --git a/public/internals/generators/language/polyfill-intl-locale.hbs b/public/internals/generators/language/polyfill-intl-locale.hbs new file mode 100644 index 0000000000..ea1586e7ed --- /dev/null +++ b/public/internals/generators/language/polyfill-intl-locale.hbs @@ -0,0 +1 @@ +$1 System.import('intl/locale-data/jsonp/{{language}}.js'), diff --git a/public/internals/generators/language/translation-messages.hbs b/public/internals/generators/language/translation-messages.hbs new file mode 100644 index 0000000000..0682d22ed0 --- /dev/null +++ b/public/internals/generators/language/translation-messages.hbs @@ -0,0 +1 @@ +$1import {{language}}TranslationMessages from './translations/{{language}}.json'; diff --git a/public/internals/generators/language/translations-json.hbs b/public/internals/generators/language/translations-json.hbs new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/public/internals/generators/language/translations-json.hbs @@ -0,0 +1 @@ +[] diff --git a/public/package.json b/public/package.json index 556971bbcf..59db1623c9 100644 --- a/public/package.json +++ b/public/package.json @@ -28,10 +28,10 @@ "start:production": "npm run build && npm run start:prod", "start:prod": "cross-env NODE_ENV=production node server", "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:js": "npm run lint:eslint -- . ", - "lint:css": "stylelint ./app/**/*.css", + "lint:scss": "stylelint ./app/**/*.scss", "lint:staged": "lint-staged", "pretest": "npm run test:clean && npm run lint", "test:clean": "rimraf ./coverage", @@ -44,7 +44,7 @@ }, "lint-staged": { "*.js": "lint:eslint", - "*.css": "stylelint" + "*.scss": "stylelint" }, "pre-commit": "lint:staged", "babel": {