Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
40c4ff80
Commit
40c4ff80
authored
May 02, 2017
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: Views localization
parent
ea2d98c9
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
128 additions
and
70 deletions
+128
-70
entries.js
server/libs/entries.js
+8
-8
git.js
server/libs/git.js
+1
-1
local.js
server/libs/local.js
+1
-1
uploads-agent.js
server/libs/uploads-agent.js
+2
-2
uploads.js
server/libs/uploads.js
+4
-4
auth.json
server/locales/en/auth.json
+2
-0
common.json
server/locales/en/common.json
+46
-4
errors.json
server/locales/en/errors.json
+8
-0
git.json
server/locales/en/git.json
+6
-0
user.js
server/models/user.js
+3
-3
header.pug
server/views/common/header.pug
+4
-4
_layout.pug
server/views/pages/admin/_layout.pug
+10
-10
all.pug
server/views/pages/all.pug
+5
-5
create.pug
server/views/pages/create.pug
+4
-4
edit.pug
server/views/pages/edit.pug
+3
-3
history.pug
server/views/pages/history.pug
+2
-2
source.pug
server/views/pages/source.pug
+5
-5
view.pug
server/views/pages/view.pug
+11
-11
welcome.pug
server/views/pages/welcome.pug
+3
-3
No files found.
server/libs/entries.js
View file @
40c4ff80
...
...
@@ -155,7 +155,7 @@ module.exports = {
return
false
}
}).
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
{
return
Promise
.
reject
(
new
Error
(
'Parent entry is not a valid file.'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'errors:parentinvalid'
)
))
}
})
}
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
{
return
Promise
.
reject
(
new
Error
(
'Entry does not exist!'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'errors:notexist'
,
{
path
:
entryPath
}
))
}
}).
catch
((
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
{
return
Promise
.
reject
(
new
Error
(
'Entry already exists!'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'errors:alreadyexists'
)
))
}
}).
catch
((
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
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
(()
=>
{
...
...
server/libs/git.js
View file @
40c4ff80
...
...
@@ -206,7 +206,7 @@ module.exports = {
let
out
=
cProc
.
stdout
.
toString
()
return
_
.
includes
(
out
,
gitFilePath
)
}).
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
)
}).
then
(()
=>
{
let
commitUsr
=
securityHelper
.
sanitizeCommitUser
(
author
)
...
...
server/libs/local.js
View file @
40c4ff80
...
...
@@ -163,7 +163,7 @@ module.exports = {
let
fpath
=
path
.
resolve
(
this
.
_uploadsPath
,
fld
,
f
)
return
fs
.
statAsync
(
fpath
).
then
((
s
)
=>
{
throw
new
Error
(
'File '
+
f
+
' already exists.'
)
throw
new
Error
(
lang
.
t
(
'errors:fileexists'
,
{
path
:
f
})
)
}).
catch
((
err
)
=>
{
if
(
err
.
code
===
'ENOENT'
)
{
return
f
...
...
server/libs/uploads-agent.js
View file @
40c4ff80
...
...
@@ -59,14 +59,14 @@ module.exports = {
return
self
.
processFile
(
pInfo
.
folder
,
pInfo
.
filename
).
then
((
mData
)
=>
{
return
db
.
UplFile
.
findByIdAndUpdate
(
mData
.
_id
,
mData
,
{
upsert
:
true
})
}).
then
(()
=>
{
return
git
.
commitUploads
(
'Uploaded '
+
p
)
return
git
.
commitUploads
(
lang
.
t
(
'git:uploaded'
,
{
path
:
p
})
)
})
})
// -> Remove upload file
self
.
_watcher
.
on
(
'unlink'
,
(
p
)
=>
{
return
git
.
commitUploads
(
'Deleted/Renamed '
+
p
)
return
git
.
commitUploads
(
lang
.
t
(
'git:deleted'
,
{
path
:
p
})
)
})
},
...
...
server/libs/uploads.js
View file @
40c4ff80
...
...
@@ -168,7 +168,7 @@ module.exports = {
return
upl
.
validateUploadsFolder
(
destFolder
).
then
((
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
)
=>
{
...
...
@@ -192,7 +192,7 @@ module.exports = {
rq
.
abort
()
destFileStream
.
destroy
()
fs
.
remove
(
destFilePath
)
reject
(
new
Error
(
'Remote file is too large!'
))
reject
(
new
Error
(
lang
.
t
(
'errors:remotetoolarge'
)
))
}
}).
on
(
'error'
,
(
err
)
=>
{
destFileStream
.
destroy
()
...
...
@@ -243,7 +243,7 @@ module.exports = {
// -> Check for invalid operations
if
(
sourceFilePath
===
destFilePath
)
{
return
Promise
.
reject
(
new
Error
(
'Invalid Operation!'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'errors:invalidoperation'
)
))
}
// -> Delete DB entry
...
...
@@ -271,7 +271,7 @@ module.exports = {
})
})
}
else
{
return
Promise
.
reject
(
new
Error
(
'Invalid Destination Folder'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'errors:invaliddestfolder'
)
))
}
})
}
...
...
server/locales/en/auth.json
View file @
40c4ff80
...
...
@@ -12,7 +12,9 @@
"errors"
:
{
"invalidlogin"
:
"Invalid Login"
,
"invalidloginmsg"
:
"The email or password is invalid."
,
"invaliduseremail"
:
"Invalid User Email"
,
"loginerror"
:
"Login error"
,
"notyetauthorized"
:
"You have not been authorized to login to this site yet."
,
"toomanyattempts"
:
"Too many attempts!"
,
"toomanyattemptsmsg"
:
"You've made too many failed attempts in a short period of time, please try again {{time}}."
,
"usernotfound"
:
"User not found"
...
...
server/locales/en/common.json
View file @
40c4ff80
{
"wiki"
:
"Wiki"
,
"headers"
:
{
"overview"
:
"Overview"
"header"
:
{
"overview"
:
"Overview"
,
"createdoc"
:
"Create New Document"
},
"footer"
:
{
"poweredby"
:
"Powered by"
,
"home"
:
"Home"
,
"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..."
}
}
\ No newline at end of file
}
server/locales/en/errors.json
View file @
40c4ff80
{
"alreadyexists"
:
"This entry already exists!"
,
"debugmsg"
:
"Detailed debug trail"
,
"fileexists"
:
"File {{path}} already exists."
,
"forbidden"
:
"Forbidden"
,
"forbiddendetail"
:
"Sorry, you don't have the necessary permissions to access this page."
,
"generic"
:
"Oops, something went wrong"
,
"invalidaction"
:
"Invalid Action."
,
"invaliddestfolder"
:
"Invalid Destination Folder!"
,
"invalidfiletype"
:
"Invalid File Type."
,
"invalidfolder"
:
"Invalid Folder."
,
"invalidoperation"
:
"Invalid Operation!"
,
"invalidpath"
:
"Invalid page path."
,
"invaliduserid"
:
"Invalid User Id"
,
"newpasswordtooshort"
:
"New password is too short!"
,
"notexist"
:
"Entry {{path}} does not exist!"
,
"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."
,
"savefailed"
:
"Failed to save document"
,
"starterfailed"
:
"Could not load starter content!"
,
"unauthorized"
:
"Unauthorized"
,
"actions"
:
{
...
...
server/locales/en/git.json
0 → 100644
View file @
40c4ff80
{
"added"
:
"Added {{path}}"
,
"deleted"
:
"Deleted/Renamed {{path}}"
,
"updated"
:
"Updated {{path}}"
,
"uploaded"
:
"Uplodated {{path}}"
}
server/models/user.js
View file @
40c4ff80
...
...
@@ -55,7 +55,7 @@ userSchema.statics.processProfile = (profile) => {
}
else
if
(
profile
.
user
&&
profile
.
user
.
email
&&
profile
.
user
.
email
.
length
>
5
)
{
primaryEmail
=
profile
.
user
.
email
}
else
{
return
Promise
.
reject
(
new
Error
(
'Invalid User Email'
))
return
Promise
.
reject
(
new
Error
(
lang
.
t
(
'auth:errors.invaliduseremail'
)
))
}
profile
.
provider
=
_
.
lowerCase
(
profile
.
provider
)
...
...
@@ -89,7 +89,7 @@ userSchema.statics.processProfile = (profile) => {
}
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
)
{
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'
)
))
})
}
...
...
server/views/common/header.pug
View file @
40c4ff80
...
...
@@ -11,7 +11,7 @@
block rootNavCenter
.nav-item
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
span
...
...
@@ -22,13 +22,13 @@
transition(name='searchresults-anim', enter-active-class='slideInDown', leave-active-class='fadeOutUp')
.searchresults.animated(v-show='searchactive', v-cloak, style={'display':'none'})
p.searchresults-label
Search Results
p.searchresults-label
= t('search.results')
ul.searchresults-list
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 }')
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')
li(v-for='sug in searchsuggest', v-bind:class='{ "is-active": searchmovekey === "sug." + sug }')
a(v-on:click='useSuggestion(sug)') {{ sug }}
server/views/pages/admin/_layout.pug
View file @
40c4ff80
extends ../../layout.pug
block rootNavCenter
h2.nav-item
Account
h2.nav-item
= t('nav.account')
block rootNavRight
i.nav-item#notifload
.nav-item
a.button.btn-edit-discard(href='/')
i.icon-home
span
Home
span
= t('nav.home')
block content
...
...
@@ -20,38 +20,38 @@ block content
aside
.sidebar-label
span
Navigation
span
= t('sidebar.navigation')
ul.sidebar-menu
li
a(href='/')
i.icon-home
span
Home
span
= t('nav.home')
aside
.sidebar-label
span
Account
span
= t('nav.account')
ul.sidebar-menu
li
a(href='/admin/profile')
i.icon-user
span
My Profile
span
= t('nav.myprofile')
li
a(href='/admin/stats')
i.icon-bar-graph-2
span
Stats
span
= t('nav.stats')
if rights.manage
li
a(href='/admin/users')
i.icon-users
span
Users
span
= t('nav.users')
li
a(href='/admin/settings')
i.icon-cog
span
System Settings
span
= t('nav.syssettings')
li
a(href='/logout')
i.icon-delete2
span
Logout
span
= t('nav.logout')
.column
block adminContent
server/views/pages/all.pug
View file @
40c4ff80
...
...
@@ -10,22 +10,22 @@ block content
.sidebar.is-collapsed
aside
.sidebar-label
span
NAV
span
= t('sidebar.nav')
ul.sidebar-menu
li
a(href='/')
i.icon-home
span
Home
span
= t('nav.home')
if !isGuest
li
a(href='/admin')
i.icon-head
span
Account
span
= t('nav.account')
else
li
a(href='/login')
i.icon-unlock
span
Login
span
= t('nav.login')
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 }')
a(v-on:click='mainAction(page)')
...
...
@@ -34,7 +34,7 @@ block content
span {{ page.title }}
template(v-else)
i.icon-home
span
Home
span
= t('nav.home')
a.is-pagelink(v-if='page.isDirectory && page.isEntry', v-on:click='goto(page._id)')
i.icon-file-text-o
i.icon-arrow-right2
server/views/pages/create.pug
View file @
40c4ff80
extends ../layout.pug
block rootNavCenter
h2.nav-item
Create New Document
h2.nav-item
= t('header.createdoc')
block rootNavRight
i.nav-item#notifload
span.nav-item
a.button.is-outlined.btn-create-discard
i.icon-cross
span
Discard
span
= t('nav.discard')
a.button.btn-create-save
i.icon-check
span
Save Document
span
= t('nav.savedocument')
block content
...
...
@@ -29,4 +29,4 @@ block content
block outside
#page-loader
i
span
Loading editor...
span
= t('loading.editor')
server/views/pages/edit.pug
View file @
40c4ff80
...
...
@@ -8,10 +8,10 @@ block rootNavRight
span.nav-item
a.button.is-outlined.btn-edit-discard
i.icon-cross
span
Discard
span
= t('nav.discard')
a.button.btn-edit-save
i.icon-check
span
Save Changes
span
= t('nav.savechanges')
block content
...
...
@@ -29,4 +29,4 @@ block content
block outside
#page-loader
i
span
Loading editor...
span
= t('loading.editor')
server/views/pages/history.pug
View file @
40c4ff80
...
...
@@ -5,7 +5,7 @@ block rootNavRight
.nav-item
a.button(href='/' + pageData.meta._id)
i.icon-circle-check
span
View Latest
span
= t('nav.viewlatest')
block content
...
...
@@ -17,7 +17,7 @@ block content
aside.stickyscroll
.sidebar-label
span
Past versions
span
= t('sidebar.pastversions')
ul.sidebar-menu
each item, index in pageData.history
- var itemDate = moment(item.date)
...
...
server/views/pages/source.pug
View file @
40c4ff80
...
...
@@ -9,17 +9,17 @@ block rootNavRight
if rights.write
a.button.is-outlined.btn-move-prompt.is-hidden
i.icon-shuffle
span
Move
span
= t('nav.move')
a.button.is-outlined(href='/' + pageData.meta.path)
i.icon-loader
span
Normal View
span
= t('nav.normalview')
if rights.write
a.button.is-orange(href='/edit/' + pageData.meta.path)
i.fa.fa-edit
span
Edit
span
= t('nav.edit')
a.button.is-blue.btn-create-prompt
i.fa.fa-plus
span
Create
span
= t('nav.create')
block content
...
...
@@ -33,4 +33,4 @@ block content
block outside
#page-loader
i
span
Loading source...
span
= t('loading.source')
server/views/pages/view.pug
View file @
40c4ff80
...
...
@@ -14,20 +14,20 @@ block rootNavRight
if rights.write
a.button.is-outlined.btn-move-prompt.is-hidden
i.icon-shuffle
span
Move
span
= t('nav.move')
a.button.is-outlined(href='/source/' + pageData.meta.path)
i.icon-loader
span
Source
span
= t('nav.source')
a.button.is-outlined(href='/hist/' + pageData.meta.path)
i.icon-clock
span
History
span
= t('nav.history')
if rights.write
a.button(href='/edit/' + pageData.meta.path)
i.icon-document-text
span
Edit
span
= t('nav.edit')
a.button.btn-create-prompt
i.icon-plus
span
Create
span
= t('nav.create')
block content
...
...
@@ -39,16 +39,16 @@ block content
aside
.sidebar-label
span
Navigation
span
= t('sidebar.navigation')
ul.sidebar-menu
li
a(href='/')
i.icon-home
span
Home
span
= t('nav.home')
li
a(href='/all')
i.icon-paper
span
All Pages
span
= t('nav.allpages')
if pageData.parent
li
a(href='/' + pageData.parent.path)
...
...
@@ -58,15 +58,15 @@ block content
li
a(href='/admin')
i.icon-head
span
Account
span
= t('nav.account')
else
li
a(href='/login')
i.icon-unlock
span
Login
span
= t('nav.login')
aside.stickyscroll
.sidebar-label
span
Page Contents
span
= t('sidebar.pagecontents')
ul.sidebar-menu
li.is-hidden-until-scroll: a(href='#root', title='Top of Page')
i.icon-arrow-up2
...
...
server/views/pages/welcome.pug
View file @
40c4ff80
...
...
@@ -11,6 +11,6 @@ block content
.container
.welcome
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')
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment