Browse Source

feat: Views localization

NGPixel 8 years ago
parent
commit
40c4ff80f4

+ 8 - 8
server/libs/entries.js

@@ -155,7 +155,7 @@ module.exports = {
         return false
         return false
       }
       }
     }).catch((err) => { // eslint-disable-line handle-callback-err
     }).catch((err) => { // eslint-disable-line handle-callback-err
-      throw new Promise.OperationalError('Entry ' + entryPath + ' does not exist!')
+      throw new Promise.OperationalError(lang.t('errors:notexist', { path: entryPath }))
     })
     })
   },
   },
 
 
@@ -184,11 +184,11 @@ module.exports = {
             }
             }
           })
           })
         } else {
         } else {
-          return Promise.reject(new Error('Parent entry is not a valid file.'))
+          return Promise.reject(new Error(lang.t('errors:parentinvalid')))
         }
         }
       })
       })
     } else {
     } else {
-      return Promise.reject(new Error('Parent entry is root.'))
+      return Promise.reject(new Error(lang.t('errors:parentisroot')))
     }
     }
   },
   },
 
 
@@ -212,11 +212,11 @@ module.exports = {
           })
           })
         })
         })
       } else {
       } else {
-        return Promise.reject(new Error('Entry does not exist!'))
+        return Promise.reject(new Error(lang.t('errors:notexist', { path: entryPath }))
       }
       }
     }).catch((err) => {
     }).catch((err) => {
       winston.error(err)
       winston.error(err)
-      return Promise.reject(new Error('Failed to save document.'))
+      return Promise.reject(new Error(lang.t('errors:savefailed')))
     })
     })
   },
   },
 
 
@@ -316,11 +316,11 @@ module.exports = {
           })
           })
         })
         })
       } else {
       } else {
-        return Promise.reject(new Error('Entry already exists!'))
+        return Promise.reject(new Error(lang.t('errors:alreadyexists')))
       }
       }
     }).catch((err) => {
     }).catch((err) => {
       winston.error(err)
       winston.error(err)
-      return Promise.reject(new Error('Something went wrong.'))
+      return Promise.reject(new Error(lang.t('errors:generic')))
     })
     })
   },
   },
 
 
