diff --git a/server/agent.js b/server/agent.js index c38d7aae..f583db8a 100644 --- a/server/agent.js +++ b/server/agent.js @@ -32,6 +32,7 @@ global.db = require('./libs/db').init() global.upl = require('./libs/uploads-agent').init() global.git = require('./libs/git').init() global.entries = require('./libs/entries').init() +global.lang = require('i18next') global.mark = require('./libs/markdown') // ---------------------------------------- @@ -43,9 +44,31 @@ const Promise = require('bluebird') const fs = Promise.promisifyAll(require('fs-extra')) const klaw = require('klaw') const Cron = require('cron').CronJob +const i18nextBackend = require('i18next-node-fs-backend') +const i18nextMw = require('i18next-express-middleware') const entryHelper = require('./helpers/entry') +// ---------------------------------------- +// Localization Engine +// ---------------------------------------- + +lang + .use(i18nextBackend) + .use(i18nextMw.LanguageDetector) + .init({ + load: 'languageOnly', + ns: ['common', 'errors', 'git'], + defaultNS: 'common', + saveMissing: false, + supportedLngs: ['en', 'fr'], + preload: ['en', 'fr'], + fallbackLng: 'en', + backend: { + loadPath: path.join(SERVERPATH, 'locales/{{lng}}/{{ns}}.json') + } + }) + // ---------------------------------------- // Start Cron // ---------------------------------------- diff --git a/server/index.js b/server/index.js index 2cd8f0af..aa361e32 100644 --- a/server/index.js +++ b/server/index.js @@ -124,7 +124,7 @@ lang .use(i18nextMw.LanguageDetector) .init({ load: 'languageOnly', - ns: ['common', 'auth'], + ns: ['common', 'admin', 'auth', 'errors', 'git'], defaultNS: 'common', saveMissing: false, supportedLngs: ['en', 'fr'], diff --git a/server/locales/en/admin.json b/server/locales/en/admin.json new file mode 100644 index 00000000..e62976fb --- /dev/null +++ b/server/locales/en/admin.json @@ -0,0 +1,51 @@ +{ + "profile": { + "displayname": "Display Name", + "displaynameexample": "John Smith", + "email": "Email", + "lastprofileupdate": "Last Profile Update", + "membersince": "Member since", + "password": "Password", + "passwordverify": "Verify Password", + "provider": "Provider", + "savechanges": "Save Changes", + "subtitle": "Profile and authentication info" + }, + "stats": { + "subtitle": "General site-wide statistics", + "entries": "Entries", + "uploads": "Uploads", + "users": "Users" + }, + "settings": { + "subtitle": "Manage site configuration", + "systemversion": "System Version", + "currentversion": "Current Version", + "latestversion": "Latest Version", + "upgrade": "Upgrade", + "reinstall": "Re-install current version", + "versioncheckfailed": "Unable to query latest version. Try again later.", + "administrativetools": "Administrative Tools", + "flushcache": "Flush cache and rebuild indexes", + "flushcachetext": "If content or search results seems out-of-date or do not include latest content, flushing the cache can help resolve these issues.", + "flushcachebtn": "Flush and Rebuild", + "resetaccounts": "Reset the system accounts to defaults", + "resetaccountstext": "The system accounts (such as the Guest account) will be reset to their default settings.", + "resetaccountsbtn": "Reset System Accounts", + "flushsessions": "Flush all active user sessions", + "flushsessionstext": "All users will be logged out and forced to login again. Your current session will also be affected!", + "flushsessionsbtn": "Flush Sessions" + }, + "users": { + "createauthorize": "Create / Authorize User", + "subtitle": "Manage users and access rights", + "name": "Name", + "email": "Email Address", + "provider": "Provider", + "createdon": "Created On", + "updatedon": "Updated On", + "returntousers": "Return to Users", + "edituser": "Edit User", + "uniqueid": "Unique ID" + } +} diff --git a/server/views/pages/admin/profile.pug b/server/views/pages/admin/profile.pug index 5a8eedd3..1c54549f 100644 --- a/server/views/pages/admin/profile.pug +++ b/server/views/pages/admin/profile.pug @@ -3,35 +3,35 @@ extends ./_layout.pug block adminContent #page-type-admin-profile .hero - h1.title#title My Profile - h2.subtitle Profile and authentication info + h1.title#title= t('nav.myprofile') + h2.subtitle= t('admin:profile.subtitle') .form-sections .columns.is-gapless .column.is-two-thirds section - label.label Email + label.label= t('admin:profile.email') p.control.is-fullwidth - input.input(type='text', placeholder='Email', value=user.email, disabled) + input.input(type='text', placeholder=t('admin:profile.email'), value=user.email, disabled) if user.provider === 'local' section - label.label Password + label.label= t('admin:profile.password') p.control.is-fullwidth - input.input(type='password', placeholder='Password', value='********', v-model='password') + input.input(type='password', placeholder=t('admin:profile.password'), value='********', v-model='password') section - label.label Verify Password + label.label= t('admin:profile.passwordverify') p.control.is-fullwidth - input.input(type='password', placeholder='Password', value='********', v-model='passwordVerify') + input.input(type='password', placeholder=t('admin:profile.password'), value='********', v-model='passwordVerify') section - label.label Display Name + label.label= t('admin:profile.displayname') p.control.is-fullwidth - input.input(type='text', placeholder='John Smith', v-model='name') + input.input(type='text', placeholder=t('admin:profile.displaynameexample'), v-model='name') section button.button.is-green(v-on:click='saveUser') i.icon-check - span Save Changes + span= t('admin:profile.savechanges') .column .panel-aside - label.label Provider + label.label= t('admin:profile.provider') p.control.account-profile-provider case user.provider when 'local': i.icon-server @@ -44,9 +44,9 @@ block adminContent when 'ldap': i.icon-arrow-repeat-outline default: i.icon-warning = t('auth:providers.' + user.provider) - label.label Member since + label.label= t('admin:profile.membersince') p.control= userMoment(user.createdAt).format('LL') - label.label Last Profile Update + label.label= t('admin:profile.lastprofileupdate') p.control= userMoment(user.updatedAt).format('LL') script(type='text/javascript'). diff --git a/server/views/pages/admin/settings.pug b/server/views/pages/admin/settings.pug index ab0223c6..afba7807 100644 --- a/server/views/pages/admin/settings.pug +++ b/server/views/pages/admin/settings.pug @@ -3,38 +3,35 @@ extends ./_layout.pug block adminContent #page-type-admin-settings .hero - h1.title#title System Settings - h2.subtitle Manage site configuration + h1.title#title= t('nav.syssettings') + h2.subtitle= t('admin:settings.subtitle') .form-sections section img(src='/images/logo.png', style={width:'200px', float:'right'}) - label.label System Version + label.label= t('admin:settings.systemversion') .section-block - p Current Version: #[strong= sysversion.current] + p #{t('admin:settings.currentversion')}: #[strong= sysversion.current] if sysversion.latest - p Latest Version: #[strong= sysversion.latest] #[em (Published #{userMoment(sysversion.latestPublishedAt).fromNow()})] + p #{t('admin:settings.latestversion')}: #[strong= sysversion.latest] #[em (Published #{userMoment(sysversion.latestPublishedAt).fromNow()})] p if sysversion.current !== sysversion.latest - button.button.is-deep-orange(v-on:click='upgrade') Upgrade + button.button.is-deep-orange(v-on:click='upgrade')= t('admin:settings.upgrade') else - button.button.is-disabled Upgrade - button.button.is-deep-orange.is-outlined(v-on:click='reinstall') Re-install current version + button.button.is-disabled= t('admin:settings.upgrade') + button.button.is-deep-orange.is-outlined(v-on:click='reinstall')= t('admin:settings.reinstall') else - p: em Unable to query latest version. Try again later. + p: em= t('admin:settings.versioncheckfailed') section - label.label Administrative Tools + label.label= t('admin:settings.administrativetools') .section-block - h6 Flush cache and rebuild indexes: - p.is-small If content or search results seems out-of-date or do not include latest content, flushing the cache can help resolve these issues. - p: button.button.is-teal.is-outlined(v-on:click='flushcache') Flush and Rebuild - h6 Reset the root administrator and guest accounts to defaults: - p.is-small - | The root administrator account will be reset to the email address in the configuration file and the password will be reinitialized to #[strong admin123]. - br - | The guest account will be recreated with its access rights set to defaults. - p: button.button.is-teal.is-outlined(v-on:click='resetaccounts') Reset System Accounts - h6 Flush all active user sessions: - p.is-small All users will be logged out and forced to login again. Your current session will also be affected! - p: button.button.is-teal.is-outlined(v-on:click='flushsessions') Flush Sessions + h6 #{t('admin:settings.flushcache')}: + p.is-small= t('admin:settings.flushcachetext') + p: button.button.is-teal.is-outlined(v-on:click='flushcache')= t('admin:settings.flushcachebtn') + h6 #{t('admin:settings.resetaccounts')}: + p.is-small= t('admin:settings.resetaccountstext') + p: button.button.is-teal.is-outlined(v-on:click='resetaccounts')= t('admin:settings.resetaccountsbtn') + h6 #{t('admin:settings.flushsessions')}: + p.is-small= t('admin:settings.flushsessionstext') + p: button.button.is-teal.is-outlined(v-on:click='flushsessions')= t('admin:settings.flushsessionsbtn') include ../../modals/admin-upgrade.pug diff --git a/server/views/pages/admin/stats.pug b/server/views/pages/admin/stats.pug index 485289ea..67df36c2 100644 --- a/server/views/pages/admin/stats.pug +++ b/server/views/pages/admin/stats.pug @@ -2,13 +2,13 @@ extends ./_layout.pug block adminContent .hero - h1.title#title Stats - h2.subtitle General site-wide statistics + h1.title#title= t('nav.stats') + h2.subtitle= t('admin:stats.subtitle') .form-sections section - label.label Entries + label.label= t('admin:stats.entries') p.control= totalEntries - label.label Uploads + label.label= t('admin:stats.uploads') p.control= totalUploads - label.label Users + label.label= t('admin:stats.users') p.control= totalUsers diff --git a/server/views/pages/admin/users-edit.pug b/server/views/pages/admin/users-edit.pug index c2e7a3c3..1c777a37 100644 --- a/server/views/pages/admin/users-edit.pug +++ b/server/views/pages/admin/users-edit.pug @@ -5,66 +5,51 @@ block rootNavRight .nav-item a.button(href='/admin/users') i.icon-reply - span Return to Users + span= t('admin:users.returntousers') block adminContent #page-type-admin-users-edit .hero - h1.title#title Edit User + h1.title#title= t('admin:users.edituser') h2.subtitle= usr.email table.table thead tr - th Unique ID - th Provider - th Created On - th Updated On + th= t('admin:users.uniqueid') + th= t('admin:users.provider') + th= t('admin:users.createdon') + th= t('admin:users.updatedon') tbody tr td.is-centered= usr._id td.is-centered.has-icons case usr.provider - when 'local' - i.icon-server.is-deep-orange - | Local Database - when 'windowslive' - i.icon-windows2.is-blue - | Microsoft Account - when 'azure' - i.icon-windows2.is-blue - | Azure Active Directory - when 'google' - i.icon-google.is-blue - | Google ID - when 'facebook' - i.icon-facebook.is-indigo - | Facebook - when 'github' - i.icon-github.is-blue-grey - | GitHub - when 'slack' - i.icon-slack.is-purple - | Slack - when 'ldap' - i.icon-arrow-repeat-outline - | LDAP / Active Directory + when 'local': i.icon-server + when 'windowslive': i.icon-windows2.is-blue + when 'azure': i.icon-windows2.is-blue + when 'google': i.icon-google.is-blue + when 'facebook': i.icon-facebook.is-indigo + when 'github': i.icon-github.is-grey + when 'slack': i.icon-slack.is-purple + when 'ldap': i.icon-arrow-repeat-outline default: i.icon-warning + = t('auth:providers.' + usr.provider) td.is-centered= userMoment(usr.createdAt).format('lll') td.is-centered= userMoment(usr.updatedAt).format('lll') .form-sections section - label.label Email Address + label.label= t('admin:profile.email') p.control.is-fullwidth input.input(type='text', placeholder='john.smith@example.com', v-model='email', disabled=!usrOpts.canChangeEmail) section - label.label Display Name + label.label= t('admin:profile.displayname') p.control.is-fullwidth - input.input(type='text', placeholder='John Smith', v-model='name', disabled=!usrOpts.canChangeName) + input.input(type='text', placeholder=t('admin:profile.displaynameexample'), v-model='name', disabled=!usrOpts.canChangeName) if usrOpts.canChangePassword section - label.label Password + label.label= t('admin:profile.password') p.control.is-fullwidth - input.input(type='password', placeholder='Password', v-model='password', value='********') + input.input(type='password', placeholder=t('admin:profile.password'), v-model='password', value='********') section label.label Access Rights table.table diff --git a/server/views/pages/admin/users.pug b/server/views/pages/admin/users.pug index 5d250f38..251641f9 100644 --- a/server/views/pages/admin/users.pug +++ b/server/views/pages/admin/users.pug @@ -5,22 +5,22 @@ block rootNavRight .nav-item a.button.btn-create-prompt i.icon-plus - span Create / Authorize User + span= t('admin:users.createauthorize') block adminContent #page-type-admin-users .hero - h1.title#title Users - h2.subtitle Manage users and access rights + h1.title#title= t('nav.users') + h2.subtitle= t('admin:users.subtitle') table.table thead tr th - th Name - th Email - th Provider - th Created On - th Updated On + th= t('admin:users.name') + th= t('admin:users.email') + th= t('admin:users.provider') + th= t('admin:users.createdon') + th= t('admin:users.updatedon') tbody each usr in usrs tr @@ -31,31 +31,16 @@ block adminContent td= usr.email td.is-centered.has-icons case usr.provider - when 'local' - i.icon-server.is-deep-orange - | Local Database - when 'windowslive' - i.icon-windows2.is-blue - | Microsoft Account - when 'azure' - i.icon-windows2.is-blue - | Azure Active Directory - when 'google' - i.icon-google.is-blue - | Google ID - when 'facebook' - i.icon-facebook.is-purple - | Facebook - when 'github' - i.icon-github.is-blue-grey - | GitHub - when 'slack' - i.icon-slack.is-purple - | Slack - when 'ldap' - i.icon-arrow-repeat-outline - | LDAP / Active Directory + when 'local': i.icon-server + when 'windowslive': i.icon-windows2.is-blue + when 'azure': i.icon-windows2.is-blue + when 'google': i.icon-google.is-blue + when 'facebook': i.icon-facebook.is-indigo + when 'github': i.icon-github.is-grey + when 'slack': i.icon-slack.is-purple + when 'ldap': i.icon-arrow-repeat-outline default: i.icon-warning + = t('auth:providers.' + usr.provider) td.is-centered= userMoment(usr.createdAt).format('lll') td.is-centered= userMoment(usr.updatedAt).format('lll')