diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee index 6de2ce7110..bb323ce052 100644 --- a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee +++ b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee @@ -18,7 +18,7 @@ module.exports = AuthenticationController = res.statusCode = 429 return res.send message: - text: 'This account has had too many login requests. Please wait 2 minutes before trying to log in again', + text: req.i18n.translate("to_many_login_requests_2_mins"), type: 'error' AuthenticationManager.authenticate email: email, password, (error, user) -> return next(error) if error? @@ -33,7 +33,7 @@ module.exports = AuthenticationController = AuthenticationController._recordFailedLogin() logger.log email: email, "failed log in" res.send message: - text: 'Your email or password were incorrect. Please try again', + text: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error' getAuthToken: (req, res, next = (error) ->) -> diff --git a/services/web/app/coffee/Features/Errors/ErrorController.coffee b/services/web/app/coffee/Features/Errors/ErrorController.coffee index 39e2375713..d0589ba5ed 100644 --- a/services/web/app/coffee/Features/Errors/ErrorController.coffee +++ b/services/web/app/coffee/Features/Errors/ErrorController.coffee @@ -2,4 +2,4 @@ module.exports = ErrorController = notFound: (req, res)-> res.statusCode = 404 res.render 'general/404', - title: "Page Not Found" \ No newline at end of file + title: "page_not_found" \ No newline at end of file diff --git a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee b/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee index c52aa9b454..53a0a8bb6e 100644 --- a/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee +++ b/services/web/app/coffee/Features/PasswordReset/PasswordResetController.coffee @@ -6,7 +6,7 @@ module.exports = renderRequestResetForm: (req, res)-> res.render "user/passwordReset", - title:"Reset Password" + title:"reset_password" requestReset: (req, res)-> email = req.body.email.trim().toLowerCase() @@ -17,7 +17,7 @@ module.exports = throttle: 6 RateLimiter.addCount opts, (err, canCompile)-> if !canCompile - return res.send 500, { message: "Rate limit hit. Please wait a while before retrying" } + return res.send 500, { message: req.i18n.translate("rate_limit_hit_wait")} PasswordResetHandler.generateAndEmailResetToken email, (err)-> if err? res.send 500, {message:err?.message} @@ -26,7 +26,7 @@ module.exports = renderSetPasswordForm: (req, res)-> res.render "user/setPassword", - title:"Set Password" + title:"set_password" passwordResetToken:req.query.passwordResetToken setNewUserPassword: (req, res)-> diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index cb8db05c00..62e24f343a 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -157,7 +157,7 @@ module.exports = ProjectController = loadEditor: (req, res, next)-> timer = new metrics.Timer("load-editor") if !Settings.editorIsOpen - return res.render("general/closed", {title:"updating site"}) + return res.render("general/closed", {title:"updating_site"}) if req.session.user? user_id = req.session.user._id diff --git a/services/web/app/coffee/Features/Referal/ReferalController.coffee b/services/web/app/coffee/Features/Referal/ReferalController.coffee index 65247febd7..fbe812a22e 100644 --- a/services/web/app/coffee/Features/Referal/ReferalController.coffee +++ b/services/web/app/coffee/Features/Referal/ReferalController.coffee @@ -5,6 +5,6 @@ module.exports = bonus: (req, res)-> ReferalHandler.getReferedUserIds req.session.user._id, (err, refered_users)-> res.render "referal/bonus", - title: "Bonus - Please recommend us" + title: "bonus_please_recommend_us" refered_users: refered_users refered_user_count: (refered_users or []).length diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index 508656b3fc..5ea4eeb90b 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -21,7 +21,7 @@ module.exports = SubscriptionController = viewName = "subscriptions/plans" logger.log viewName:viewName, "showing plans page" res.render viewName, - title: "Plans and Pricing" + title: "plans_and_pricing" plans: plans baseUrl: baseUrl @@ -41,7 +41,7 @@ module.exports = SubscriptionController = }, (error, signature) -> return next(error) if error? res.render "subscriptions/new", - title : "Subscribe" + title : "subscribe" plan_code: req.query.planCode recurlyConfig: JSON.stringify currency: "USD" @@ -74,7 +74,7 @@ module.exports = SubscriptionController = logger.log user: user, subscription:subscription, hasSubOrFreeTrial:hasSubOrFreeTrial, "showing subscription dashboard" plans = SubscriptionViewModelBuilder.buildViewModel() res.render "subscriptions/dashboard", - title: "Your Subscription" + title: "your_subscription" plans: plans subscription: subscription subscriptionTabActive: true @@ -92,7 +92,7 @@ module.exports = SubscriptionController = }, (error, signature) -> return next(error) if error? res.render "subscriptions/edit-billing-details", - title : "Update Billing Details" + title : "update_billing_details" recurlyConfig: JSON.stringify currency: "USD" subdomain: Settings.apis.recurly.subdomain @@ -115,7 +115,7 @@ module.exports = SubscriptionController = SecurityManager.getCurrentUser req, (error, user) => SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel user, (error, subscription) -> res.render "subscriptions/successful_subscription", - title: "Thank you!" + title: "thank_you" subscription:subscription cancelSubscription: (req, res, next) -> diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee index 4ba79f5757..674c5affbe 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee @@ -29,6 +29,6 @@ module.exports = return res.redirect("/") SubscriptionGroupHandler.getPopulatedListOfMembers user_id, (err, users)-> res.render "subscriptions/group_admin", - title: 'Group Admin' + title: 'group_admin' users: users subscription: subscription diff --git a/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee b/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee index aaca34a52c..cc86f90f07 100644 --- a/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee +++ b/services/web/app/coffee/Features/Templates/TemplatesWebController.coffee @@ -10,7 +10,7 @@ module.exports = TemplatesWebController = if err? or !data? logger.err err:err, "something went wrong in renderTemplatesIndexPage" return res.send 500 - data.title = "LaTeX Templates" + data.title = "latex_templates" res.render "templates/index", data renerTemplateInTag: (req, res)-> @@ -60,7 +60,7 @@ module.exports = TemplatesWebController = if err? logger.err err:err, user_id:user_id, "something went wrong in _renderCanonicalPage" return res.send 500 - data.title = "All Templates" + data.title = "all_templates" res.render "templates/tag", data _renderTagPage: (req, res)-> diff --git a/services/web/app/coffee/Features/User/UserController.coffee b/services/web/app/coffee/Features/User/UserController.coffee index 62b8d8b203..ba41904812 100644 --- a/services/web/app/coffee/Features/User/UserController.coffee +++ b/services/web/app/coffee/Features/User/UserController.coffee @@ -63,7 +63,11 @@ module.exports = UserUpdater.changeEmailAddress user_id, newEmail, (err)-> if err? logger.err err:err, user_id:user_id, newEmail:newEmail, "problem updaing users email address" - return res.send 500, {message:err?.message} + if err.message == "alread_exists" + message = req.i18n.translate("alread_exists") + else + message = req.i18n.translate("problem_changing_email_address") + return res.send 500, {message:message} res.send(200) logout : (req, res)-> diff --git a/services/web/app/coffee/Features/User/UserPagesController.coffee b/services/web/app/coffee/Features/User/UserPagesController.coffee index b3041bfa7a..a99633529d 100644 --- a/services/web/app/coffee/Features/User/UserPagesController.coffee +++ b/services/web/app/coffee/Features/User/UserPagesController.coffee @@ -16,16 +16,15 @@ module.exports = newTemplateData.templateName = req.session.templateData.templateName res.render 'user/register', - title: 'Register' + title: 'register' redir: req.query.redir sharedProjectData: sharedProjectData newTemplateData: newTemplateData new_email:req.query.new_email || "" loginPage : (req, res)-> - console.info req res.render 'user/login', - title: 'Login', + title: 'login', redir: req.query.redir settingsPage : (req, res)-> @@ -34,7 +33,7 @@ module.exports = dropboxHandler.getUserRegistrationStatus user._id, (err, status)-> userIsRegisteredWithDropbox = !err? and status.registered res.render 'user/settings', - title:'Account Settings', + title:'account_settings', userHasDropboxFeature: user.features.dropbox userIsRegisteredWithDropbox: userIsRegisteredWithDropbox user: user, diff --git a/services/web/app/coffee/Features/User/UserUpdater.coffee b/services/web/app/coffee/Features/User/UserUpdater.coffee index 86ea60240d..2ed2d2bad0 100644 --- a/services/web/app/coffee/Features/User/UserUpdater.coffee +++ b/services/web/app/coffee/Features/User/UserUpdater.coffee @@ -19,7 +19,7 @@ module.exports = UserUpdater = logger.log user_id:user_id, newEmail:newEmail, "updaing email address of user" UserLocator.findByEmail newEmail, (error, user) -> if user? - return callback({message:"User with that email already exists."}) + return callback({message:"alread_exists"}) self.updateUser user_id.toString(), { $set: { "email": newEmail}, }, (err) -> diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index 34035e66fe..21f70fc55b 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -51,6 +51,7 @@ module.exports = (app)-> app.use (req, res, next)-> res.locals.translate = req.i18n.translate + res.locals.currentUrl = req.originalUrl next() app.use (req, res, next)-> diff --git a/services/web/app/coffee/infrastructure/Server.coffee b/services/web/app/coffee/infrastructure/Server.coffee index 39bf636e91..264360c81c 100644 --- a/services/web/app/coffee/infrastructure/Server.coffee +++ b/services/web/app/coffee/infrastructure/Server.coffee @@ -18,7 +18,7 @@ oneDayInMilliseconds = 86400000 ReferalConnect = require('../Features/Referal/ReferalConnect') RedirectManager = require("./RedirectManager") OldAssetProxy = require("./OldAssetProxy") -translations = require "translations-sharelatex" +translations = require("translations-sharelatex").setup(Settings.i18n) metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongojs/node_modules/mongodb"), logger) metrics.mongodb.monitor(Path.resolve(__dirname + "/../../../node_modules/mongoose/node_modules/mongodb"), logger) @@ -40,6 +40,8 @@ ignoreCsrfRoutes = [] app.ignoreCsrf = (method, route) -> ignoreCsrfRoutes.push new express.Route(method, route) + + app.configure () -> if Settings.behindProxy app.enable('trust proxy') @@ -49,10 +51,12 @@ app.configure () -> app.use express.bodyParser(uploadDir: Settings.path.uploadFolder) app.use express.bodyParser(uploadDir: __dirname + "/../../../data/uploads") app.use translations.expressMiddlewear + app.use translations.setLangBasedOnDomainMiddlewear app.use cookieParser app.use express.session proxy: Settings.behindProxy cookie: + domain: Settings.cookieDomain maxAge: cookieSessionLength secure: Settings.secureCookie store: sessionStore @@ -90,7 +94,7 @@ app.use (req, res, next)-> app.use (req, res, next) -> if !Settings.editorIsOpen res.status(503) - res.render("general/closed", {title:"Maintenance"}) + res.render("general/closed", {title:"maintenance"}) else next() diff --git a/services/web/app/views/general/404.jade b/services/web/app/views/general/404.jade index 425e056c61..018a11c2ac 100644 --- a/services/web/app/views/general/404.jade +++ b/services/web/app/views/general/404.jade @@ -6,8 +6,8 @@ block content .row .col-md-8.col-md-offset-2.text-center .page-header - h2 Sorry, we can't find the page you are looking for. + h2 #{translate("cant_find_page")} p a(href="/") i.fa.fa-arrow-circle-o-left - | Take me home! + | #{translate("take_me_home")} diff --git a/services/web/app/views/layout.jade b/services/web/app/views/layout.jade index daa8701c60..4362ef92d3 100644 --- a/services/web/app/views/layout.jade +++ b/services/web/app/views/layout.jade @@ -3,14 +3,21 @@ html(itemscope, itemtype='http://schema.org/Product') block vars head - -if (typeof(title) == "undefined") - title ShareLaTeX, the Online LaTeX Editor - -else - title= title + ' - ShareLaTeX, the Online LaTeX Editor' + + - if (typeof(priority_title) !== "undefined" && priority_title) + title= title + ' - '+ translate("online_latex_editor") + - else + title= translate("online_latex_editor") +' ShareLaTeX - ' +translate(title) + title= translate(title) + ' - ShareLaTeX, '+ + link(rel="icon", href="/favicon.ico") link(rel='stylesheet', href='/stylesheets/style.css?fingerprint='+fingerprint('/stylesheets/style.css')) link(href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css",rel="stylesheet") + if settings.i18n.subdomainLang + each subdomainDetails in settings.i18n.subdomainLang + link(rel="alternate", href=subdomainDetails.url+currentUrl, hreflang=subdomainDetails.lngCode) + meta(itemprop="name" ,content="ShareLaTeX - Real Time Online LaTeX Collaborative Editor in Your Browser") meta(itemprop="description", content="Online LaTeX editor for collaborative editing, great for Maths or Sciences. You don't need to install LaTeX so it's great for beginners too.") meta(itemprop="image", content="https://www.sharelatex.com/favicon.ico") diff --git a/services/web/app/views/layout/navbar.jade b/services/web/app/views/layout/navbar.jade index 0b6b7de692..00a08bdd46 100644 --- a/services/web/app/views/layout/navbar.jade +++ b/services/web/app/views/layout/navbar.jade @@ -6,13 +6,14 @@ nav.navbar.navbar-default a(href='/').navbar-brand .navbar-collapse.collapse(collapse="navCollapsed") + ul.nav.navbar-nav.navbar-right each item in nav.header if ((item.only_when_logged_in && session && session.user) || (item.only_when_logged_out && (!session || !session.user)) || (!item.only_when_logged_out && !item.only_when_logged_in)) if item.dropdown li.dropdown(class=item.class) a.dropdown-toggle(href) - | !{item.text} + | !{translate(item.text)} b.caret ul.dropdown-menu each child in item.dropdown @@ -21,14 +22,14 @@ nav.navbar.navbar-default else li if child.url - a(href=child.url, class=child.class) !{child.text} + a(href=child.url, class=child.class) !{translate(child.text)} else - | !{child.text} + | !{translate(child.text)} else li(class=item.class) if item.url - a(href=item.url, class=item.class) !{item.text} + a(href=item.url, class=item.class) !{translate(item.text)} else - | !{item.text} + | !{translate(item.text)} diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade index b362a2d806..00e7db8654 100644 --- a/services/web/app/views/project/editor.jade +++ b/services/web/app/views/project/editor.jade @@ -10,30 +10,25 @@ block content .editor(ng-controller="IdeController").full-size .loading-screen(ng-show="state.loading") .container - h3 Loading... + h3 #{translate("loading")}... .progress .progress-bar(style="width: 20%", ng-style="{'width': state.load_progress + '%'}") .global-alerts(ng-cloak) .alert.alert-danger.small(ng-if="connection.forced_disconnect") - strong Disconnected - | Please refresh the page to continue. + strong #{translate("disconnected")} + | #{translate("please_refresh")} .alert.alert-warning.small(ng-if="connection.reconnection_countdown") - strong Lost Connection. - | Reconnecting in {{ connection.reconnection_countdown }} secs. - a.pull-right(href, ng-click="tryReconnectNow()") Try Now + strong #{translate("lost_connection")}. + | #{translate("reconnecting_in_x_secs", {seconds:"{{ connection.reconnection_countdown }}"})}. + a.pull-right(href, ng-click="tryReconnectNow()") #{translate("try_now")} .alert.alert-warning.small(ng-if="connection.reconnecting") - strong Reconnecting... + strong #{translate("reconnecting")}... .div(ng-controller="SavingNotificationController") - .alert.alert-warning.small( - ng-repeat="(doc_id, state) in docSavingStatus" - ng-if="state.unsavedSeconds > 3" - ) - | Saving {{ state.doc.name }}... ({{ state.unsavedSeconds }} seconds of unsaved changes) - + .alert.alert-warning.small( ng-repeat="(doc_id, state) in docSavingStatus" ng-if="state.unsavedSeconds > 3") #{translate("saving_notification_with_seconds", {docname:"{{ state.doc.name }}", seconds:"{{ state.unsavedSeconds }}"})} include ./editor/left-menu @@ -78,7 +73,7 @@ block content h3 {{ title }} .modal-body {{ message }} .modal-footer - button.btn.btn-info(ng-click="done()") OK + button.btn.btn-info(ng-click="done()") #{translate("ok")} script(src='/socket.io/socket.io.js') diff --git a/services/web/app/views/project/editor/binary-file.jade b/services/web/app/views/project/editor/binary-file.jade index 015724288f..ca25a6d806 100644 --- a/services/web/app/views/project/editor/binary-file.jade +++ b/services/web/app/views/project/editor/binary-file.jade @@ -13,7 +13,7 @@ div.binary-file.full-size( ) p.no-preview( ng-if="['png', 'jpg', 'jpeg', 'gif', 'pdf', 'eps'].indexOf(extension(openFile)) == -1" - ) Sorry, no preview is available. + ) #{translate("no_preview_available")} a.btn.btn-info( ng-href="/project/{{ project_id }}/file/{{ openFile.id }}" - ) Download {{ openFile.name }} + ) #{translate("download")} {{ openFile.name }} diff --git a/services/web/app/views/project/editor/chat.jade b/services/web/app/views/project/editor/chat.jade index 85d08d147a..e6f6249793 100644 --- a/services/web/app/views/project/editor/chat.jade +++ b/services/web/app/views/project/editor/chat.jade @@ -12,11 +12,11 @@ aside.chat( .infinite-scroll-inner .loading(ng-show="chat.loading") i.fa.fa-fw.fa-spin.fa-refresh - |   Loading... + |   #{translate("loading")}... .no-messages.text-center.small(ng-show='!chat.loading && chat.messages.length == 0') - | No messages + | #{translate("no_messages")} .first-message.text-center(ng-show='!chat.loading && chat.messages.length == 0') - | Send your first message + | #{translate("send_first_message")} br i.fa.fa-arrow-down ul.list-unstyled( @@ -27,8 +27,7 @@ aside.chat( ng-controller="ChatMessageController" ng-class="{'self': message.user.id == user.id }" ) - div.date(ng-if="$index == 0 || (message.timestamp - chat.messages[$index - 1].timestamp) > 5 * 60 * 1000") - {{ message.timestamp | formatDate:'h:mm a' }} {{ message.timestamp | relativeDate }} + div.date(ng-if="$index == 0 || (message.timestamp - chat.messages[$index - 1].timestamp) > 5 * 60 * 1000") {{ message.timestamp | formatDate:'h:mm a' }} {{ message.timestamp | relativeDate }} span.avatar img(ng-src="{{message.user.gravatar_url}}?d=mm&s=50") div.message-wrapper diff --git a/services/web/app/views/project/editor/dropbox.jade b/services/web/app/views/project/editor/dropbox.jade index b4200ab6c0..3d86f57d60 100644 --- a/services/web/app/views/project/editor/dropbox.jade +++ b/services/web/app/views/project/editor/dropbox.jade @@ -5,44 +5,41 @@ script(type="text/ng-template", id="dropboxModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Dropbox Sync + h3 #{translate("dropbox_sync")} .modal-body.modal-body-share div(ng-show="dbState.gotLinkStatus") div(ng-hide="dbState.userIsLinkedToDropbox || !dbState.hasDropboxFeature") - span(ng-hide="dbState.startedLinkProcess") Your account is not linked to dropbox + span(ng-hide="dbState.startedLinkProcess") #{translate("account_not_linked_to_dropbox")} |     - a(ng-click="linkToDropbox()").btn.btn-info Update Dropbox Settings + a(ng-click="linkToDropbox()").btn.btn-info #{translate("update_dropbox_settings")} p.small.text-center(ng-show="dbState.startedLinkProcess") - | Please refresh this page after starting your free trial. + | #{translate("refresh_page_after_starting_free_trial")} div(ng-show="dbState.hasDropboxFeature && dbState.userIsLinkedToDropbox") progressbar.progress-striped.active(value='dbState.percentageLeftTillNextPoll', type="info") p - strong {{dbState.minsTillNextPoll}} minutes - span until Dropbox is next checked for changes. + strong {{dbState.minsTillNextPoll}} #{translate("minutes")} + span #{translate("until_db_checked_for_changes")} p.small - | This project will appear in your Dropbox folder at + | #{translate("this_project_will_appear_in_your_dropbox_folder_at")} strong Dropbox/sharelatex/{{ project.name }} - div.text-center(ng-hide="dbState.hasDropboxFeature") - p You need to upgrade your account to link to dropbox. + p #{translate("need_to_upgrade_for_dropbox")} p - a.btn.btn-info(ng-click="startFreeTrial('dropbox')") Start Free Trial + a.btn.btn-info(ng-click="startFreeTrial('dropbox')") #{translate("start_free_trial")} p.small(ng-show="startedFreeTrial") - | Please refresh this page after starting your free trial. + | #{translate("refresh_page_after_starting_free_trial")} div(ng-hide="dbState.gotLinkStatus") i.fa.fa-refresh.fa-spin - span.small   Checking dropbox status - - + span.small   #{translate("checking_dropbox_status")} .modal-footer() button.btn.btn-default( ng-click="cancel()", ) - span Dismiss + span #{translate("dismiss")} diff --git a/services/web/app/views/project/editor/editor.jade b/services/web/app/views/project/editor/editor.jade index 624471690d..715fdc3f5c 100644 --- a/services/web/app/views/project/editor/editor.jade +++ b/services/web/app/views/project/editor/editor.jade @@ -10,7 +10,7 @@ div.full-size( .ui-layout-center .loading-panel(ng-show="!editor.sharejs_doc || editor.opening") i.fa.fa-spin.fa-refresh - |   Loading... + |   #{translate("loading")}... #editor( ace-editor="editor", diff --git a/services/web/app/views/project/editor/file-tree.jade b/services/web/app/views/project/editor/file-tree.jade index 4cf93468fd..44190a5217 100644 --- a/services/web/app/views/project/editor/file-tree.jade +++ b/services/web/app/views/project/editor/file-tree.jade @@ -137,13 +137,13 @@ script(type='text/ng-template', id='entityListItemTemplate') href ng-click="startRenaming()" right-click="startRenaming()" - ) Rename + ) #{translate("rename")} li a( href ng-click="openDeleteModal()" right-click="openDeleteModal()" - ) Delete + ) #{translate("delete")} div.dropdown.context-menu( id="context-menu-{{ entity.id }}", @@ -155,13 +155,13 @@ script(type='text/ng-template', id='entityListItemTemplate') href ng-click="startRenaming()" right-click="startRenaming()" - ) Rename + ) #{translate("rename")} li a( href ng-click="openDeleteModal()" right-click="openDeleteModal()" - ) Delete + ) #{translate("delete")} .entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController") @@ -219,32 +219,32 @@ script(type='text/ng-template', id='entityListItemTemplate') href ng-click="startRenaming()" right-click="startRenaming()" - ) Rename + ) #{translate("rename")} li a( href ng-click="openDeleteModal()" right-click="openDeleteModal()" - ) Delete + ) #{translate("delete")} li.divider li a( href ng-click="openNewDocModal()" right-click="openNewDocModal()" - ) New File + ) #{translate("new_file")} li a( href ng-click="openNewFolderModal()" right-click="openNewFolderModal()" - ) New Folder + ) #{translate("new_folder")} li a( href ng-click="openUploadFileModal()" right-click="openUploadFileModal()" - ) Upload File + ) #{translate("upload_file")} .dropdown.context-menu( ng-if="permissions.write" @@ -256,32 +256,32 @@ script(type='text/ng-template', id='entityListItemTemplate') href ng-click="startRenaming()" right-click="startRenaming()" - ) Rename + ) #{translate("rename")} li a( href ng-click="openDeleteModal()" right-click="openDeleteModal()" - ) Delete + ) #{translate("delete")} li.divider li a( href ng-click="openNewDocModal()" right-click="openNewDocModal()" - ) New File + ) #{translate("new_file")} li a( href ng-click="openNewFolderModal()" right-click="openNewFolderModal()" - ) New Folder + ) #{translate("new_folder")} li a( href ng-click="openUploadFileModal()" right-click="openUploadFileModal()" - ) Upload File + ) #{translate("upload_file")} ul.list-unstyled( ng-if="entity.type == 'folder'" @@ -298,7 +298,7 @@ script(type='text/ng-template', id='entityListItemTemplate') script(type='text/ng-template', id='newDocModalTemplate') .modal-header - h3 New File + h3 #{translate("new_file")} .modal-body form(novalidate, name="newDocForm") input.form-control( @@ -313,17 +313,17 @@ script(type='text/ng-template', id='newDocModalTemplate') button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="newDocForm.$invalid || state.inflight" ng-click="create()" ) - span(ng-hide="state.inflight") Create - span(ng-show="state.inflight") Creating... + span(ng-hide="state.inflight") #{translate("create")} + span(ng-show="state.inflight") #{translate("creating")}... script(type='text/ng-template', id='newFolderModalTemplate') .modal-header - h3 New Folder + h3 #{translate("new_folder")} .modal-body form(novalidate, name="newFolderForm") input.form-control( @@ -338,17 +338,17 @@ script(type='text/ng-template', id='newFolderModalTemplate') button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="newFolderForm.$invalid || state.inflight" ng-click="create()" ) - span(ng-hide="state.inflight") Create - span(ng-show="state.inflight") Creating... + span(ng-hide="state.inflight") #{translate("create")} + span(ng-show="state.inflight") #{translate("creating")}... script(type="text/ng-template", id="uploadFileModalTemplate") .modal-header - h3 Upload File(s) + h3 #{translate("upload_files")} .modal-body( fine-upload endpoint="/project/{{ project_id }}/upload" @@ -362,23 +362,23 @@ script(type="text/ng-template", id="uploadFileModalTemplate") on-upload-callback="onUpload" params="{'folder_id': parent_folder_id}" ) - span Upload file(s) + span #{translate("upload_files")} .modal-footer - button.btn.btn-default(ng-click="cancel()") Cancel + button.btn.btn-default(ng-click="cancel()") #{translate("cancel")} script(type='text/ng-template', id='deleteEntityModalTemplate') .modal-header - h3 Delete {{ entity.name }} + h3 #{translate("delete")} {{ entity.name }} .modal-body - p Are you sure you want to permanently delete {{ entity.name }}? + p #{translate("sure_you_want_to_delete")} .modal-footer button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-danger( ng-disabled="state.inflight" ng-click="delete()" ) - span(ng-hide="state.inflight") Delete - span(ng-show="state.inflight") Deleting... + span(ng-hide="state.inflight") #{translate("delete")} + span(ng-show="state.inflight") #{translate("deleting")}... diff --git a/services/web/app/views/project/editor/hotkeys.jade b/services/web/app/views/project/editor/hotkeys.jade index e1f76039ef..c584e5eb28 100644 --- a/services/web/app/views/project/editor/hotkeys.jade +++ b/services/web/app/views/project/editor/hotkeys.jade @@ -5,9 +5,9 @@ script(type="text/ng-template", id="hotkeysModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Hotkeys + h3 #{translate("hotkeys")} .modal-body.modal-hotkeys - h3 Common + h3 #{translate("common")} .row .col-xs-6 .hotkey @@ -24,7 +24,7 @@ script(type="text/ng-template", id="hotkeysModalTemplate") span.combination {{ctrl}} + Y span.description Redo - h3 Navigation + h3 #{translate("navigation")} .row .col-xs-6 .hotkey @@ -38,7 +38,7 @@ script(type="text/ng-template", id="hotkeysModalTemplate") span.combination {{ctrl}} + L span.description Go To Line - h3 Editing + h3 #{translate("editing")} .row .col-xs-6 .hotkey @@ -63,4 +63,4 @@ script(type="text/ng-template", id="hotkeysModalTemplate") .modal-footer button.btn.btn-default( ng-click="cancel()" - ) OK \ No newline at end of file + ) #{translate("ok")} \ No newline at end of file diff --git a/services/web/app/views/project/editor/left-menu.jade b/services/web/app/views/project/editor/left-menu.jade index 1bba98a4b7..283a5fdc68 100644 --- a/services/web/app/views/project/editor/left-menu.jade +++ b/services/web/app/views/project/editor/left-menu.jade @@ -2,7 +2,7 @@ aside#left-menu.full-size( ng-class="{ 'shown': ui.leftMenuShown }" ng-cloak ) - h4 Download + h4 #{translate("download")} ul.list-unstyled.nav.nav-downloads.text-center li @@ -12,7 +12,7 @@ aside#left-menu.full-size( ) i.fa.fa-file-archive-o.fa-2x br - | Source + | #{translate("source")} li a( ng-href="{{pdf.url}}" @@ -32,7 +32,7 @@ aside#left-menu.full-size( | PDF span(ng-show="!anonymous") - h4 Actions + h4 #{translate("Actions")} ul.list-unstyled.nav li(ng-controller="CloneProjectController") a( @@ -40,26 +40,26 @@ aside#left-menu.full-size( ng-click="openCloneProjectModal()" ) i.fa.fa-fw.fa-copy - |   Copy Project + |   #{translate("copy_project")} li(ng-controller="TemplatesController", ng-show="permissions.admin") a(ng-click="openPublishTemplateModal()") i.fa.fa-external-link.fa-fw - |   Publish as Template + |    #{translate("publish_as_template")} span(ng-controller="DropboxController", ng-show="permissions.admin") - h4() Sync + h4() #{translate("sync")} ul.list-unstyled.nav() li a(ng-click="openDropboxModal()") i.fa.fa-dropbox.fa-fw |    Dropbox - h4(ng-show="!anonymous") Settings + h4(ng-show="!anonymous") #{translate("settings")} form.settings(ng-controller="SettingsController", ng-show="!anonymous") .containter-fluid .form-controls(ng-show="permissions.write") - label(for="compiler") Compiler + label(for="compiler") #{translate("compiler")} select( name="compiler" ng-model="project.compiler" @@ -70,7 +70,7 @@ aside#left-menu.full-size( option(value='lualatex') LuaLaTeX .form-controls(ng-show="permissions.write") - label(for="rootDoc_id") Main document + label(for="rootDoc_id") #{translate("main_document")} select( name="rootDoc_id", ng-model="project.rootDoc_id", @@ -78,12 +78,12 @@ aside#left-menu.full-size( ) .form-controls - label(for="spellCheckLanguage") Spell Check + label(for="spellCheckLanguage") #{translate("spell_check")} select( name="spellCheckLanguage" ng-model="project.spellCheckLanguage" ) - option(value="") Off + option(value="") #{translate("off")} optgroup(label="Language") for language in languages option( @@ -91,7 +91,7 @@ aside#left-menu.full-size( )= language.name .form-controls - label(for="autoComplete") Auto-Complete + label(for="autoComplete") #{translate("auto_complete")} select( name="autoComplete" ng-model="settings.autoComplete" @@ -99,7 +99,7 @@ aside#left-menu.full-size( ) .form-controls - label(for="theme") Theme + label(for="theme") #{translate("theme")} select( name="theme" ng-model="settings.theme" @@ -108,7 +108,7 @@ aside#left-menu.full-size( option(value=theme) #{theme.replace(/_/g, ' ')} .form-controls(ng-show="!anonymous") - label(for="mode") Keybindings + label(for="mode") #{translate("keybindings")} select( name="mode" ng-model="settings.mode" @@ -118,7 +118,7 @@ aside#left-menu.full-size( option(value='emacs') Emacs .form-controls - label(for="fontSize") Font Size + label(for="fontSize") #{translate("font_size")} select( name="fontSize" ng-model="settings.fontSize" @@ -127,20 +127,20 @@ aside#left-menu.full-size( option(value=size) #{size}px .form-controls - label(for="pdfViewer") PDF Viewer + label(for="pdfViewer") select( name="pdfViewer" ng-model="settings.pdfViewer" ) - option(value="pdfjs") Built-In - option(value="native") Native + option(value="pdfjs") #{translate("built_in")} + option(value="native") #{translate("native")} - h4 Hotkeys + h4 #{translate("hotkeys")} ul.list-unstyled.nav li(ng-controller="HotkeysController") a(ng-click="openHotkeysModal()") i.fa.fa-keyboard-o.fa-fw - |    Show Hotkeys + |    #{translate("show_hotkeys")} #left-menu-mask( ng-show="ui.leftMenuShown", @@ -150,11 +150,11 @@ aside#left-menu.full-size( script(type='text/ng-template', id='cloneProjectModalTemplate') .modal-header - h3 Copy Project + h3 #{translate("copy_project")} .modal-body form(name="cloneProjectForm", novalidate) .form-group - label New Name + label #{translate("new_name")} input.form-control( type="text", placeholder="New Project Name", @@ -167,10 +167,10 @@ script(type='text/ng-template', id='cloneProjectModalTemplate') button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="cloneProjectForm.$invalid || state.inflight" ng-click="clone()" ) - span(ng-hide="state.inflight") Copy - span(ng-show="state.inflight") Copying... + span(ng-hide="state.inflight") #{translate("copy")} + span(ng-show="state.inflight") #{translate("copying")}... diff --git a/services/web/app/views/project/editor/pdf.jade b/services/web/app/views/project/editor/pdf.jade index 6f218d4aa2..6359ec61e5 100644 --- a/services/web/app/views/project/editor/pdf.jade +++ b/services/web/app/views/project/editor/pdf.jade @@ -9,8 +9,8 @@ div.full-size.pdf(ng-controller="PdfController") ng-class="{'fa-spin': pdf.compiling }" ) |    - span(ng-show="!pdf.compiling") Recompile - span(ng-show="pdf.compiling") Compiling... + span(ng-show="!pdf.compiling") #{translate("recompile")} + span(ng-show="pdf.compiling") #{translate("compiling")}... a.log-btn( href ng-click="toggleLogs()" @@ -76,29 +76,28 @@ div.full-size.pdf(ng-controller="PdfController") .pdf-uncompiled(ng-show="pdf.uncompiled && !pdf.compiling") |   i.fa.fa-level-up.fa-flip-horizontal.fa-2x - |   Click here to preview your work as a PDF. + |   #{translate("click_here_to_preview_pdf")} .pdf-errors(ng-show="pdf.timedout || pdf.error") .alert.alert-danger(ng-show="pdf.error") - strong Server Error. - span Sorry, something went wrong and your project could not be compiled. Please try again in a few moments. + strong #{translate("server_error")} + span #{translate("somthing_went_wrong_compiling")} - .alert.alert-danger(ng-show="pdf.timedout") + .alert.alert-danger(ng-show="pdf.timedout") p - strong Your compile timed out. - | Sorry, your compile was taking too long and timed out. - | This may be due to a problem with your LaTeX code, or too many high-res images. + strong #{translate("timedout")}. + span #{translate("proj_timed_out_reason")} p a.text-info(href="https://www.sharelatex.com/learn/Debugging_Compilation_timeout_errors", target="_blank") - | Please see our help guide for more information. + | #{translate("please_see_help_for_more_info")} .pdf-logs(ng-show="(pdf.view == 'logs' || pdf.failure) && !pdf.error && !pdf.timeout && !pdf.uncompiled") .alert.alert-success(ng-show="pdf.logEntries.all.length == 0") - | No errors, good job! + | #{translate("no_errors_good_job")} .alert.alert-danger(ng-show="pdf.failure") - strong Compile Error. - span Sorry, your LaTeX code couldn't compile for some reason. Please check the errors below for details, or view the raw log. + strong #{translate("compile_error")}. + span #{translate("generic_failed_compile_message")}. div(ng-repeat="entry in pdf.logEntries.all", ng-controller="PdfLogEntryController") .alert( @@ -131,7 +130,7 @@ div.full-size.pdf(ng-controller="PdfController") href dropdown-toggle ) - | Other logs & files + | #{translate("other_logs_and_files")} span.caret ul.dropdown-menu.dropdown-menu-right li(ng-repeat="file in pdf.outputFiles") @@ -141,26 +140,25 @@ div.full-size.pdf(ng-controller="PdfController") ng-click="openOutputFile(file)" ) {{ file.name }} a.btn.btn-info.btn-sm(href, ng-click="toggleRawLog()") - span(ng-show="!pdf.showRawLog") View Raw Logs - span(ng-show="pdf.showRawLog") Hide Raw Logs + span(ng-show="!pdf.showRawLog") #{translate("view_raw_logs")} + span(ng-show="pdf.showRawLog") #{translate("hide_raw_logs")} pre(ng-bind="pdf.rawLog", ng-show="pdf.showRawLog") script(type='text/ng-template', id='clearCacheModalTemplate') .modal-header - h3 Clear cache? + h3 #{translate("clear_cache")}? .modal-body - p This will clear all hidden LaTeX files (.aux, .bbl, etc) from our compile server. - | You generally don't need to do this unless you're having trouble with references. - p Your project files will not be deleted or changed. + p #{translate("clear_cache_explanation")} + p #{translate("clear_cache_is_safe")} .modal-footer button.btn.btn-default( ng-click="cancel()" ng-disabled="state.inflight" - ) Cancel + ) #{translate("cancel")} button.btn.btn-info( ng-click="clear()" ng-disabled="state.inflight" ) - span(ng-show="!state.inflight") Clear cache - span(ng-show="state.inflight") Clearing... + span(ng-show="!state.inflight") #{translate("clear_cache")} + span(ng-show="state.inflight") #{translate("clearing")}... diff --git a/services/web/app/views/project/editor/publish-template.jade b/services/web/app/views/project/editor/publish-template.jade index f7ff01694b..69c50fd52c 100644 --- a/services/web/app/views/project/editor/publish-template.jade +++ b/services/web/app/views/project/editor/publish-template.jade @@ -5,11 +5,11 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Publish as Template + h3 #{translate("publish_as_template")} .modal-body.modal-body-share span(ng-hide="problemTalkingToTemplateApi") form() - label(for='Description') Template Description + label(for='Description') #{translate("template_description")} .form-group textarea.form-control( rows=5, @@ -19,11 +19,11 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") value="" ) div(ng-show="templateDetails.exists").text-center.templateDetails - | Your project was last published at + | #{translate("project_last_published_at")} strong {{templateDetails.publishedDate}}. - a(ng-href="{{templateDetails.canonicalUrl}}") View it in template gallery. + a(ng-href="{{templateDetails.canonicalUrl}}") #{translate("view_in_template_gallery")}. - span(ng-show="problemTalkingToTemplateApi") There is a problem with our publishing service, please try again in a few minutes. + span(ng-show="problemTalkingToTemplateApi") #{translate("problem_talking_to_publishing_service")}. @@ -33,20 +33,20 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") ng-click="cancel()", ng-disabled="state.publishInflight || state.unpublishInflight" ) - span Cancel + span #{translate("cancel")} button.btn.btn-info( ng-click="unpublishTemplate()", ng-disabled="state.publishInflight || state.unpublishInflight" ng-show="templateDetails.exists" ) - span(ng-show="!state.unpublishInflight") Unpublish - span(ng-show="state.unpublishInflight") Unpublishing... + span(ng-show="!state.unpublishInflight") #{translate("unpublish")} + span(ng-show="state.unpublishInflight") #{translate("unpublishing")}... button.btn.btn-primary( ng-click="publishTemplate()", ng-disabled="state.publishInflight || state.unpublishInflight" ) - span(ng-show="!state.publishInflight && !templateDetails.exists") Publish - span(ng-show="!state.publishInflight && templateDetails.exists") Republish - span(ng-show="state.publishInflight") Publishing... \ No newline at end of file + span(ng-show="!state.publishInflight && !templateDetails.exists") #{translate("publish")} + span(ng-show="!state.publishInflight && templateDetails.exists") #{translate("republish")} + span(ng-show="state.publishInflight") #{translate("publishing")}... \ No newline at end of file diff --git a/services/web/app/views/project/editor/share.jade b/services/web/app/views/project/editor/share.jade index fb47236cc8..8dddb51a3a 100644 --- a/services/web/app/views/project/editor/share.jade +++ b/services/web/app/views/project/editor/share.jade @@ -5,26 +5,26 @@ script(type='text/ng-template', id='shareProjectModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 Share Project + h3 #{translate("share_project")} .modal-body.modal-body-share .container-fluid .row.public-access-level(ng-show="project.publicAccesLevel == 'private'") .col-xs-12.text-center - | This project is private and can only be accessed by the people below. + | #{translate("this_project_is_private")} |    a( href ng-click="openMakePublicModal()" - ) Make Public + ) #{translate("make_public")} .row.public-access-level(ng-show="project.publicAccesLevel != 'private'") .col-xs-12.text-center - strong(ng-if="project.publicAccesLevel == 'readAndWrite'") This project is public and can be edited by anyone with the URL. - strong(ng-if="project.publicAccesLevel == 'readOnly'") This project is public and can be viewed by anyone with the URL. + strong(ng-if="project.publicAccesLevel == 'readAndWrite'") #{translate("this_project_is_public")} + strong(ng-if="project.publicAccesLevel == 'readOnly'") #{translate("this_project_is_public")} |    a( href ng-click="openMakePrivateModal()" - ) Make Private + ) #{translate("make_private")} .row.project-member .col-xs-8 {{ project.owner.email }} .text-right( @@ -33,8 +33,8 @@ script(type='text/ng-template', id='shareProjectModalTemplate') .row.project-member(ng-repeat="member in project.members") .col-xs-8 {{ member.email }} .col-xs-3.text-right - span(ng-show="member.privileges == 'readAndWrite'") Can Edit - span(ng-show="member.privileges == 'readOnly'") Read Only + span(ng-show="member.privileges == 'readAndWrite'") #{translate("can_edit")} + span(ng-show="member.privileges == 'readOnly'") #{translate("read_only")} .col-xs-1 a( href @@ -45,7 +45,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate') i.fa.fa-times .row.invite-controls form(ng-show="canAddCollaborators") - .small Share with your collaborators + .small #{translate("share_with_your_collabs")} .form-group input.form-control( type="email" @@ -59,19 +59,19 @@ script(type='text/ng-template', id='shareProjectModalTemplate') ng-model="inputs.privileges" name="privileges" ) - option(value="readAndWrite") Can Edit - option(value="readOnly") Read Only + option(value="readAndWrite") #{translate("can_edit")} + option(value="readOnly") #{translate("read_only")} |    button.btn.btn-info( type="submit" ng-click="addMember()" - ) Share + ) #{translate("share")} div.text-center(ng-hide="canAddCollaborators") - p You need to upgrade your account to add more collaborators. + p #{translate("need_to_upgrade_for_more_collabs")}. p - a.btn.btn-info(href, ng-click="startFreeTrial('projectMembers')") Start Free Trial + a.btn.btn-info(href, ng-click="startFreeTrial('projectMembers')") #{translate("start_free_trial")} p.small(ng-show="startedFreeTrial") - | Please refresh this page after starting your free trial. + | #{translate("refresh_page_after_starting_free_trial")}. .modal-footer .modal-footer-left @@ -79,7 +79,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate') span.text-danger.error(ng-show="state.error") {{ state.error }} button.btn.btn-primary( ng-click="done()" - ) Done + ) #{translate("done")} script(type="text/ng-template", id="makePublicModalTemplate") .modal-header @@ -88,23 +88,23 @@ script(type="text/ng-template", id="makePublicModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Make project public? + h3 #{translate("make_project_public")}? .modal-body.modal-body-share - p If you make your project public then anyone with the URL will be able to access it. + p #{translate("make_project_public_consequences")} p select.form-control( ng-model="inputs.privileges" name="privileges" ) - option(value="readAndWrite") Allow public editing - option(value="readOnly") Allow public read only access + option(value="readAndWrite") #{translate("allow_public_editing")} + option(value="readOnly") #{translate("allow_public_read_only")} .modal-footer button.btn.btn-default( ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-info( ng-click="makePublic()" - ) Make public + ) #{translate("make_public")} script(type="text/ng-template", id="makePrivateModalTemplate") .modal-header @@ -113,13 +113,13 @@ script(type="text/ng-template", id="makePrivateModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Make project private? + h3 #{translate("make_project_private")}? .modal-body.modal-body-share - p If you make your project private then only the people you choose to share it with will have access. + p #{translate("make_project_private_consequences")} .modal-footer button.btn.btn-default( ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-info( ng-click="makePrivate()" - ) Make private + ) #{translate("make_private")} diff --git a/services/web/app/views/project/editor/track-changes.jade b/services/web/app/views/project/editor/track-changes.jade index 92bc4228f1..c9505a5a53 100644 --- a/services/web/app/views/project/editor/track-changes.jade +++ b/services/web/app/views/project/editor/track-changes.jade @@ -1,15 +1,15 @@ div#trackChanges(ng-show="ui.view == 'track-changes'") .upgrade-prompt(ng-show="!project.features.versioning") .message(ng-show="project.owner._id == user.id") - p You need to upgrade your account to use the History feature. + p #{translate("need_to_upgrade_for_history")} p a.btn.btn-info( href ng-click="startFreeTrial('track-changes')" - ) Start Free Trial - p.small(ng-show="startedFreeTrial") Please refresh the page after starting your free trial. + ) #{translate("start_free_trial")} + p.small(ng-show="startedFreeTrial") #{translate("refresh_page_after_starting_free_trial")} .message(ng-show="project.owner._id != user.id") - p Please ask the project owner to upgrade to use the History feature. + p #{translate("ask_proj_owner_to_upgrade_for_history")} aside.change-list( ng-controller="TrackChangesListController" @@ -73,11 +73,11 @@ div#trackChanges(ng-show="ui.view == 'track-changes'") .name(ng-if="update_user.id == user.id") You div.user(ng-if="update.meta.users.length == 0") .color-square(style="background-color: hsl(100, 100%, 50%)") - span Anonymous + span #{translate("anonymous")} .loading(ng-show="trackChanges.loading") i.fa.fa-spin.fa-refresh - |   Loading... + |    #{translate("loading")}... .diff-panel.full-size(ng-controller="TrackChangesDiffController") .diff( @@ -98,7 +98,7 @@ div#trackChanges(ng-show="ui.view == 'track-changes'") a.btn.btn-danger.btn-sm( href, ng-click="openRestoreDiffModal()" - ) Restore to before these changes + ) #{translate("restore_to_before_these_changes")} .diff-editor.hide-ace-cursor( ace-editor="track-changes", theme="settings.theme", @@ -112,17 +112,18 @@ div#trackChanges(ng-show="ui.view == 'track-changes'") .diff-deleted.text-centered( ng-show="trackChanges.diff.deleted" ) - p.text-serif {{ trackChanges.diff.doc.name }} has been deleted. + p.text-serif #{translate("file_has_been_deleted", {filename:"{{ trackChanges.diff.doc.name }} "})} + p a.btn.btn-primary.btn-lg( href, ng-click="restoreDeletedDoc()" - ) Restore + ) #{translate("restore")} .loading-panel(ng-show="trackChanges.diff.loading") i.fa.fa-spin.fa-refresh - |   Loading... + |   #{translate("loading")}... .error-panel(ng-show="trackChanges.diff.error") - .alert.alert-danger Sorry, something went wrong :( + .alert.alert-danger #{translate("generic_something_went_wrong")} script(type="text/ng-template", id="trackChangesRestoreDiffModalTemplate") .modal-header @@ -131,17 +132,17 @@ script(type="text/ng-template", id="trackChangesRestoreDiffModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Restore {{diff.doc.name}} + h3 #{translate("restore")} {{diff.doc.name}} .modal-body.modal-body-share - p Are you sure you want to restore {{diff.doc.name}} to before the changes on {{diff.start_ts | formatDate}}? + p #{translate("sure_you_want_to_restore_before", {filename:"{{diff.doc.name}}", date:"{{diff.start_ts | formatDate}}"})} .modal-footer button.btn.btn-default( ng-click="cancel()", ng-disabled="state.inflight" - ) Cancel + ) #{translate("cancel")} button.btn.btn-danger( ng-click="restore()", ng-disabled="state.inflight" ) - span(ng-show="!state.inflight") Restore - span(ng-show="state.inflight") Restoring... + span(ng-show="!state.inflight") #{translate("restore")} + span(ng-show="state.inflight") #{translate("restoring")} ... diff --git a/services/web/app/views/project/list.jade b/services/web/app/views/project/list.jade index 06a0024c98..7544da209c 100644 --- a/services/web/app/views/project/list.jade +++ b/services/web/app/views/project/list.jade @@ -3,6 +3,9 @@ extends ../layout block content //- We need to do .replace(/\//g, '\\/') do that '' -> '<\/script>' //- and doesn't prematurely end the script tag. + + + script(type="text/javascript"). window.data = { projects: !{JSON.stringify(projects).replace(/\//g, '\\/')}, diff --git a/services/web/app/views/project/list/modals.jade b/services/web/app/views/project/list/modals.jade index ca5f6fbbe3..ca609ae697 100644 --- a/services/web/app/views/project/list/modals.jade +++ b/services/web/app/views/project/list/modals.jade @@ -5,7 +5,7 @@ script(type='text/ng-template', id='newTagModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 Create New Folder + h3 #{translate("create_new_folder")} .modal-body form(name="newTagForm", novalidate) input.form-control( @@ -23,12 +23,12 @@ script(type='text/ng-template', id='newTagModalTemplate') button.btn.btn-default( ng-click="cancel()" stop-propagation="click" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="newTagForm.$invalid" ng-click="create()" stop-propagation="click" - ) Create + ) #{translate("create")} script(type='text/ng-template', id='renameProjectModalTemplate') .modal-header @@ -37,7 +37,7 @@ script(type='text/ng-template', id='renameProjectModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 Rename Project + h3 #{translate("rename_project")} .modal-body form(name="renameProjectForm", novalidate) input.form-control( @@ -49,11 +49,11 @@ script(type='text/ng-template', id='renameProjectModalTemplate') focus-on="open" ) .modal-footer - button.btn.btn-default(ng-click="cancel()") Cancel + button.btn.btn-default(ng-click="cancel()") #{translate("cancel")} button.btn.btn-primary( ng-click="rename()", ng-disabled="renameProjectForm.$invalid" - ) Rename + ) #{translate("rename")} script(type='text/ng-template', id='cloneProjectModalTemplate') .modal-header @@ -62,11 +62,11 @@ script(type='text/ng-template', id='cloneProjectModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 Copy Project + h3 #{translate("copy_project")} .modal-body form(name="cloneProjectForm", novalidate) .form-group - label New Name + label #{translate("new_name")} input.form-control( type="text", placeholder="New Project Name", @@ -79,13 +79,13 @@ script(type='text/ng-template', id='cloneProjectModalTemplate') button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="cloneProjectForm.$invalid || state.inflight" ng-click="clone()" ) - span(ng-hide="state.inflight") Copy - span(ng-show="state.inflight") Copying... + span(ng-hide="state.inflight") #{translate("copy")} + span(ng-show="state.inflight") #{translate("copying")} ... script(type='text/ng-template', id='newProjectModalTemplate') .modal-header @@ -94,7 +94,7 @@ script(type='text/ng-template', id='newProjectModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 New Project + h3 #{translate("new_project")} .modal-body form(novalidate, name="newProjectForm") input.form-control( @@ -109,13 +109,13 @@ script(type='text/ng-template', id='newProjectModalTemplate') button.btn.btn-default( ng-disabled="state.inflight" ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-primary( ng-disabled="newProjectForm.$invalid || state.inflight" ng-click="create()" ) - span(ng-hide="state.inflight") Create - span(ng-show="state.inflight") Creating... + span(ng-hide="state.inflight") #{translate("create")} + span(ng-show="state.inflight") #{translate("creating")} ... script(type='text/ng-template', id='deleteProjectsModalTemplate') .modal-header @@ -124,22 +124,22 @@ script(type='text/ng-template', id='deleteProjectsModalTemplate') data-dismiss="modal" ng-click="cancel()" ) × - h3 {{action}} Projects + h3 {{action}} #{translate("projects")} .modal-body div(ng-show="projectsToDelete.length > 0") - p You are about to delete the following projects: + p #{translate("about_to_delete_projects")} ul li(ng-repeat="project in projectsToDelete | orderBy:'name'") strong {{project.name}} div(ng-show="projectsToLeave.length > 0") - p You are about to leave the following projects: + p #{translate("about_to_leave_projects")} ul li(ng-repeat="project in projectsToLeave | orderBy:'name'") strong {{project.name}} .modal-footer button.btn.btn-default( ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-danger( ng-click="delete()" ) {{action}} @@ -151,7 +151,7 @@ script(type="text/ng-template", id="uploadProjectModalTemplate") data-dismiss="modal" ng-click="cancel()" ) × - h3 Upload Zipped Project + h3 #{translate("upload_zipped_project")} .modal-body( fine-upload endpoint="/project/new/upload" @@ -163,9 +163,9 @@ script(type="text/ng-template", id="uploadProjectModalTemplate") allowed-extensions="['zip']" on-complete-callback="onComplete" ) - span Upload a zipped project + span #{translate("upload_a_zipped_project")} .modal-footer - button.btn.btn-default(ng-click="cancel()") Cancel + button.btn.btn-default(ng-click="cancel()") #{translate("cancel")} script(type="text/ng-template", id="userProfileModalTemplate") .modal-header @@ -174,12 +174,12 @@ script(type="text/ng-template", id="userProfileModalTemplate") data-dismiss="modal" ng-click="done()" ) × - h3 Your Profile + h3 #{translate("your_profile")} .modal-body form(enctype='multipart/form-data', method='post') .form-group - label(for="first_name") First Name + label(for="first_name") #{translate("first_name")} input.form-control( type='text', name='first_name', @@ -189,7 +189,7 @@ script(type="text/ng-template", id="userProfileModalTemplate") ) .form-group - label(for="last_name") Last Name + label(for="last_name") #{translate("last_name")} input.form-control( type='text', name='last_name', @@ -198,7 +198,7 @@ script(type="text/ng-template", id="userProfileModalTemplate") ) .form-group.user_details_auto_complete - label(for="institution") Institution + label(for="institution") #{translate("institution")} autocomplete( ng-model="userInfoForm.institution", name="institution", @@ -209,7 +209,7 @@ script(type="text/ng-template", id="userProfileModalTemplate") ) .form-group.user_details_auto_complete - label(for="role") Role + label(for="role") #{translate("role")} autocomplete( ng-model="userInfoForm.role", name="role", @@ -220,4 +220,4 @@ script(type="text/ng-template", id="userProfileModalTemplate") .modal-footer - button.btn.btn-info(ng-click="done()") Done + button.btn.btn-info(ng-click="done()") #{translate("done")} diff --git a/services/web/app/views/project/list/project-list.jade b/services/web/app/views/project/list/project-list.jade index 3d82d4c550..13849d1a00 100644 --- a/services/web/app/views/project/list/project-list.jade +++ b/services/web/app/views/project/list/project-list.jade @@ -52,7 +52,7 @@ role="menu" ng-controller="TagListController" ) - li.dropdown-header Add to folder + li.dropdown-header #{translate("add_to_folder")} li( ng-repeat="tag in tags | filter:nonEmpty | orderBy:'name'", ng-controller="TagDropdownItemController" @@ -68,25 +68,25 @@ | {{tag.name}} li.divider li - a(href="#", ng-click="openNewTagModal()", stop-propagation="click") Create New Folder + a(href="#", ng-click="openNewTagModal()", stop-propagation="click") #{translate("create_new_folder")} .btn-group(ng-hide="selectedProjects.length != 1").dropdown a.btn.btn-default.dropdown-toggle( href='#', data-toggle="dropdown" - ) More + ) #{translate("more")} span.caret ul.dropdown-menu.dropdown-menu-right(role="menu") li(ng-show="getFirstSelectedProject().accessLevel == 'owner'") a( href='#', ng-click="openRenameProjectModal()" - ) Rename + ) #{translate("rename")} li a( href='#', ng-click="openCloneProjectModal()" - ) Make a copy + ) #{translate("make_copy")} .btn-toolbar(ng-show="filter == 'archived'") .btn-group(ng-hide="selectedProjects.length < 1") @@ -96,7 +96,7 @@ data-toggle="tooltip", data-placement="bottom", ng-click="restoreSelectedProjects()" - ) Restore + ) #{translate("restore")} .btn-group(ng-hide="selectedProjects.length < 1") a.btn.btn-danger( @@ -105,7 +105,7 @@ data-toggle="tooltip", data-placement="bottom", ng-click="openDeleteProjectsModal()" - ) Delete Forever + ) #{translate("delete_forever")} .row.row-spaced .col-xs-12 @@ -123,13 +123,13 @@ select-all, type="checkbox" ) - span.header.clickable(ng-click="changePredicate('name')") Title + span.header.clickable(ng-click="changePredicate('name')") #{translate("title")} i.tablesort.fa(ng-class="getSortIconClass('name')") .col-xs-2 - span.header.clickable(ng-click="changePredicate('accessLevel')") Owner + span.header.clickable(ng-click="changePredicate('accessLevel')") #{translate("owner")} i.tablesort.fa(ng-class="getSortIconClass('accessLevel')") .col-xs-4 - span.header.clickable(ng-click="changePredicate('lastUpdated')") Last Modified + span.header.clickable(ng-click="changePredicate('lastUpdated')") #{translate("last_modified")} i.tablesort.fa(ng-class="getSortIconClass('lastUpdated')") li.project_entry.container-fluid( ng-repeat="project in visibleProjects | orderBy:predicate:reverse", @@ -162,13 +162,13 @@ ) .row .col-xs-12.text-centered - small No projects + small #{translate("no_projects")} div.welcome.text-centered(ng-if="projects.length == 0", ng-cloak) - h2 Welcome to ShareLaTeX! - p New to LaTeX? Start by having a look at our - a(href="/templates") templates - | or - a(href="/learn") help guides + h2 #{translate("welcome_to_sl")} + p #{translate("new_to_latex_look_at")} + a(href="/templates") #{translate("templates").toLowerCase()} + | #{translate("or")} + a(href="/learn") #{translate("latex_help_guide")} | , br - | or create your first project on the left. \ No newline at end of file + | #{translate("or_create_project_left")} diff --git a/services/web/app/views/project/list/side-bar.jade b/services/web/app/views/project/list/side-bar.jade index 7be015e7b0..c560ebc3c3 100644 --- a/services/web/app/views/project/list/side-bar.jade +++ b/services/web/app/views/project/list/side-bar.jade @@ -2,54 +2,56 @@ a.btn.btn-primary.dropdown-toggle( href="#", data-toggle="dropdown" - ) New Project + ) + | #{translate("new_project")} + ul.dropdown-menu(role="menu") li a( href, ng-click="openCreateProjectModal()" - ) Blank Project + ) #{translate("blank_project")} li a( href, ng-click="openCreateProjectModal('example')" - ) Example Project + ) #{translate("example_project")} li a( href, ng-click="openUploadProjectModal()" - ) Upload Project + ) #{translate("upload_project")} li.divider - li.dropdown-header Templates + li.dropdown-header #{translate("templates")} li - a.menu-indent(href="/templates/cv") CV or Resume + a.menu-indent(href="/templates/cv") #{translate("cv_or_resume")} li - a.menu-indent(href="/templates/cover-letters") Cover Letter + a.menu-indent(href="/templates/cover-letters") #{translate("cover_letter")} li - a.menu-indent(href="/templates/journals") Journal Article + a.menu-indent(href="/templates/journals") #{translate("journal_article")} li - a.menu-indent(href="/templates/presentations") Presentation + a.menu-indent(href="/templates/presentations") #{translate("presentation")} li - a.menu-indent(href="/templates/thesis") Thesis + a.menu-indent(href="/templates/thesis") #{translate("thesis")} li - a.menu-indent(href="/templates/bibliographies") Bibliographies + a.menu-indent(href="/templates/bibliographies") #{translate("bibliographies")} li - a.menu-indent(href="/templates") View All » + a.menu-indent(href="/templates") #{translate("view_all")} » .row-spaced(ng-if="projects.length > 0", ng-cloak) ul.list-unstyled.folders-menu( ng-controller="TagListController" ) li(ng-class="{active: (filter == 'all')}") - a(href, ng-click="filterProjects('all')") All projects + a(href, ng-click="filterProjects('all')") #{translate("all_projects")} li(ng-class="{active: (filter == 'owned')}") - a(href, ng-click="filterProjects('owned')") Your projects + a(href, ng-click="filterProjects('owned')") #{translate("your_projects")} li(ng-class="{active: (filter == 'shared')}") - a(href, ng-click="filterProjects('shared')") Shared with you + a(href, ng-click="filterProjects('shared')") #{translate("shared_with_you")} li(ng-class="{active: (filter == 'archived')}") - a(href, ng-click="filterProjects('archived')") Deleted projects + a(href, ng-click="filterProjects('archived')") #{translate("deleted_projects")} li - h2 Folders + h2 #{translate("folders")} li( ng-repeat="tag in tags | filter:nonEmpty", ng-class="{active: tag.selected}", @@ -67,14 +69,14 @@ li(ng-cloak) a.tag(href, ng-click="openNewTagModal()") i.fa.fa-fw.fa-plus - span.name New Folder + span.name #{translate("new_folder")} .row-spaced(ng-if="projects.length == 0", ng-cloak) .first-project div i.fa.fa-arrow-up.fa-2x div - strong Create your first project! + strong #{translate("create_your_first_project")} - if (showUserDetailsArea) .row-spaced#userProfileInformation(ng-if="projects.length > 0", ng-cloak) @@ -84,22 +86,19 @@ .progress .progress-bar.progress-bar-info(ng-style="{'width' : (percentComplete+'%')}") - p.small - | Your profile is - strong {{percentComplete}}% - | complete - + p.small #{translate("profile_complete_percentage_test", {percentval:"{{percentComplete}}"})} + button#completeUserProfileInformation.btn.btn-info( ng-hide="formVisable", ng-click="openUserProfileModal()" - ) Complete + ) #{translate("complete")} -if (settings.enableSubscriptions && !hasSubscription) .row-spaced(ng-if="projects.length > 0", ng-cloak).text-centered hr - p.small You are using the free version of ShareLaTeX. + p.small #{translate("on_free_sl")} p - a(href="/user/subscription/plans").btn.btn-primary Upgrade + a(href="/user/subscription/plans").btn.btn-primary #{translate("upgrade")} p.small - | or unlock some free bonus features by - a(href="/user/bonus") sharing ShareLaTeX. \ No newline at end of file + | #{translate("or_unlock_features_bonus")} + a(href="/user/bonus") #{translate("sharing_sl")} . \ No newline at end of file diff --git a/services/web/app/views/referal/bonus.jade b/services/web/app/views/referal/bonus.jade index 1bcc874d20..3439e4694e 100644 --- a/services/web/app/views/referal/bonus.jade +++ b/services/web/app/views/referal/bonus.jade @@ -10,12 +10,12 @@ block content .row .col-md-12 .page-header - h1 Help us spread the word about ShareLaTeX. + h1 #{translate("help_us_spread_word")}. .row .col-md-10.col-md-offset-1 - h2 Share ShareLaTeX with your friends and colleagues and unlock the rewards below + h2 #{translate("share_sl_to_get_rewards")} .row .col-md-8.col-md-offset-2.bonus-banner @@ -29,31 +29,31 @@ block content .row .col-md-8.col-md-offset-2.bonus-banner .title - a(href='#', onclick='postToFeed(); return false;').facebook Post on Facebook + a(href='#', onclick='postToFeed(); return false;').facebook #{translate("post_on_facebook")} .row .col-md-8.col-md-offset-2.bonus-banner .title - a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl('gp'))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus Share us on Google+ + a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl('gp'))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus #{translate("share_us_on_googleplus")} .row .col-md-8.col-md-offset-2.bonus-banner .title - a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email Email us to your friends + a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email #{translate("email_us_to_your_friends")} .row .col-md-8.col-md-offset-2.bonus-banner .title - a(href='#link-modal', data-toggle="modal", ng-click="openLinkToUsModal()").link Link to us from your website + a(href='#link-modal', data-toggle="modal", ng-click="openLinkToUsModal()").link #{translate("link_to_us")} .row .col-md-10.col-md-offset-1.bonus-banner - h2.direct-link Direct Link + h2.direct-link #{translate("direct_link")} pre.text-centered #{buildReferalUrl("d")} .row.ab-bonus .col-md-10.col-md-offset-1.bonus-banner - p.thanks When someone starts using ShareLaTeX after your recommendation we'll give you some free stuff to say thanks! Check your progress below. + p.thanks #{translate("sl_gives_you_free_stuff_see_progress_below")} .row.ab-bonus .col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 30px; margin-top: 20px;") - for (var i = 0; i <= 10; i++) { @@ -67,24 +67,24 @@ block content .col-md-10.col-md-offset-1.bonus-banner .progress - if (refered_user_count == 0) - div(style="text-align: center; padding: 4px;") Spread the word and fill this bar up + div(style="text-align: center; padding: 4px;") #{translate("spread_the_word_and_fill_bar")} .progress-bar.progress-bar-info(style="width: #{refered_user_count}0%") .row.ab-bonus .col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 70px;") - .perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") One free collaborator - .perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") Three free collaborators - .perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") Free Dropbox and History - .perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") Free Professional account + .perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") #{translate("one_free_collab")} + .perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") #{translate("three_free_collab")} + .perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") #{translate("free_dropbox_and_history")} + .perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") #{translate("free_prof_account")} .row.ab-bonus .col-md-10.col-md-offset-1.bonus-banner - if (refered_user_count == 0) - p.thanks You've not introduced anyone to ShareLaTeX yet. Get sharing! + p.thanks #{translate("you_not_introed_anyone_to_sl")} - else if (refered_user_count == 1) - p.thanks You've introduced #{refered_user_count} person to ShareLaTeX. Good job, but can you get some more? + p.thanks #{translate("you_introed_small_number", {numberOfPeople:"#{refered_user_count}"})} - else - p.thanks You've introduced #{refered_user_count} people to ShareLaTeX. Good job! + p.thanks #{translate("you_introed_high_number", {numberOfPeople:"#{refered_user_count}"})} script(type="text/ng-template", id="BonusLinkToUsModal") .modal-header @@ -93,22 +93,22 @@ block content data-dismiss="modal" ng-click="cancel()" ) × - h3 Link to ShareLaTeX + h3 #{translate("link_to_sl")} .modal-body.modal-body-share.link-modal - p You can link to ShareLaTeX with the following HTML: + p #{translate("can_link_to_sl_with_html")} p textarea.col-md-12(readonly=true) Online LaTeX Editor ShareLaTeX - p Thanks! + p #{translate("thanks")}! .modal-footer() button.btn.btn-default( ng-click="cancel()", ) - span Close + span #{translate("close")} diff --git a/services/web/app/views/subscriptions/dashboard.jade b/services/web/app/views/subscriptions/dashboard.jade index 7b5bc077b1..39bb5087d1 100644 --- a/services/web/app/views/subscriptions/dashboard.jade +++ b/services/web/app/views/subscriptions/dashboard.jade @@ -9,14 +9,14 @@ mixin printPlan(plan) strong #{plan.name} td -if (plan.annual) - | $#{plan.price / 100} / year + | $#{plan.price / 100} / #{translate("year")} -else - | $#{plan.price / 100} / month + | $#{plan.price / 100} / #{translate("month")} td -if (subscription.state == "free-trial") - a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-success Subscribe to this plan + a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-success #{translate("subscribe_to_this_plan")} -else if (plan.planCode == subscription.planCode) - button.btn.disabled Your plan + button.btn.disabled #{translate("your_plan")} -else form(action="/user/subscription/update",method="post") input(type="hidden", name="_csrf", value=csrfToken) @@ -34,44 +34,44 @@ block content .col-md-8.col-md-offset-2 .card .page-header - h1 Your Subscription + h1 #{translate("your_subscription")} case subscription.state when "free-trial" - p You are currently using a free trial which expires on #{subscription.expiresAt}. - p Choose a plan below to subscribe to. + p #{translate("on_free_trial_expiring_at", {expiresAt:"#{subscription.expiresAt}"})} + p #{translate("choose_a_plan_below")} when "active" - p You are currently subscribed to the #{subscription.name} plan. - a(href, ng-click="changePlan = true") Change Plan. - p The next payment of #{subscription.price} will be collected on #{subscription.nextPaymentDueAt} + p #{translate("currently_subscribed_to_plan", {planName:"#{subscription.name}"})} + a(href, ng-click="changePlan = true") #{translate("change_plan")}. + p #{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"#{subscription.price}", collectionDate:"#{subscription.nextPaymentDueAt}"})} p.pull-right p: form(action="/user/subscription/cancel",method="post") input(type="hidden", name="_csrf", value=csrfToken) - a(href="/user/subscription/billing-details/edit").btn.btn-info Update your billing details + a(href="/user/subscription/billing-details/edit").btn.btn-info #{translate("update_your_billing_details")} |   input(type="submit", value="Cancel your subscription").btn.btn-primary#cancelSubscription when "canceled" - p You are currently subscribed to the #{subscription.name} plan. - p Your subscription has been canceled and will terminate on #{subscription.nextPaymentDueAt}. No further payments will be taken. + p #{translate("currently_subscribed_to_plan", {planName:"#{subscription.name}"})} + p #{translate("subscription_canceled_and_terminate_on_x", {terminateDate:"#{subscription.nextPaymentDueAt}"})} p: form(action="/user/subscription/reactivate",method="post") input(type="hidden", name="_csrf", value=csrfToken) input(type="submit",value="Reactivate your subscription").btn.btn-success when "expired" - p Your subscription has expired. - a(href="/user/subscription/plans") Create New Subscription + p #{translate("your_subscription_has_expired")} + a(href="/user/subscription/plans") #{translate("create_new_subscription")} default - p There is a problem with your subscription. Please contact us for more information. + p #{translate("problem_with_subscription_contact_us")} -if(subscription.groupPlan) - a(href="/subscription/group").btn.btn-success Manage Group + a(href="/subscription/group").btn.btn-success #{translate("manage_group")} div(ng-show="changePlan", ng-cloak) hr - h2 Change plan + h2 #{translate("change_plan")} p: table.table tr - th Name - th Price + th #{translate("name")} + th #{translate("price")} th mixin printPlans(plans.studentAccounts) mixin printPlans(plans.individualMonthlyPlans) diff --git a/services/web/app/views/subscriptions/edit-billing-details.jade b/services/web/app/views/subscriptions/edit-billing-details.jade index b3fa4114d9..bc47efb4cb 100644 --- a/services/web/app/views/subscriptions/edit-billing-details.jade +++ b/services/web/app/views/subscriptions/edit-billing-details.jade @@ -11,8 +11,8 @@ block content .col-md-6.col-md-offset-3 .card .page-header - h1.text-centered Update Your Billing Details - #billingDetailsForm Loading billing details form... + h1.text-centered #{translate("update_your_billing_details")} + #billingDetailsForm #{translate("loading_billing_form")}... script(type="text/javascript"). diff --git a/services/web/app/views/subscriptions/group_admin.jade b/services/web/app/views/subscriptions/group_admin.jade index d75f93d1e9..ca3dec0478 100644 --- a/services/web/app/views/subscriptions/group_admin.jade +++ b/services/web/app/views/subscriptions/group_admin.jade @@ -8,13 +8,13 @@ block content .card(ng-controller="GroupMembersController") .page-header .pull-right(ng-cloak) - small(ng-show="selectedUsers.length == 0") You have added {{ users.length }} of {{ groupSize }} available members + small(ng-show="selectedUsers.length == 0") #{translate("you_have_added_x_of_group_size_y", {addedUsersSize:"{{ users.length }}", groupSize:"{{ groupSize }}"})} a.btn.btn-danger( href, ng-show="selectedUsers.length > 0" ng-click="removeMembers()" - ) Remove from group - h1 Group Account + ) #{translate("remove_from_group")} + h1 #{translate("group_account")} .row-spaced-small ul.list-unstyled.structured-list( @@ -28,11 +28,11 @@ block content select-all, type="checkbox" ) - span.header Email + span.header #{translate("email")} .col-md-5 - span.header Name + span.header #{translate("name")} .col-md-2 - span.header Registered + span.header #{translate("registered")} li.container-fluid( ng-repeat="user in users | orderBy:'email':true", ng-controller="GroupMemberListItemController" @@ -57,12 +57,12 @@ block content ) .row .col-md-12.text-centered - small No members + small #{translate("no_members")} div(ng-if="users.length < groupSize", ng-cloak) hr p - .small Add more members + .small #{translate("add_more_members")} form.form .row .col-xs-6 @@ -74,7 +74,7 @@ block content on-enter="addMembers()" ) .col-xs-6 - button.btn.btn-primary(ng-click="addMembers()") Add + button.btn.btn-primary(ng-click="addMembers()") #{translate("add")} script(type="text/javascript"). window.users = !{JSON.stringify(users)}; diff --git a/services/web/app/views/subscriptions/new.jade b/services/web/app/views/subscriptions/new.jade index 9852db25f8..0e6ea577c7 100644 --- a/services/web/app/views/subscriptions/new.jade +++ b/services/web/app/views/subscriptions/new.jade @@ -11,8 +11,8 @@ block content .col-md-6.col-md-offset-3 .card .page-header - h1.text-centered New Subscription - #subscribeForm Loading subscription form... + h1.text-centered #{translate("new_subscription")} + #subscribeForm #{translate("loading_billing_form")}... script(type="text/javascript") ga('send', 'event', 'pageview', 'payment_form', "#{plan_code}") diff --git a/services/web/app/views/subscriptions/plans.jade b/services/web/app/views/subscriptions/plans.jade index c390850246..6877fd9cfb 100644 --- a/services/web/app/views/subscriptions/plans.jade +++ b/services/web/app/views/subscriptions/plans.jade @@ -7,11 +7,11 @@ block content .row .col-md-12 .page-header.centered.plans-header.text-centered - h1 Start Your 30-Day Free Trial Today! + h1 #{translate("start_30_day_trial")} .row .col-md-8.col-md-offset-2 - p.text-centered ShareLaTeX is the world's easiest to use LaTeX editor. Stay up to date with your collaborators, keep track of all changes to your work, and use our LaTeX environment from anywhere in the world. + p.text-centered #{translate("sl_benefits_plans")} .row(ng-cloak) .col-md-12 @@ -20,55 +20,55 @@ block content a( href, ng-click="switchToMonthly()" - ) Monthly + ) #{translate("monthly")} li(ng-class="{'active': ui.view == 'annual'}") a( href ng-click="switchToAnnual()" - ) Annual + ) #{translate("annual")} li(ng-class="{'active': ui.view == 'student'}") a( href, ng-click="switchToStudent()" - ) Half Price Student Plans + ) #{translate("half_price_student")} .row(ng-cloak) .col-md-12 .card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'") .card .card-header - h2 Personal - .circle Free + h2 #{translate("personal")} + .circle #{translate("free")} ul.list-unstyled - li Only one collaborator + li #{translate("one_collaborator")} li   li   li br - a.btn.btn-info(href="/register") Sign up now + a.btn.btn-info(href="/register") #{translate("sign_up_now")} .card.highlighted .card-header - h2 Collaborator + h2 #{translate("collaborator")} .circle span(ng-if="ui.view == 'monthly'") | $15 span.small /mo span(ng-if="ui.view == 'annual'") | $180 - span.small/yr + span.small /yr ul.list-unstyled li - strong 10 collaborators per project - li Full document history - li Sync to Dropbox + strong #{translate("collabs_per_proj", {collabcount:10})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} li br a.btn.btn-info( ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '-annual' || ''}}_free_trial", ng-click="signUpNowClicked('collaborator')" - ) Start Free Trial! + ) #{translate("start_free_trial")} .card .card-header - h2 Professional + h2 #{translate("professional")} .circle span(ng-if="ui.view == 'monthly'") | $30 @@ -78,91 +78,91 @@ block content span.small /yr ul.list-unstyled li - strong Unlimited collaborators - li Full document history - li Sync to Dropbox + strong #{translate("unlimited_collabs")} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} li br a.btn.btn-info( ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || ''}}_free_trial", ng-click="signUpNowClicked('professional')" - ) Start Free Trial! + ) #{translate("start_free_trial")} .card-group.text-centered(ng-if="ui.view == 'student'") .card .card-header - h2 Personal - .circle Free + h2 #{translate("personal")} + .circle #{translate("free")} ul.list-unstyled - li Only one collaborator + li #{translate("one_collaborator")} li   li   li br - a.btn.btn-info(href="/register") Sign up now + a.btn.btn-info(href="/register") #{translate("sign_up_now")} .card.highlighted .card-header - h2 Student + h2 #{translate("student")} .circle span | $8 span.small /mo ul.list-unstyled li - strong 6 collaborators per project - li Full document history - li Sync to Dropbox + strong #{translate("collabs_per_proj", {collabcount:6})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} li br a.btn.btn-info( ng-href="#{baseUrl}/user/subscription/new?planCode=student_free_trial", ng-click="signUpNowClicked('student')" - ) Start Free Trial! + ) #{translate("start_free_trial")} .card .card-header - h2 Student (Annual) + h2 #{translate("student")} (#{translate("annual")}) .circle span | $80 span.small /yr ul.list-unstyled li - strong 6 collaborators per project - li Full document history - li Sync to Dropbox + strong #{translate("collabs_per_proj", {collabcount:6})} + li #{translate("full_doc_history")} + li #{translate("sync_to_dropbox")} li br a.btn.btn-info( ng-href="#{baseUrl}/user/subscription/new?planCode=stud-ann_free_trial", ng-click="signUpNowClicked('student')" - ) Start Free Trial! + ) #{translate("start_free_trial")} .row(ng-cloak) - p.text-centered Choose the plan that works for you with our 30-day free trial. Cancel at any time. + p.text-centered #{translate("start_free_trial")} #{translate("choose_plan_works_for_you")} .row(ng-cloak) .col-md-8.col-md-offset-2 .alert.alert-info.text-centered - | Interested in using ShareLaTeX with a group, team or department wide account? + | #{translate("interested_in_group_licence")} br - a(href, ng-click="openGroupPlanModal()") Get in touch for details! + a(href, ng-click="openGroupPlanModal()") #{translate("get_in_touch_for_details")} script(type="text/ng-template", id="groupPlanModalTemplate") .modal-header - h3 Group Plan Enquiry + h3 #{translate("group_plan_enquiry")} .modal-body form(name='form1', autocomplete='off', enctype='multipart/form-data', method='post', novalidate='', action='https://sharelatex.wufoo.com/forms/z7x3p3/#public', _lpchecked='1') .form-group - label(for='Field9') Name + label(for='Field9') #{translate("name")} input.form-control(name='Field9', type='text', value='', maxlength='255', tabindex='1', onkeyup='') .form-group - label(for='Field11') Email + label(for='Field11') #{translate("email")} input.form-control(name='Field11', type='email', spellcheck='false', value='', maxlength='255', tabindex='2') .form-group - label(for='Field12') University + label(for='Field12') #{translate("university")} input.form-control(name='Field12', type='text', value='', maxlength='255', tabindex='3', onkeyup='') .form-group - label(for='Field13') Position + label(for='Field13') #{translate("position")} input.form-control(name='Field13', type='text', value='', maxlength='255', tabindex='4', onkeyup='') .form-group @@ -176,19 +176,19 @@ block content .row .col-md-12 .page-header.plans-header.plans-subheader.text-centered - h2 Enjoy all of these great features + h2 #{translate("enjoy_these_features")} .col-md-4 .card.features.text-centered i.fa.fa-file-text-o.fa-5x - h4 Unlimited projects - p Create as many projects as you need. + h4 #{translate("unlimited_projects")} + p #{translate("create_unlimited_projects")} .col-md-4 .card.features.text-centered i.fa.fa-clock-o.fa-5x - h4 Full document history - p Never lose a step, we've got your back. + h4 #{translate("full_doc_history")} + p #{translate("never_loose_work")} .col-md-4 .card.features.text-centered i.fa.fa-dropbox.fa-5x - h4 Sync to Dropbox - p Access your projects everywhere. + h4 #{translate("sync_to_dropbox")} + p #{translate("access_projects_anywhere")} diff --git a/services/web/app/views/subscriptions/successful_subscription.jade b/services/web/app/views/subscriptions/successful_subscription.jade index 1e1fd24b3e..86d9484480 100644 --- a/services/web/app/views/subscriptions/successful_subscription.jade +++ b/services/web/app/views/subscriptions/successful_subscription.jade @@ -7,23 +7,22 @@ block content .col-md-8.col-md-offset-2 .card .page-header - h2 Thanks for subscribing! + h2 #{translate("thanks_for_subscribing")} .alert.alert-success - p Your card will be charged soon. - p The next payment of #{subscription.price} will be collected on #{subscription.nextPaymentDueAt}. - p If you do not want to be charged again - a(href="/user/subscription") click here to cancel. + p #{translate("your_card_will_be_charged_soon")} + p #{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"#{subscription.price}", collectionDate:"#{subscription.nextPaymentDueAt}"})} + p #{translate("if_you_dont_want_to_be_charged")} + a(href="/user/subscription") #{translate("click_here_to_cancel")}. p - if (subscription.groupPlan == true) - a.btn.btn-success.btn-large(href="/subscription/group") Add your first group members now + a.btn.btn-success.btn-large(href="/subscription/group") #{translate("add_your_first_group_member_now")} p.letter-from-founders - p Thank you for subscribing to the #{subscription.name} plan. It's support from people like yourself that allows ShareLaTeX to continue to grow and improve. - - p If there is anything you ever need please feel free to contact us directly at + p #{translate("thanks_for_subscribing_you_help_sl", {planName:subscription.name})} + p #{translate("need_anything_contact_us_at")} a(href='mailto:support@sharelatex.com') support@sharelatex.com - | . It goes straight to both our inboxes. - p Regards, + | . #{translate("goes_straight_to_our_inboxes")}. + p #{translate("regards")}, br | Henry and James .portraits @@ -33,4 +32,4 @@ block content span.img-circle img(src="/img/about/james_allen.jpg") p - a.btn.btn-primary(href="/project") < Back to your projects + a.btn.btn-primary(href="/project") < #{translate("back_to_your_projects")} diff --git a/services/web/app/views/templates/index.jade b/services/web/app/views/templates/index.jade index cd0717ba8e..d265af4f36 100644 --- a/services/web/app/views/templates/index.jade +++ b/services/web/app/views/templates/index.jade @@ -7,7 +7,7 @@ block content .col-md-2 h2 - a(href="/templates") Templates + a(href="/templates") #{translate("templates")} .col-md-8 form.project-search.form-horizontal(role="form") .form-group.has-feedback.has-feedback-left.col-md-12 diff --git a/services/web/app/views/templates/tag.jade b/services/web/app/views/templates/tag.jade index 2ac601a596..4ee7e70b76 100644 --- a/services/web/app/views/templates/tag.jade +++ b/services/web/app/views/templates/tag.jade @@ -6,7 +6,7 @@ block content .row .page-header h2 - a(href="/templates") Templates + a(href="/templates") #{translate("templates")} | › a(href=tag.tagPagePath) #{tag.name} .row diff --git a/services/web/app/views/templates/template.jade b/services/web/app/views/templates/template.jade index 50c2db74fb..d403bfa576 100644 --- a/services/web/app/views/templates/template.jade +++ b/services/web/app/views/templates/template.jade @@ -6,7 +6,7 @@ block content .row .page-header h2 - a(href="/templates") Templates + a(href="/templates") #{translate("templates")} | › - if(tag) a(href=tag.tagPagePath) #{tag.name} @@ -22,7 +22,7 @@ block content .col-md-6 .template-details-section - h3 About + h3 #{translate("about")} div !{template.description} div(ng-controller="openInSlController").download-buttons a.btn.btn-primary.btn-large(href=template.open_in_sharelatex_url, ng-click='open()', ng-disabled="isDisabled", rel='nofollow') {{openInSlText}} @@ -47,7 +47,7 @@ block content a.addthis_button_compact script(type='text/javascript', src='//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-517c16586439faa7') - h3 Comment + h3 #{translate("comment")} #disqus_thread script(type='text/javascript'). /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ diff --git a/services/web/app/views/user/login.jade b/services/web/app/views/user/login.jade index 132aa4fbf9..aa200d5db3 100644 --- a/services/web/app/views/user/login.jade +++ b/services/web/app/views/user/login.jade @@ -7,7 +7,7 @@ block content .col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4 .card .page-header - h1 Log In + h1 #{translate("log_in")} form(async-form="login", name="loginForm", action='/login', ng-cloak) input(name='_csrf', type='hidden', value=csrfToken) input(name='redir', type='hidden', value=redir) @@ -23,7 +23,7 @@ block content focus="true" ) span.small.text-primary(ng-show="loginForm.email.$invalid && loginForm.email.$dirty") - | Must be an email address + | #{translate("must_be_email_address")} .form-group input.form-control( type='password', @@ -33,12 +33,12 @@ block content ng-model="password" ) span.small.text-primary(ng-show="loginForm.password.$invalid && loginForm.password.$dirty") - | Required + | #{translate("required")} .actions button.btn-primary.btn( type='submit', ng-disabled="loginForm.inflight" ) - span(ng-show="!loginForm.inflight") Login - span(ng-show="loginForm.inflight") Logging in... - a.pull-right(href='/user/password/reset') Forgot your password? + span(ng-show="!loginForm.inflight") #{translate("login")} + span(ng-show="loginForm.inflight") #{translate("logging_in")}... + a.pull-right(href='/user/password/reset') #{translate("forgot_your_password")}? diff --git a/services/web/app/views/user/passwordReset.jade b/services/web/app/views/user/passwordReset.jade index 11957138d8..4db644d916 100644 --- a/services/web/app/views/user/passwordReset.jade +++ b/services/web/app/views/user/passwordReset.jade @@ -7,7 +7,7 @@ block content .col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4 .card .page-header - h1 Password Reset + h1 #{translate("password_reset")} .messageArea form( async-form="password-reset-request", @@ -18,9 +18,9 @@ block content input(type="hidden", name="_csrf", value=csrfToken) form-messages(for="passwordResetForm") .alert.alert-success(ng-show="passwordResetForm.response.success") - | You have been sent an email to complete your password reset. + | #{translate("password_reset_email_sent")} .form-group - label(for='email') Please enter your email address + label(for='email') #{translate("please_enter_email")} input.form-control( type='email', name='email', @@ -31,9 +31,9 @@ block content ) span.small.text-primary( ng-show="passwordResetForm.email.$invalid && passwordResetForm.email.$dirty" - ) Must be a valid email address + ) #{translate("must_be_email_address")} .actions button.btn.btn-primary( type='submit', ng-disabled="passwordResetForm.$invalid" - ) Request password reset + ) #{translate("request_password_reset")} diff --git a/services/web/app/views/user/register.jade b/services/web/app/views/user/register.jade index a2faf4fe25..0b9010d0cc 100644 --- a/services/web/app/views/user/register.jade +++ b/services/web/app/views/user/register.jade @@ -6,24 +6,25 @@ block content .row .registration_message if sharedProjectData.user_first_name !== undefined - h1 #{sharedProjectData.user_first_name} would like you to view '#{sharedProjectData.project_name}' - div Join ShareLaTeX to view this project + h1 #{translate("user_wants_you_to_see_project", {username:sharedProjectData.user_first_name, projectname:sharedProjectData.project_name})} + div #{translate("join_sl_to_view_project")} else if newTemplateData.templateName !== undefined - h1 Please register to edit the '#{newTemplateData.templateName}' template - div Already have a ShareLaTeX account? - a(href="/login") Login here + h1 #{translate("register_to_edit_template", {templatename:newTemplateData.templateName})} + + div #{translate("already_have_sl_account")} + a(href="/login") #{translate("login_here")} .row .col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4 .card .page-header - h1 Register + h1 #{translate("register")} form(async-form="register", name="registerForm", action="/register", ng-cloak) input(name='_csrf', type='hidden', value=csrfToken) input(name='redir', type='hidden', value=redir) form-messages(for="registerForm") .form-group - label(for='email') Email + label(for='email') #{translate("email")} input.form-control( type='email', name='email', @@ -35,9 +36,9 @@ block content focus="true" ) span.small.text-primary(ng-show="registerForm.email.$invalid && registerForm.email.$dirty") - | Must be an email address + | #{translate("must_be_email_address")} .form-group - label(for='password') Password + label(for='password') #{translate("password")} input.form-control( type='password', name='password', @@ -46,11 +47,11 @@ block content ng-model="password" ) span.small.text-primary(ng-show="registerForm.password.$invalid && registerForm.password.$dirty") - | Required + | #{translate("required")} .actions button.btn-primary.btn( type='submit' ng-disabled="registerForm.inflight" ) - span(ng-show="!registerForm.inflight") Register - span(ng-show="registerForm.inflight") Registering... + span(ng-show="!registerForm.inflight") #{translate("register")} + span(ng-show="registerForm.inflight") #{translate("registering")}... diff --git a/services/web/app/views/user/restricted.jade b/services/web/app/views/user/restricted.jade index 4c4ebcd52a..99d9099e23 100644 --- a/services/web/app/views/user/restricted.jade +++ b/services/web/app/views/user/restricted.jade @@ -6,8 +6,8 @@ block content .row .col-md-8.col-md-offset-2.text-center .page-header - h2 Restricted, sorry you don't have permission to load this page. + h2 #{translate("restricted_no_permission")} p a(href="/") i.fa.fa-arrow-circle-o-left - | Take me home! \ No newline at end of file + | #{translate("take_me_home")} \ No newline at end of file diff --git a/services/web/app/views/user/setPassword.jade b/services/web/app/views/user/setPassword.jade index 067a0dfecb..815f0030ca 100644 --- a/services/web/app/views/user/setPassword.jade +++ b/services/web/app/views/user/setPassword.jade @@ -7,7 +7,7 @@ block content .col-md-6.col-md-offset-3.col-lg-4.col-lg-offset-4 .card .page-header - h1 Reset your password + h1 #{translate("reset_your_password")} form( async-form="password-reset", name="passwordResetForm", @@ -17,8 +17,8 @@ block content input(type="hidden", name="_csrf", value=csrfToken) form-messages(for="passwordResetForm") .alert.alert-success(ng-show="passwordResetForm.response.success") - | Your password has been reset. - a(href='/login') Login here + | #{translate("password_has_been_reset")} + a(href='/login') #{translate("login_here")} .form-group input.form-control( @@ -31,7 +31,7 @@ block content ) span.small.text-primary( ng-show="passwordResetForm.password.$invalid && passwordResetForm.password.$dirty" - ) Required + ) #{translate("required")} input( type="hidden", name="passwordResetToken", @@ -41,4 +41,4 @@ block content button.btn.btn-primary( type='submit', ng-disabled="passwordResetForm.$invalid" - ) Set new password \ No newline at end of file + ) #{translate("set_new_password")} \ No newline at end of file diff --git a/services/web/app/views/user/settings.jade b/services/web/app/views/user/settings.jade index 2934748b01..3cf36a5012 100644 --- a/services/web/app/views/user/settings.jade +++ b/services/web/app/views/user/settings.jade @@ -7,20 +7,20 @@ block content .col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 .card .page-header - h1 Account Settings + h1 #{translate("account_settings")} .account-settings(ng-controller="AccountSettingsController", ng-cloak) form-messages(for="settingsForm") .alert.alert-success(ng-show="settingsForm.response.success") - | Thanks, your settings have been updated. + | #{translate("thanks_settings_updated")} form-messages(for="changePasswordForm") .container-fluid .row .col-md-5 - h3 Update Account Info + h3 #{translate("update_account_info")} form(async-form="settings", name="settingsForm", action="/user/settings", novalidate) input(type="hidden", name="_csrf", value=csrfToken) .form-group - label(for='email') Email + label(for='email') #{translate("email")} input.form-control( type='email', name='email', @@ -31,16 +31,16 @@ block content ng-model-options="{ updateOn: 'blur' }" ) span.small.text-primary(ng-show="settingsForm.email.$invalid && settingsForm.email.$dirty") - | Must be an email address + | #{translate("must_be_email_address")} .form-group - label(for='firstName').control-label First Name + label(for='firstName').control-label #{translate("first_name")} input.form-control( type='text', name='first_name', value=user.first_name ) .form-group - label(for='lastName').control-label Last Name + label(for='lastName').control-label #{translate("last_name")} input.form-control( type='text', name='last_name', @@ -50,14 +50,14 @@ block content button.btn.btn-primary( type='submit', ng-disabled="settingsForm.$invalid" - ) Update + ) #{translate("update")} .col-md-5.col-md-offset-1 - h3 Change Password + h3 #{translate("change_password")} form(async-form="changepassword", name="changePasswordForm", action="/user/password/update", novalidate) input(type="hidden", name="_csrf", value=csrfToken) .form-group - label(for='currentPassword') Current Password + label(for='currentPassword') #{translate("current_password")} input.form-control( type='password', name='currentPassword', @@ -66,9 +66,9 @@ block content required ) span.small.text-primary(ng-show="changePasswordForm.currentPassword.$invalid && changePasswordForm.currentPassword.$dirty") - | Required + | #{translate("required")} .form-group - label(for='newPassword1') New Password + label(for='newPassword1') #{translate("new_password")} input.form-control( id='newPassword1', type='password', @@ -78,9 +78,9 @@ block content required ) span.small.text-primary(ng-show="changePasswordForm.newPassword1.$invalid && changePasswordForm.newPassword1.$dirty") - | Required + | #{translate("required")} .form-group - label(for='newPassword2') Confirm New Password + label(for='newPassword2') #{translate("confirm_new_password")} input.form-control( type='password', name='newPassword2', @@ -89,60 +89,57 @@ block content equals="newPassword1" ) span.small.text-primary(ng-show="changePasswordForm.newPassword2.$invalid && changePasswordForm.newPassword2.$dirty") - | Doesn't match + | #{translate("doesnt_match")} .actions button.btn.btn-primary( type='submit', ng-disabled="changePasswordForm.$invalid" - ) Change + ) #{translate("change")} hr.soften - h3 Dropbox Integration + h3 #{translate("dropbox_integration")} span.small - a(href='/help/kb/dropbox-2') (Learn more) + a(href='/help/kb/dropbox-2') (#{translate("learn_more")}) - if(!userHasDropboxFeature) - .alert.alert-info Dropbox sync is a premium feature     - a.btn.btn-info(href='/user/subscription/plans') Upgrade + .alert.alert-info #{translate("dropbox_is_premium")}     + a.btn.btn-info(href='/user/subscription/plans') #{translate("upgrade")} - else if(userIsRegisteredWithDropbox) - .alert.alert-success Account is linked! + .alert.alert-success #{translate("account_is_linked")} row - a(href='/dropbox/unlink').btn Unlink Dropbox + a(href='/dropbox/unlink').btn #{translate("unlink_dropbox")} - else - a.btn.btn-info(href='/dropbox/beginAuth') Link to dropbox + a.btn.btn-info(href='/dropbox/beginAuth') #{translate("link_to_dropbox")} hr.soften p.small - | Every few months we send a newsletter out summarizing the new features available. - | If you would prefer not to receive this email then you can unsubscribe at any time: + | #{translate("newsletter_info_and_unsubscribe")} a( href, ng-click="unsubscribe()", ng-show="subscribed && !unsubscribing" - ) Unsubscribe + ) #{translate("unsubscribe")} span( ng-show="unsubscribing" ) - i.fa.fa-spin.fa-refresh - | Unsubscribing + i.fa.fa-spin.fa-refresh + | #{translate("unsubscribing")} span.text-success( ng-show="!subscribed" ) i.fa.fa-check - | Unsubscribed + | #{translate("unsubscribed")} - p Need to leave? - a(href, ng-click="deleteAccount()") Delete your account + p #{translate("need_to_leave")} + a(href, ng-click="deleteAccount()") #{translate("delete_your_account")} script(type='text/ng-template', id='deleteAccountModalTemplate') .modal-header - h3 Delete Account + h3 #{translate("delete_account")} .modal-body - p - | You are about to permanently delete all of your account data, including your projects - | and settings. Please type DELETE into the box below to proceed. + p !{translate("delete_account_warning_message")} form(novalidate, name="deleteAccountForm") input.form-control( type="text", @@ -154,11 +151,11 @@ block content .modal-footer button.btn.btn-default( ng-click="cancel()" - ) Cancel + ) #{translate("cancel")} button.btn.btn-danger( ng-disabled="!state.isValid || state.inflight" ng-click="delete()" ) - span(ng-hide="state.inflight") Delete - span(ng-show="state.inflight") Deleting... + span(ng-hide="state.inflight") #{translate("delete")} + span(ng-show="state.inflight") #{translate("deleting")}... diff --git a/services/web/config/settings.defaults.coffee b/services/web/config/settings.defaults.coffee index 8f28bf9fae..212cc3b926 100644 --- a/services/web/config/settings.defaults.coffee +++ b/services/web/config/settings.defaults.coffee @@ -107,6 +107,11 @@ module.exports = # that are sent out, generated links, etc. siteUrl : 'http://localhost:3000' + # cooke domain + # use full domain for cookies to only be accesabble from that domain, + # replace subdomain with dot to have them accessable on all subdomains + # cookieDomain: ".sharelatex.dev" + # Same, but with http auth credentials. httpAuthSiteUrl: 'http://#{httpAuthUser}:#{httpAuthPass}@localhost:3000' @@ -134,6 +139,13 @@ module.exports = features: defaultFeatures }] + + # i18n + # ------ + # + i18n: + defaultLng:"en-US" + # Spelling languages # ------------------ # diff --git a/services/web/public/coffee/main.coffee b/services/web/public/coffee/main.coffee index f8ea3aa273..da6e361893 100644 --- a/services/web/public/coffee/main.coffee +++ b/services/web/public/coffee/main.coffee @@ -18,6 +18,5 @@ define [ "directives/selectAll" "directives/maxHeight" "filters/formatDate" - ], () -> angular.bootstrap(document.body, ["SharelatexApp"]) diff --git a/services/web/public/coffee/main/project-list.coffee b/services/web/public/coffee/main/project-list.coffee index f18b9eda6d..c552dad532 100644 --- a/services/web/public/coffee/main/project-list.coffee +++ b/services/web/public/coffee/main/project-list.coffee @@ -1,7 +1,9 @@ define [ "base" ], (App) -> - App.factory "queuedHttp", ["$http", "$q", ($http, $q) -> + + + App.factory "queuedHttp", ($http, $q) -> pendingRequests = [] inflight = false @@ -48,8 +50,6 @@ define [ return queuedHttp - ] - App.controller "ProjectPageController", ($scope, $modal, $q, $window, queuedHttp, event_tracking, $timeout) -> $scope.projects = window.data.projects $scope.tags = window.data.tags diff --git a/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee b/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee index 45c370e185..f6d55d2a4a 100644 --- a/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Authentication/AuthenticationControllerTests.coffee @@ -96,10 +96,11 @@ describe "AuthenticationController", -> @AuthenticationController.login(@req, @res) it "should return an error", -> - expect(@res.body).to.deep.equal - message: - text: 'Your email or password were incorrect. Please try again', - type: 'error' + # @res.body.should.exist + expect(@res.body.message).to.exist + # message: + # text: 'Your email or password were incorrect. Please try again', + # type: 'error' it "should not establish a session", -> @AuthenticationController._establishUserSession.called.should.equal false diff --git a/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee b/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee index 187719dcd3..6b9968318e 100644 --- a/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/PasswordReset/PasswordResetControllerTests.coffee @@ -30,6 +30,8 @@ describe "PasswordResetController", -> email:@email passwordResetToken:@token password:@password + i18n: + translate:-> @res = {} diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee index 5df9d5d1e2..78bb13c617 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee @@ -78,7 +78,6 @@ describe "Subscription controller sanboxed", -> it "should set the correct variables for the template", -> should.exist @res.renderedVariables.signature - @res.renderedVariables.title.should.equal "Update Billing Details" @res.renderedVariables.successURL.should.equal "#{Settings.siteUrl}/user/subscription/update" @res.renderedVariables.user.id.should.equal @user.id @@ -137,9 +136,6 @@ describe "Subscription controller sanboxed", -> @res.callback = done @SubscriptionController.successful_subscription @req, @res - it "should render the thank you page", -> - @res.renderedVariables.title.should.equal "Thank you!" - describe "userSubscriptionPage", -> describe "with a user without a subscription", -> beforeEach (done) -> @@ -164,7 +160,6 @@ describe "Subscription controller sanboxed", -> done() it "should set the correct subscription details", -> - @res.renderedVariables.title.should.equal "Your Subscription" @res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription describe "with a user with a free trial", -> @@ -175,11 +170,9 @@ describe "Subscription controller sanboxed", -> @SubscriptionController.userSubscriptionPage @req, @res it "should render the dashboard", -> - @res.rendered.should.equal true @res.renderedTemplate.should.equal "subscriptions/dashboard" it "should set the correct subscription details", -> - @res.renderedVariables.title.should.equal "Your Subscription" @res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription describe "createSubscription", -> diff --git a/services/web/test/UnitTests/coffee/helpers/MockRequest.coffee b/services/web/test/UnitTests/coffee/helpers/MockRequest.coffee index 61a54f11c3..9c83844654 100644 --- a/services/web/test/UnitTests/coffee/helpers/MockRequest.coffee +++ b/services/web/test/UnitTests/coffee/helpers/MockRequest.coffee @@ -5,6 +5,8 @@ class MockRequest params: {} query: {} + i18n: + translate:-> module.exports = MockRequest