@@ -352,7 +352,7 @@ module.exports = {
     let self = this
     let self = this
 
 
     if (_.isEmpty(entryPath) || entryPath === 'home') {
     if (_.isEmpty(entryPath) || entryPath === 'home') {
-      return Promise.reject(new Error('Invalid path!'))
+      return Promise.reject(new Error(lang.t('errors:invalidpath')))
     }
     }
 
 
     return git.moveDocument(entryPath, newEntryPath).then(() => {
     return git.moveDocument(entryPath, newEntryPath).then(() => {

+ 1 - 1
server/libs/git.js

@@ -206,7 +206,7 @@ module.exports = {
       let out = cProc.stdout.toString()
       let out = cProc.stdout.toString()
       return _.includes(out, gitFilePath)
       return _.includes(out, gitFilePath)
     }).then((isTracked) => {
     }).then((isTracked) => {
-      commitMsg = (isTracked) ? 'Updated ' + gitFilePath : 'Added ' + gitFilePath
+      commitMsg = (isTracked) ? lang.t('git:updated', { path: gitFilePath }) : lang.t('git:added', { path: gitFilePath })
       return self._git.add(gitFilePath)
       return self._git.add(gitFilePath)
     }).then(() => {
     }).then(() => {
       let commitUsr = securityHelper.sanitizeCommitUser(author)
       let commitUsr = securityHelper.sanitizeCommitUser(author)

+ 1 - 1
server/libs/local.js

@@ -163,7 +163,7 @@ module.exports = {
     let fpath = path.resolve(this._uploadsPath, fld, f)
     let fpath = path.resolve(this._uploadsPath, fld, f)
 
 
     return fs.statAsync(fpath).then((s) => {
     return fs.statAsync(fpath).then((s) => {
-      throw new Error('File ' + f + ' already exists.')
+      throw new Error(lang.t('errors:fileexists', { path: f }))
     }).catch((err) => {
     }).catch((err) => {
       if (err.code === 'ENOENT') {
       if (err.code === 'ENOENT') {
         return f
         return f

+ 2 - 2
server/libs/uploads-agent.js

@@ -59,14 +59,14 @@ module.exports = {
       return self.processFile(pInfo.folder, pInfo.filename).then((mData) => {
       return self.processFile(pInfo.folder, pInfo.filename).then((mData) => {
         return db.UplFile.findByIdAndUpdate(mData._id, mData, { upsert: true })
         return db.UplFile.findByIdAndUpdate(mData._id, mData, { upsert: true })
       }).then(() => {
       }).then(() => {
-        return git.commitUploads('Uploaded ' + p)
+        return git.commitUploads(lang.t('git:uploaded', { path: p }))
       })
       })
     })
     })
 
 
     // -> Remove upload file
     // -> Remove upload file
 
 
     self._watcher.on('unlink', (p) => {
     self._watcher.on('unlink', (p) => {
-      return git.commitUploads('Deleted/Renamed ' + p)
+      return git.commitUploads(lang.t('git:deleted', { path: p }))
     })
     })
   },
   },
 
 

+ 4 - 4
server/libs/uploads.js

@@ -168,7 +168,7 @@ module.exports = {
 
 
     return upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
     return upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
       if (!destFolderPath) {
       if (!destFolderPath) {
-        return Promise.reject(new Error('Invalid Folder'))
+        return Promise.reject(new Error(lang.t('errors:invalidfolder')))
       }
       }
 
 
       return lcdata.validateUploadsFilename(fUrlFilename, destFolder).then((destFilename) => {
       return lcdata.validateUploadsFilename(fUrlFilename, destFolder).then((destFilename) => {
@@ -192,7 +192,7 @@ module.exports = {
               rq.abort()
               rq.abort()
               destFileStream.destroy()
               destFileStream.destroy()
               fs.remove(destFilePath)
               fs.remove(destFilePath)
-              reject(new Error('Remote file is too large!'))
+              reject(new Error(lang.t('errors:remotetoolarge')))
             }
             }
           }).on('error', (err) => {
           }).on('error', (err) => {
             destFileStream.destroy()
             destFileStream.destroy()
@@ -243,7 +243,7 @@ module.exports = {
             // -> Check for invalid operations
             // -> Check for invalid operations
 
 
             if (sourceFilePath === destFilePath) {
             if (sourceFilePath === destFilePath) {
-              return Promise.reject(new Error('Invalid Operation!'))
+              return Promise.reject(new Error(lang.t('errors:invalidoperation')))
             }
             }
 
 
             // -> Delete DB entry
             // -> Delete DB entry
@@ -271,7 +271,7 @@ module.exports = {
           })
           })
         })
         })
       } else {
       } else {
-        return Promise.reject(new Error('Invalid Destination Folder'))
+        return Promise.reject(new Error(lang.t('errors:invaliddestfolder')))
       }
       }
     })
     })
   }
   }

+ 2 - 0
server/locales/en/auth.json

@@ -12,7 +12,9 @@
   "errors": {
   "errors": {
     "invalidlogin": "Invalid Login",
     "invalidlogin": "Invalid Login",
     "invalidloginmsg": "The email or password is invalid.",
     "invalidloginmsg": "The email or password is invalid.",
+    "invaliduseremail": "Invalid User Email",
     "loginerror": "Login error",
     "loginerror": "Login error",
+    "notyetauthorized": "You have not been authorized to login to this site yet.",
     "toomanyattempts": "Too many attempts!",
     "toomanyattempts": "Too many attempts!",
     "toomanyattemptsmsg": "You've made too many failed attempts in a short period of time, please try again {{time}}.",
     "toomanyattemptsmsg": "You've made too many failed attempts in a short period of time, please try again {{time}}.",
     "usernotfound": "User not found"
     "usernotfound": "User not found"

+ 46 - 3
server/locales/en/common.json

@@ -1,11 +1,54 @@
 {
 {
   "wiki": "Wiki",
   "wiki": "Wiki",
-  "headers": {
-    "overview": "Overview"
+  "header": {
+    "overview": "Overview",
+    "createdoc": "Create New Document"
   },
   },
   "footer": {
   "footer": {
     "poweredby": "Powered by",
     "poweredby": "Powered by",
     "home": "Home",
     "home": "Home",
     "top": "Return to top"
     "top": "Return to top"
+  },
+  "search": {
+    "placeholder": "Search...",
+    "results": "Search Results",
+    "nomatch": "No results matching your query",
+    "didyoumean": "Did you mean...?"
+  },
+  "sidebar": {
+    "nav": "NAV",
+    "navigation": "Navigation",
+    "pagecontents": "Page Contents",
+    "pastversions": "Past Versions"
+  },
+  "nav": {
+    "home": "Home",
+    "account": "Account",
+    "myprofile": "My Profile",
+    "stats": "Stats",
+    "syssettings": "System Settings",
+    "users": "Users",
+    "logout": "Logout",
+    "create": "Create",
+    "edit": "Edit",
+    "history": "History",
+    "source": "Source",
+    "move": "Move",
+    "allpages": "All Pages",
+    "login": "Login",
+    "normalview": "Normal View",
+    "viewlatest": "View Latest",
+    "discard": "Discard",
+    "savechanges": "Save Changes",
+    "savedocument": "Save Document"
+  },
+  "welcome": {
+    "title": "Welcome to your wiki!",
+    "subtitle": "Let's get started and create the home page.",
+    "createhome": "Create Home Page"
+  },
+  "loading": {
+    "source": "Loading source...",
+    "editor": "Loading editor..."
   }
   }
-}
+}

+ 8 - 0
server/locales/en/errors.json

@@ -1,17 +1,25 @@
 {
 {
   "alreadyexists": "This entry already exists!",
   "alreadyexists": "This entry already exists!",
   "debugmsg": "Detailed debug trail",
   "debugmsg": "Detailed debug trail",
+  "fileexists": "File {{path}} already exists.",
   "forbidden": "Forbidden",
   "forbidden": "Forbidden",
   "forbiddendetail": "Sorry, you don't have the necessary permissions to access this page.",
   "forbiddendetail": "Sorry, you don't have the necessary permissions to access this page.",
   "generic": "Oops, something went wrong",
   "generic": "Oops, something went wrong",
   "invalidaction": "Invalid Action.",
   "invalidaction": "Invalid Action.",
+  "invaliddestfolder": "Invalid Destination Folder!",
   "invalidfiletype": "Invalid File Type.",
   "invalidfiletype": "Invalid File Type.",
   "invalidfolder": "Invalid Folder.",
   "invalidfolder": "Invalid Folder.",
+  "invalidoperation": "Invalid Operation!",
   "invalidpath": "Invalid page path.",
   "invalidpath": "Invalid page path.",
   "invaliduserid": "Invalid User Id",
   "invaliduserid": "Invalid User Id",
   "newpasswordtooshort": "New password is too short!",
   "newpasswordtooshort": "New password is too short!",
+  "notexist": "Entry {{path}} does not exist!",
   "notexistdetail": "Would you like to create this entry?",
   "notexistdetail": "Would you like to create this entry?",
+  "parentinvalid": "Parent entry is not a valid file.",
+  "parentisroot": "Parent entry is root.",
+  "remotetoolarge": "Remote file is too large!",
   "reservedname": "You cannot create a document with this name as it is reserved by the system.",
   "reservedname": "You cannot create a document with this name as it is reserved by the system.",
+  "savefailed": "Failed to save document",
   "starterfailed": "Could not load starter content!",
   "starterfailed": "Could not load starter content!",
   "unauthorized": "Unauthorized",
   "unauthorized": "Unauthorized",
   "actions": {
   "actions": {

+ 6 - 0
server/locales/en/git.json

@@ -0,0 +1,6 @@
+{
+  "added": "Added {{path}}",
+  "deleted": "Deleted/Renamed {{path}}",
+  "updated": "Updated {{path}}",
+  "uploaded": "Uplodated {{path}}"
+}

+ 3 - 3
server/models/user.js

@@ -55,7 +55,7 @@ userSchema.statics.processProfile = (profile) => {
   } else if (profile.user && profile.user.email && profile.user.email.length > 5) {
   } else if (profile.user && profile.user.email && profile.user.email.length > 5) {
     primaryEmail = profile.user.email
     primaryEmail = profile.user.email
   } else {
   } else {
-    return Promise.reject(new Error('Invalid User Email'))
+    return Promise.reject(new Error(lang.t('auth:errors.invaliduseremail')))
   }
   }
 
 
   profile.provider = _.lowerCase(profile.provider)
   profile.provider = _.lowerCase(profile.provider)
@@ -89,7 +89,7 @@ userSchema.statics.processProfile = (profile) => {
       }
       }
       return db.User.create(nUsr)
       return db.User.create(nUsr)
     }
     }
-    return user || Promise.reject(new Error('You have not been authorized to login to this site yet.'))
+    return user || Promise.reject(new Error(lang.t('auth:errors:notyetauthorized')))
   })
   })
 }
 }
 
 
@@ -99,7 +99,7 @@ userSchema.statics.hashPassword = (rawPwd) => {
 
 
 userSchema.methods.validatePassword = function (rawPwd) {
 userSchema.methods.validatePassword = function (rawPwd) {
   return bcrypt.compare(rawPwd, this.password).then((isValid) => {
   return bcrypt.compare(rawPwd, this.password).then((isValid) => {
-    return (isValid) ? true : Promise.reject(new Error('Invalid Login'))
+    return (isValid) ? true : Promise.reject(new Error(lang.t('auth:errors:invalidlogin')))
   })
   })
 }
 }
 
 

+ 4 - 4
server/views/common/header.pug

@@ -11,7 +11,7 @@
       block rootNavCenter
       block rootNavCenter
         .nav-item
         .nav-item
           p.control(v-bind:class='{ "is-loading": searchload > 0 }')
           p.control(v-bind:class='{ "is-loading": searchload > 0 }')
-            input.input#search-input(type='text', v-model='searchq', @keyup.esc='closeSearch', @keyup.down='moveDownSearch', @keyup.up='moveUpSearch', @keyup.enter='moveSelectSearch', debounce='400', placeholder='Search...')
+            input.input#search-input(type='text', v-model='searchq', @keyup.esc='closeSearch', @keyup.down='moveDownSearch', @keyup.up='moveUpSearch', @keyup.enter='moveSelectSearch', debounce='400', placeholder=t('search.placeholder'))
     span.nav-toggle
     span.nav-toggle
       span
       span
       span
       span
@@ -22,13 +22,13 @@
 
 
   transition(name='searchresults-anim', enter-active-class='slideInDown', leave-active-class='fadeOutUp')
   transition(name='searchresults-anim', enter-active-class='slideInDown', leave-active-class='fadeOutUp')
     .searchresults.animated(v-show='searchactive', v-cloak, style={'display':'none'})
     .searchresults.animated(v-show='searchactive', v-cloak, style={'display':'none'})
-      p.searchresults-label Search Results
+      p.searchresults-label= t('search.results')
       ul.searchresults-list
       ul.searchresults-list
         li(v-if='searchres.length === 0')
         li(v-if='searchres.length === 0')
-          a: em No results matching your query
+          a: em= t('search.nomatch')
         li(v-for='sres in searchres', v-bind:class='{ "is-active": searchmovekey === "res." + sres.entryPath }')
         li(v-for='sres in searchres', v-bind:class='{ "is-active": searchmovekey === "res." + sres.entryPath }')
           a(v-bind:href='"/" + sres.entryPath') {{ sres.title }}
           a(v-bind:href='"/" + sres.entryPath') {{ sres.title }}
-      p.searchresults-label(v-if='searchsuggest.length > 0') Did you mean...?
+      p.searchresults-label(v-if='searchsuggest.length > 0')= t('search.didyoumean')
       ul.searchresults-list(v-if='searchsuggest.length > 0')
       ul.searchresults-list(v-if='searchsuggest.length > 0')
         li(v-for='sug in searchsuggest', v-bind:class='{ "is-active": searchmovekey === "sug." + sug }')
         li(v-for='sug in searchsuggest', v-bind:class='{ "is-active": searchmovekey === "sug." + sug }')
           a(v-on:click='useSuggestion(sug)') {{ sug }}
           a(v-on:click='useSuggestion(sug)') {{ sug }}

+ 10 - 10
server/views/pages/admin/_layout.pug

@@ -1,14 +1,14 @@
 extends ../../layout.pug
 extends ../../layout.pug
 
 
 block rootNavCenter
 block rootNavCenter
-  h2.nav-item Account
+  h2.nav-item= t('nav.account')
 
 
 block rootNavRight
 block rootNavRight
   i.nav-item#notifload
   i.nav-item#notifload
   .nav-item
   .nav-item
     a.button.btn-edit-discard(href='/')
     a.button.btn-edit-discard(href='/')
       i.icon-home
       i.icon-home
-      span Home
+      span= t('nav.home')
 
 
 block content
 block content
 
 
@@ -20,38 +20,38 @@ block content
 
 
           aside
           aside
             .sidebar-label
             .sidebar-label
-              span Navigation
+              span= t('sidebar.navigation')
             ul.sidebar-menu
             ul.sidebar-menu
               li
               li
                 a(href='/')
                 a(href='/')
                   i.icon-home
                   i.icon-home
-                  span Home
+                  span= t('nav.home')
 
 
           aside
           aside
             .sidebar-label
             .sidebar-label
-              span Account
+              span= t('nav.account')
             ul.sidebar-menu
             ul.sidebar-menu
               li
               li
                 a(href='/admin/profile')
                 a(href='/admin/profile')
                   i.icon-user
                   i.icon-user
-                  span My Profile
+                  span= t('nav.myprofile')
               li
               li
                 a(href='/admin/stats')
                 a(href='/admin/stats')
                   i.icon-bar-graph-2
                   i.icon-bar-graph-2
-                  span Stats
+                  span= t('nav.stats')
               if rights.manage
               if rights.manage
                 li
                 li
                   a(href='/admin/users')
                   a(href='/admin/users')
                     i.icon-users
                     i.icon-users
-                    span Users
+                    span= t('nav.users')
                 li
                 li
                   a(href='/admin/settings')
                   a(href='/admin/settings')
                     i.icon-cog
                     i.icon-cog
-                    span System Settings
+                    span= t('nav.syssettings')
               li
               li
                 a(href='/logout')
                 a(href='/logout')
                   i.icon-delete2
                   i.icon-delete2
-                  span Logout
+                  span= t('nav.logout')
 
 
         .column
         .column
           block adminContent
           block adminContent

+ 5 - 5
server/views/pages/all.pug

@@ -10,22 +10,22 @@ block content
       .sidebar.is-collapsed
       .sidebar.is-collapsed
         aside
         aside
           .sidebar-label
           .sidebar-label
-            span NAV
+            span= t('sidebar.nav')
           ul.sidebar-menu
           ul.sidebar-menu
             li
             li
               a(href='/')
               a(href='/')
                 i.icon-home
                 i.icon-home
-                span Home
+                span= t('nav.home')
             if !isGuest
             if !isGuest
               li
               li
                 a(href='/admin')
                 a(href='/admin')
                   i.icon-head
                   i.icon-head
-                  span Account
+                  span= t('nav.account')
             else
             else
               li
               li
                 a(href='/login')
                 a(href='/login')
                   i.icon-unlock
                   i.icon-unlock
-                  span Login
+                  span= t('nav.login')
       ul.collapsable-nav(v-for='treeItem in tree', :class='{ "has-children": treeItem.hasChildren }', v-cloak)
       ul.collapsable-nav(v-for='treeItem in tree', :class='{ "has-children": treeItem.hasChildren }', v-cloak)
         li(v-for='page in treeItem.pages', :class='{ "is-active": page.isActive }')
         li(v-for='page in treeItem.pages', :class='{ "is-active": page.isActive }')
           a(v-on:click='mainAction(page)')
           a(v-on:click='mainAction(page)')
@@ -34,7 +34,7 @@ block content
               span {{ page.title }}
               span {{ page.title }}
             template(v-else)
             template(v-else)
               i.icon-home
               i.icon-home
-              span Home
+              span= t('nav.home')
           a.is-pagelink(v-if='page.isDirectory && page.isEntry', v-on:click='goto(page._id)')
           a.is-pagelink(v-if='page.isDirectory && page.isEntry', v-on:click='goto(page._id)')
             i.icon-file-text-o
             i.icon-file-text-o
             i.icon-arrow-right2
             i.icon-arrow-right2

+ 4 - 4
server/views/pages/create.pug

@@ -1,17 +1,17 @@
 extends ../layout.pug
 extends ../layout.pug
 
 
 block rootNavCenter
 block rootNavCenter
-  h2.nav-item Create New Document
+  h2.nav-item= t('header.createdoc')
 
 
 block rootNavRight
 block rootNavRight
   i.nav-item#notifload
   i.nav-item#notifload
   span.nav-item
   span.nav-item
     a.button.is-outlined.btn-create-discard
     a.button.is-outlined.btn-create-discard
       i.icon-cross
       i.icon-cross
-      span Discard
+      span= t('nav.discard')
     a.button.btn-create-save
     a.button.btn-create-save
       i.icon-check
       i.icon-check
-      span Save Document
+      span= t('nav.savedocument')
 
 
 block content
 block content
 
 
@@ -29,4 +29,4 @@ block content
 block outside
 block outside
   #page-loader
   #page-loader
     i
     i
-    span Loading editor...
+    span= t('loading.editor')

+ 3 - 3
server/views/pages/edit.pug

@@ -8,10 +8,10 @@ block rootNavRight
   span.nav-item
   span.nav-item
     a.button.is-outlined.btn-edit-discard
     a.button.is-outlined.btn-edit-discard
       i.icon-cross
       i.icon-cross
-      span Discard
+      span= t('nav.discard')
     a.button.btn-edit-save
     a.button.btn-edit-save
       i.icon-check
       i.icon-check
-      span Save Changes
+      span= t('nav.savechanges')
 
 
 block content
 block content
 
 
@@ -29,4 +29,4 @@ block content
 block outside
 block outside
   #page-loader
   #page-loader
     i
     i
-    span Loading editor...
+    span= t('loading.editor')

+ 2 - 2
server/views/pages/history.pug

@@ -5,7 +5,7 @@ block rootNavRight
   .nav-item
   .nav-item
     a.button(href='/' + pageData.meta._id)
     a.button(href='/' + pageData.meta._id)
       i.icon-circle-check
       i.icon-circle-check
-      span View Latest
+      span= t('nav.viewlatest')
 
 
 block content
 block content
 
 
@@ -17,7 +17,7 @@ block content
 
 
           aside.stickyscroll
           aside.stickyscroll
             .sidebar-label
             .sidebar-label
-              span Past versions
+              span= t('sidebar.pastversions')
             ul.sidebar-menu
             ul.sidebar-menu
               each item, index in pageData.history
               each item, index in pageData.history
                 - var itemDate = moment(item.date)
                 - var itemDate = moment(item.date)

+ 5 - 5
server/views/pages/source.pug

@@ -9,17 +9,17 @@ block rootNavRight
     if rights.write
     if rights.write
       a.button.is-outlined.btn-move-prompt.is-hidden
       a.button.is-outlined.btn-move-prompt.is-hidden
         i.icon-shuffle
         i.icon-shuffle
-        span Move
+        span= t('nav.move')
     a.button.is-outlined(href='/' + pageData.meta.path)
     a.button.is-outlined(href='/' + pageData.meta.path)
       i.icon-loader
       i.icon-loader
-      span Normal View
+      span= t('nav.normalview')
     if rights.write
     if rights.write
       a.button.is-orange(href='/edit/' + pageData.meta.path)
       a.button.is-orange(href='/edit/' + pageData.meta.path)
         i.fa.fa-edit
         i.fa.fa-edit
-        span Edit
+        span= t('nav.edit')
       a.button.is-blue.btn-create-prompt
       a.button.is-blue.btn-create-prompt
         i.fa.fa-plus
         i.fa.fa-plus
-        span Create
+        span= t('nav.create')
 
 
 block content
 block content
 
 
@@ -33,4 +33,4 @@ block content
 block outside
 block outside
   #page-loader
   #page-loader
     i
     i
-    span Loading source...
+    span= t('loading.source')

+ 11 - 11
server/views/pages/view.pug

@@ -14,20 +14,20 @@ block rootNavRight
     if rights.write
     if rights.write
       a.button.is-outlined.btn-move-prompt.is-hidden
       a.button.is-outlined.btn-move-prompt.is-hidden
         i.icon-shuffle
         i.icon-shuffle
-        span Move
+        span= t('nav.move')
     a.button.is-outlined(href='/source/' + pageData.meta.path)
     a.button.is-outlined(href='/source/' + pageData.meta.path)
       i.icon-loader
       i.icon-loader
-      span Source
+      span= t('nav.source')
     a.button.is-outlined(href='/hist/' + pageData.meta.path)
     a.button.is-outlined(href='/hist/' + pageData.meta.path)
       i.icon-clock
       i.icon-clock
-      span History
+      span= t('nav.history')
     if rights.write
     if rights.write
       a.button(href='/edit/' + pageData.meta.path)
       a.button(href='/edit/' + pageData.meta.path)
         i.icon-document-text
         i.icon-document-text
-        span Edit
+        span= t('nav.edit')
       a.button.btn-create-prompt
       a.button.btn-create-prompt
         i.icon-plus
         i.icon-plus
-        span Create
+        span= t('nav.create')
 
 
 block content
 block content
 
 
@@ -39,16 +39,16 @@ block content
 
 
           aside
           aside
             .sidebar-label
             .sidebar-label
-              span Navigation
+              span= t('sidebar.navigation')
             ul.sidebar-menu
             ul.sidebar-menu
               li
               li
                 a(href='/')
                 a(href='/')
                   i.icon-home
                   i.icon-home
-                  span Home
+                  span= t('nav.home')
               li
               li
                 a(href='/all')
                 a(href='/all')
                   i.icon-paper
                   i.icon-paper
-                  span All Pages
+                  span= t('nav.allpages')
               if pageData.parent
               if pageData.parent
                 li
                 li
                   a(href='/' + pageData.parent.path)
                   a(href='/' + pageData.parent.path)
@@ -58,15 +58,15 @@ block content
                 li
                 li
                   a(href='/admin')
                   a(href='/admin')
                     i.icon-head
                     i.icon-head
-                    span Account
+                    span= t('nav.account')
               else
               else
                 li
                 li
                   a(href='/login')
                   a(href='/login')
                     i.icon-unlock
                     i.icon-unlock
-                    span Login
+                    span= t('nav.login')
           aside.stickyscroll
           aside.stickyscroll
             .sidebar-label
             .sidebar-label
-              span Page Contents
+              span= t('sidebar.pagecontents')
             ul.sidebar-menu
             ul.sidebar-menu
               li.is-hidden-until-scroll: a(href='#root', title='Top of Page')
               li.is-hidden-until-scroll: a(href='#root', title='Top of Page')
                 i.icon-arrow-up2
                 i.icon-arrow-up2

+ 3 - 3
server/views/pages/welcome.pug

@@ -11,6 +11,6 @@ block content
     .container
     .container
       .welcome
       .welcome
         img(src='/images/logo.png', alt='Wiki.js')
         img(src='/images/logo.png', alt='Wiki.js')
-        h1 Welcome to your wiki!
-        h2 Let's get started and create the home page.
-        a.button.is-indigo(href='/create/home') Create Home Page
+        h1= t('welcome.title')
+        h2= t('welcome.subtitle')
+        a.button.is-indigo(href='/create/home')= t('welcome.createhome')