Merge branch 'master' into quickform

Conflicts:
	.meteor/versions
	client/views/settings/quickFormSettings.html
	collections/posts.js
	lib/router.js
	packages/telescope-api/versions.json
	packages/telescope-base/versions.json
	packages/telescope-module-embedly/versions.json
	packages/telescope-module-share/versions.json
	packages/telescope-notifications/versions.json
	packages/telescope-rss/versions.json
	packages/telescope-theme-base/versions.json
	packages/telescope-theme-hubble/versions.json
This commit is contained in:
Sacha Greif 2014-11-26 11:22:54 +09:00
commit b8dc56ea40
208 changed files with 5971 additions and 3582 deletions

6
.gitignore vendored
View file

@ -24,4 +24,8 @@ settings.json
scratch
.deploy
.deploy/*
.deploy/*
### Meteor template
.meteor/local
.meteor/meteorite
mup.json

View file

@ -4,3 +4,4 @@
notices-for-0.9.0
notices-for-0.9.1
0.9.4-platform-file

View file

@ -13,60 +13,64 @@ accounts-twitter
spiderable
email
accounts-facebook
service-configuration
accounts-ui
# Atmosphere Packages
iron:router@0.9.1
iron:router
meteorhacks:fast-render@1.0.0
meteorhacks:subs-manager@1.1.0
meteorhacks:fast-render
meteorhacks:subs-manager
meteorhacks:npm
aldeed:autoform@4.0.0-rc1
aldeed:collection2
aldeed:simple-schema
mrt:jquery-hotkeys@0.0.1
mrt:cookies@0.3.0
mrt:jquery-hotkeys
mrt:cookies
mrt:moment
mrt:mailchimp
cmather:handlebars-server@0.2.0
tmeasday:crypto-md5@3.1.2
sacha:spin@2.0.4
cmather:handlebars-server
sacha:spin
sacha:juice
chuangbo:marked@0.3.3
percolatestudio:synced-cron@0.1.1
chuangbo:marked
percolatestudio:synced-cron
npm-container
matb33:collection-hooks
djedi:sanitize-html
rajit:bootstrap3-datepicker
bengott:avatar
jparker:gravatar
# Telescope Packages
tap:i18n
# Telescope Packages (Required)
telescope-tags
telescope-base
telescope-search
telescope-lib
telescope-rss
telescope-api
telescope-module-share
telescope-theme-base
telescope-theme-hubble
telescope-daily
telescope-newsletter
telescope-module-embedly
telescope-i18n
# Telescope Packages (Optional)
telescope-theme-base
telescope-module-share
telescope-api
telescope-rss
telescope-search
telescope-tags
telescope-theme-hubble
telescope-email
telescope-module-embedly
telescope-newsletter
telescope-daily
telescope-update-prompt
telescope-notifications
telescope-kadira
telescope-update-prompt
telescope-notifications
telescope-kadira
# Accounts Templates
service-configuration
accounts-ui
splendido:accounts-templates-unstyled
useraccounts:unstyled

2
.meteor/platforms Normal file
View file

@ -0,0 +1,2 @@
server
browser

View file

@ -1 +1 @@
METEOR@0.9.3.1
METEOR@1.0

View file

@ -1,104 +1,113 @@
accounts-base@1.1.1
accounts-facebook@1.0.1
accounts-oauth@1.1.1
accounts-password@1.0.2
accounts-twitter@1.0.1
accounts-ui-unstyled@1.1.2
accounts-ui@1.1.1
aldeed:autoform@4.0.0-rc1
aldeed:collection2@2.1.0
aldeed:simple-schema@1.0.3
application-configuration@1.0.2
autoupdate@1.1.1
accounts-base@1.1.2
accounts-facebook@1.0.2
accounts-oauth@1.1.2
accounts-password@1.0.4
accounts-twitter@1.0.2
accounts-ui-unstyled@1.1.4
accounts-ui@1.1.3
aldeed:autoform@4.0.2
aldeed:collection2@2.2.0
aldeed:simple-schema@1.1.0
application-configuration@1.0.3
artwells:queue@0.0.3
autoupdate@1.1.3
backbone@1.0.0
base64@1.0.0
bengott:avatar@0.1.1
binary-heap@1.0.0
blaze-tools@1.0.0
blaze@2.0.1
boilerplate-generator@1.0.0
callback-hook@1.0.0
check@1.0.1
base64@1.0.1
bengott:avatar@0.6.0
binary-heap@1.0.1
blaze-tools@1.0.1
blaze@2.0.3
boilerplate-generator@1.0.1
callback-hook@1.0.1
check@1.0.2
chuangbo:cookie@1.1.0
chuangbo:marked@0.3.5
cmather:handlebars-server@0.2.0
coffeescript@1.0.3
ctl-helper@1.0.3
ctl@1.0.1
ddp@1.0.9
deps@1.0.4
cmather:handlebars-server@2.0.0
coffeescript@1.0.4
ctl-helper@1.0.4
ctl@1.0.2
ddp@1.0.11
deps@1.0.5
djedi:sanitize-html@1.3.0
ejson@1.0.3
email@1.0.3
facebook@1.1.0
fastclick@1.0.0
follower-livedata@1.0.1
geojson-utils@1.0.0
handlebars@1.0.0
html-tools@1.0.1
htmljs@1.0.1
http@1.0.6
id-map@1.0.0
iron:core@0.3.4
iron:dynamic-template@0.4.1
iron:layout@0.4.1
iron:router@0.9.4
ejson@1.0.4
email@1.0.4
facebook@1.1.2
fastclick@1.0.1
follower-livedata@1.0.2
geojson-utils@1.0.1
handlebars@1.0.1
html-tools@1.0.2
htmljs@1.0.2
http@1.0.8
id-map@1.0.1
iron:controller@1.0.0
iron:core@1.0.3
iron:dynamic-template@1.0.3
iron:layout@1.0.3
iron:location@1.0.3
iron:middleware-stack@1.0.0
iron:router@1.0.1
iron:url@1.0.3
jparker:crypto-core@0.1.0
jparker:crypto-md5@0.1.1
jquery@1.0.0
json@1.0.0
kestanous:herald-email@0.2.1
kestanous:herald@0.6.0
less@1.0.9
livedata@1.0.10
localstorage@1.0.0
logging@1.0.3
jparker:gravatar@0.3.0
jquery@1.0.1
json@1.0.1
kestanous:herald-email@0.4.2
kestanous:herald@1.1.3
launch-screen@1.0.0
less@1.0.11
livedata@1.0.11
localstorage@1.0.1
logging@1.0.5
matb33:collection-hooks@0.7.6
meteor-platform@1.1.1
meteor@1.1.1
meteor-platform@1.2.0
meteor@1.1.3
meteorhacks:async@1.0.0
meteorhacks:fast-render@1.1.2
meteorhacks:kadira-binary-deps@1.2.0
meteorhacks:kadira@2.11.2
meteorhacks:npm@1.2.0
meteorhacks:subs-manager@1.1.0
minifiers@1.1.0
minimongo@1.0.3
mobile-status-bar@1.0.0
mongo-livedata@1.0.5
mongo@1.0.6
meteorhacks:fast-render@1.2.1
meteorhacks:kadira-binary-deps@1.3.1
meteorhacks:kadira@2.14.0
meteorhacks:meteorx@1.2.0
meteorhacks:npm@1.2.1
meteorhacks:subs-manager@1.2.0
minifiers@1.1.2
minimongo@1.0.5
mobile-status-bar@1.0.1
mongo-livedata@1.0.6
mongo@1.0.8
mrt:cookies@0.3.0
mrt:jquery-hotkeys@0.0.1
mrt:mailchimp@0.4.0
mrt:moment@2.8.1
npm-bcrypt@0.7.7
npm-container@1.0.0
oauth1@1.1.0
oauth2@1.1.0
oauth@1.1.0
observe-sequence@1.0.2
ordered-dict@1.0.0
percolatestudio:synced-cron@0.3.0
oauth1@1.1.2
oauth2@1.1.1
oauth@1.1.2
observe-sequence@1.0.3
ordered-dict@1.0.1
percolatestudio:synced-cron@1.0.0
rajit:bootstrap3-datepicker@1.3.1
random@1.0.0
reactive-dict@1.0.3
reactive-var@1.0.2
reload@1.1.0
retry@1.0.0
routepolicy@1.0.1
random@1.0.1
reactive-dict@1.0.4
reactive-var@1.0.3
reload@1.1.1
retry@1.0.1
routepolicy@1.0.2
sacha:juice@0.1.0
sacha:spin@2.0.4
service-configuration@1.0.1
session@1.0.2
sha@1.0.0
softwarerero:accounts-t9n@1.0.0
spacebars-compiler@1.0.2
spacebars@1.0.2
spiderable@1.0.3
splendido:accounts-templates-core@0.9.9
splendido:accounts-templates-unstyled@0.9.9
srp@1.0.0
standard-app-packages@1.0.2
stylus@1.0.4
service-configuration@1.0.2
session@1.0.4
sha@1.0.1
softwarerero:accounts-t9n@1.0.2
spacebars-compiler@1.0.3
spacebars@1.0.3
spiderable@1.0.5
srp@1.0.1
standard-app-packages@1.0.3
stylus@1.0.5
tap:http-methods@0.0.23
tap:i18n@1.2.1
telescope-api@0.0.0
telescope-base@0.0.0
telescope-daily@0.0.0
@ -116,13 +125,13 @@ telescope-tags@0.0.0
telescope-theme-base@0.0.0
telescope-theme-hubble@0.0.0
telescope-update-prompt@0.1.0
templating@1.0.7
tmeasday:crypto-base@3.1.2
tmeasday:crypto-md5@3.1.2
tracker@1.0.2
twitter@1.1.0
ui@1.0.3
underscore@1.0.0
url@1.0.0
webapp-hashing@1.0.0
webapp@1.1.2
templating@1.0.9
tracker@1.0.3
twitter@1.1.2
ui@1.0.4
underscore@1.0.1
url@1.0.2
useraccounts:core@1.2.3
useraccounts:unstyled@1.2.3
webapp-hashing@1.0.1
webapp@1.1.4

View file

@ -1,3 +1,21 @@
## v0.9.10 “i18nScope”
* Now using [tap:i18n](https://github.com/TAPevents/tap-i18n) for internationalization (thanks a ton to @theosp).
* Each package is now i18n'd invididually.
* Chinese i18n code is now `zh-CN`, not `zh`.
* Various fixes (thanks @anthonymayer).
* Upgrade Avatar package (thanks @bengott).
## v0.9.9
* Updating to Meteor 1.0.
* Updating to Iron Router 1.0.
* Adding view counter (thanks @steffenstraetz! See [PR #489](https://github.com/TelescopeJS/Telescope/pull/489))
* Splitting out `router.js` in multiple files.
* URL can now be removed when editing a post (thanks @massimilianomarini! See [PR 484](https://github.com/TelescopeJS/Telescope/pull/484)).
* Now waiting on `allUsersAdmin` subscription for post submit page (thanks @kai101! See [PR 508](https://github.com/TelescopeJS/Telescope/pull/508))
* Putting server-side routes for email template tests in their own respective packages.
## v0.9.8
* Fixing #457 (pending posts view not working).

View file

@ -40,7 +40,3 @@ Statuses={
approved: 2,
rejected: 3
};
Avatar.options = {
emailHashProperty: 'email_hash'
};

View file

@ -42,7 +42,7 @@ UI.registerHelper('isAdmin', function(showError) {
return true;
}else{
if((typeof showError === "string") && (showError === "true"))
throwError(i18n.t('Sorry, you do not have access to this page'));
throwError(i18n.t('sorry_you_do_not_have_access_to_this_page'));
return false;
}
});
@ -60,9 +60,15 @@ UI.registerHelper('log', function(context){
});
UI.registerHelper("formatDate", function(datetime, format) {
Session.get('momentLocale'); // depend on session variable to reactively rerun the helper
return moment(datetime).format(format);
});
UI.registerHelper("timeAgo", function(datetime) {
Session.get('momentLocale'); // depend on session variable to reactively rerun the helper
return moment(datetime).fromNow()
});
UI.registerHelper("sanitize", function(content) {
console.log('cleaning up…')
console.log(content)

View file

@ -36,5 +36,5 @@ postHeading = _.sortBy(postHeading, 'order');
postMeta = _.sortBy(postMeta, 'order');
Meteor.startup(function () {
$('#rss-link').attr('title', i18n.t('New Posts'));
$('#rss-link').attr('title', i18n.t('new_posts'));
});

View file

@ -1,5 +1,5 @@
<template name="comment_deleted">
<div class="grid-small grid-block">
<p>{{i18n "Your comment has been deleted."}}</p>
<p>{{_ "your_comment_has_been_deleted"}}</p>
</div>
</template>

View file

@ -3,12 +3,12 @@
{{#with comment}}
<form class="grid-block form-horizontal">
<div class="control-group">
<label class="control-label">{{i18n "Comment"}}</label>
<label class="control-label">{{_ "comment_"}}</label>
<div class="controls comment-field" id="editor"><textarea id="body" value="" class="input-xlarge">{{body}}</textarea></div>
</div>
<div class="form-actions">
<a class="delete-link" href="/comments/deleted">{{i18n "Delete Comment"}}</a>
<input type="submit" class="button" value="{{i18n "Submit"}}" title="(⌘+enter)" />
<a class="delete-link" href="/comments/deleted">{{_ "delete_comment"}}</a>
<input type="submit" class="button" value="{{_ "submit"}}" title="(⌘+enter)" />
</div>
</form>
{{/with}}

View file

@ -20,7 +20,7 @@ Template[getTemplate('comment_edit')].events({
e.preventDefault();
if(!Meteor.user())
throw i18n.t('You must be logged in.');
throw i18n.t('you_must_be_logged_in');
Comments.update(comment._id, {
$set: {
@ -36,7 +36,7 @@ Template[getTemplate('comment_edit')].events({
e.preventDefault();
if(confirm(i18n.t("Are you sure?"))){
if(confirm(i18n.t("are_you_sure"))){
Meteor.call('removeComment', comment._id);
Router.go("/posts/"+comment.postId);
throwError("Your comment has been deleted.");

View file

@ -6,7 +6,7 @@
<textarea id="comment" rows="3" autofocus="autofocus"></textarea>
</div>
<div class="comment-submit">
<input type="submit" class="button" value="{{i18n "Add Comment"}}" title="(⌘+enter)" />
<input type="submit" class="button" value="{{_ "add_comment"}}" title="(⌘+enter)" />
</div>
</form>
</div>

View file

@ -8,22 +8,22 @@
<div class="comment-actions {{#if upvoted}}upvoted{{else}}not-upvoted{{/if}} {{#if downvoted}}downvoted{{else}}not-downvoted{{/if}}">
<a class="upvote" href="#">
<i class="icon-up"></i>
<span>{{i18n "upvote"}}</span>
<span>{{_ "upvote"}}</span>
</a>
<a class="downvote" href="#">
<i class="icon-down"></i>
<span>{{i18n "downvote"}}</span>
<span>{{_ "downvote"}}</span>
</a>
</div>
<div class="user-avatar">{{>avatar userId=userId cssClass="avatar circle"}}</div>
<div class="user-avatar">{{> avatar userId=userId shape="circle"}}</div>
<div class="comment-main">
<div class="comment-meta">
<a class="comment-username" href="{{profileUrl}}">{{authorName}}</a>
<span class="comment-time">{{ago}},</span>
<span class="comment-time">{{timeAgo ago}},</span>
<span class="points">{{upvotes}}</span> <span class="unit">points </span>
<a href="/comments/{{_id}}" class="comment-permalink icon-link goto-comment">{{i18n "link"}}</a>
<a href="/comments/{{_id}}" class="comment-permalink icon-link goto-comment">{{_ "link"}}</a>
{{#if can_edit}}
| <a class="edit-link" href="/comments/{{_id}}/edit">{{i18n "Edit"}}</a>
| <a class="edit-link" href="/comments/{{_id}}/edit">{{_ "edit"}}</a>
{{/if}}
{{#if isAdmin}}
| <span>{{full_date}}</span>
@ -31,7 +31,7 @@
</div>
<div class="comment-text markdown">{{{htmlBody}}}</div>
{{#if getSetting "nestedComments" true}}
<a href="/comments/{{_id}}" class="comment-reply goto-comment">{{i18n "Reply"}}</a>
<a href="/comments/{{_id}}" class="comment-reply goto-comment">{{_ "reply"}}</a>
{{/if}}
</div>
</div>

View file

@ -91,7 +91,7 @@ Template[getTemplate('comment_item')].helpers({
return true;
},
ago: function(){
return moment(this.createdAt).fromNow();
return this.createdAt;
},
upvoted: function(){
return Meteor.user() && _.include(this.upvoters, Meteor.user()._id);
@ -153,7 +153,7 @@ Template[getTemplate('comment_item')].events({
e.preventDefault();
if(!Meteor.user()){
Router.go(getSigninUrl());
throwError(i18n.t("Please log in first"));
throwError(i18n.t("please_log_in_first"));
}
Meteor.call('upvoteComment', this, function(error, result){
trackEvent("post upvoted", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId});
@ -163,7 +163,7 @@ Template[getTemplate('comment_item')].events({
e.preventDefault();
if(!Meteor.user()){
Router.go(getSigninUrl());
throwError(i18n.t("Please log in first"));
throwError(i18n.t("please_log_in_first"));
}
Meteor.call('cancelUpvoteComment', this, function(error, result){
trackEvent("post upvote cancelled", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId});
@ -173,7 +173,7 @@ Template[getTemplate('comment_item')].events({
e.preventDefault();
if(!Meteor.user()){
Router.go(getSigninUrl());
throwError(i18n.t("Please log in first"));
throwError(i18n.t("please_log_in_first"));
}
Meteor.call('downvoteComment', this, function(error, result){
trackEvent("post downvoted", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId});
@ -183,7 +183,7 @@ Template[getTemplate('comment_item')].events({
e.preventDefault();
if(!Meteor.user()){
Router.go(getSigninUrl());
throwError(i18n.t("Please log in first"));
throwError(i18n.t("please_log_in_first"));
}
Meteor.call('cancelDownvoteComment', this, function(error, result){
trackEvent("post downvote cancelled", {'commentId':instance.data._id, 'postId': instance.data.post, 'authorId':instance.data.userId});

View file

@ -1,5 +1,5 @@
<template name="already_logged_in">
<div class="grid-small grid-block dialog">
<p>{{i18n "You are already logged in"}}</p>
<p>{{_ "you_are_already_logged_in"}}</p>
</div>
</template>

View file

@ -1,9 +1,9 @@
<template name="no_account">
<div class="grid-small grid-block dialog">
<p>{{i18n "Sorry, this is a private site. Please sign up first."}}</p>
<p>{{_ "sorry_this_is_a_private_site_please_sign_up_first"}}</p>
{{landingPageText}}
<div class="twitter-signup twitter-auth">
<a class="twitter-button button" href="#">{{i18n "Sign In/Sign Up with Twitter"}}</a>
<a class="twitter-button button" href="#">{{_ "sign_in_sign_up_with_twitter"}}</a>
</div>
</div>
</template>

View file

@ -1,7 +1,7 @@
<template name="no_invite">
<div class="grid-small grid-block dialog">
<h2>{{i18n "Thanks for signing up!"}}</h2>
<h2>{{_ "thanks_for_signing_up"}}</h2>
{{afterSignupText}}
<p>{{i18n "The site is currently invite-only, but we will let you know as soon as a spot opens up."}}</p>
<p>{{_ "the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up"}}</p>
</div>
</template>

View file

@ -1,5 +1,5 @@
<template name="no_rights">
<div class="grid-small grid-block dialog">
{{i18n "Sorry, you don't have the rights to view this page."}}
{{_ "sorry_you_dont_have_the_rights_to_view_this_page"}}
</div>
</template>

View file

@ -1,6 +1,6 @@
<template name="notFound">
<div class="grid-small grid-block dialog">
<h2>{{i18n "Not Found!"}}</h2>
<p>{{i18n "We're sorry; whatever you were looking for isn't here.."}}</p>
<h2>{{_ "not_found"}}</h2>
<p>{{_ "were_sorry_whatever_you_were_looking_for_isnt_here"}}</p>
</div>
</template>

View file

@ -1,7 +1,7 @@
<template name="adminMenu">
{{#if isAdmin}}
<div class="dropdown header-submodule admin-menu">
<a class="admin dropdown-top-level" href="/">{{i18n "Admin"}}</a>
<a class="admin dropdown-top-level" href="/">{{_ "admin"}}</a>
<div class="dropdown-menu">
<ul role="menu" aria-labelledby="dLabel">
{{#each menu}}

View file

@ -1,3 +1,3 @@
<template name="menuItem">
<li><a class="dropdown-sub-level" href="{{pathFor route}}">{{i18n label}}</a></li>
<li><a class="dropdown-sub-level" href="{{pathFor route}}">{{_ label}}</a></li>
</template>

View file

@ -1,5 +1,5 @@
<template name="submitButton">
{{#if canPost}}
<a id="submit" class="submit button header-submodule" href="/submit">{{i18n "Post"}}</a>
<a id="submit" class="submit button header-submodule" href="/submit">{{_ "post"}}</a>
{{/if}}
</template>

View file

@ -4,14 +4,14 @@
<a class="view dropdown-top-level" href="/">{{name}}</a>
<div class="dropdown-menu">
<ul role="menu" aria-labelledby="dLabel">
<li><a href="{{profileUrl}}">{{i18n "Profile"}}</a></li>
<li><a href="/account">{{i18n "Edit Account"}}</a></li>
<li><a href="/sign-out">{{i18n "Sign Out"}}</a></li>
<li><a href="{{profileUrl}}">{{_ "profile"}}</a></li>
<li><a href="/account">{{_ "edit_account"}}</a></li>
<li><a href="/sign-out">{{_ "sign_out"}}</a></li>
</ul>
</div>
</div>
{{else}}
<a class="account-link sign-in" href="/sign-in">{{i18n "Sign In"}}</a>
<a class="account-link sign-up" href="/sign-up">{{i18n "Sign Up"}}</a>
<a class="account-link sign-in" href="/sign-in">{{_ "sign_in"}}</a>
<a class="account-link sign-up" href="/sign-up">{{_ "sign_up"}}</a>
{{/if}}
</template>

View file

@ -1,7 +1,7 @@
<template name="viewsMenu">
{{#if canView}}
<div class="dropdown header-submodule views-menu">
<a class="view dropdown-top-level" href="/">{{i18n "View"}}</a>
<a class="view dropdown-top-level" href="/">{{_ "view"}}</a>
<div class="dropdown-menu">
<ul role="menu" aria-labelledby="dLabel">
{{#each views}}

View file

@ -4,12 +4,12 @@
{{#if postsMustBeApproved}}
|
{{#if isApproved}}
<a href="#" class="unapprove-link goto-edit">Unapprove</a>
<a href="#" class="unapprove-link goto-edit">{{_ "unapprove"}}</a>
{{else}}
<a href="#" class="approve-link goto-edit">Approve</a>
<a href="#" class="approve-link goto-edit">{{_ "approve"}}</a>
{{/if}}
{{/if}}
| {{i18n "score"}}: {{shortScore}}, {{i18n "clicks"}}: {{clicks}}
| {{_ "score"}}: {{shortScore}}, {{_ "clicks"}}: {{clickCount}}, {{_ "views"}}: {{viewCount}}
</div>
{{/if}}
</template>

View file

@ -1,8 +1,8 @@
<template name="postCommentsLink">
<div class="post-meta-item">
<a class="comments-link" href="/posts/{{_id}}">
<span class="count">{{commentsCount}}</span>
<span class="action">{{i18n 'Comments'}}</span>
<span class="count">{{commentCount}}</span>
<span class="action">{{_ 'comments_'}}</span>
</a>
</div>
</template>

View file

@ -1,7 +1,7 @@
<template name="postDiscuss">
<a class="discuss-link go-to-comments" href="/posts/{{_id}}">
<i class="icon-comment"></i>
<span class="count">{{commentsCount}}</span>
<span class="action">{{i18n 'Discuss'}}</span>
<span class="count">{{commentCount}}</span>
<span class="action">{{_ 'discuss'}}</span>
</a>
</template>

View file

@ -1,8 +1,8 @@
<template name="postInfo">
<div class="post-meta-item">
<span class="points">{{baseScore}} <span class="unit">{{pointsUnitDisplayText}} </span></span>by <a class="post-author" href="{{profileUrl}}">{{authorName}}</a> <span class="post-time">{{ago}}</span>
<span class="points">{{baseScore}} <span class="unit">{{pointsUnitDisplayText}} </span></span>by <a class="post-author" href="{{profileUrl}}">{{authorName}}</a> <span class="post-time">{{timeAgo ago}}</span>
{{#if can_edit}}
| <a href="/posts/{{_id}}/edit" class="edit-link goto-edit">Edit</a>
| <a href="/posts/{{_id}}/edit" class="edit-link goto-edit">{{_ "edit"}}</a>
{{/if}}
</div>
</template>

View file

@ -11,7 +11,7 @@ Template[getTemplate('postInfo')].helpers({
ago: function(){
// if post is approved show submission time, else show creation time.
time = this.status == STATUS_APPROVED ? this.postedAt : this.createdAt;
return moment(time).fromNow();
return time;
},
profileUrl: function(){
// note: we don't want the post to be re-rendered every time user properties change

View file

@ -1,8 +1,8 @@
<template name="postUpvote">
<div class="post-rank"><span>{{oneBasedRank}}</span></div>
{{#if upvoted}}
<span class="upvote-link voted"><i class="icon-check"></i><span>{{i18n "Upvoted"}}</span></span>
<span class="upvote-link voted"><i class="icon-check"></i><span>{{_ "upvoted"}}</span></span>
{{else}}
<a class="upvote-link not-voted" href="#"><i class="icon-up"></i><span>{{i18n "Upvote"}}</span></a>
<a class="upvote-link not-voted" href="#"><i class="icon-up"></i><span>{{_ "upvote_"}}</span></a>
{{/if}}
</template>

View file

@ -16,7 +16,7 @@ Template[getTemplate('postUpvote')].events({
e.preventDefault();
if(!Meteor.user()){
Router.go(getSigninUrl());
throwError(i18n.t("Please log in first"));
throwError(i18n.t("please_log_in_first"));
}
Meteor.call('upvotePost', post, function(error, result){
trackEvent("post upvoted", {'_id': post._id});

View file

@ -1,5 +1,5 @@
<template name="post_deleted">
<div class="grid-small grid-block">
<p>{{i18n "Your post has been deleted."}}</p>
<p>{{_ "your_post_has_been_deleted"}}</p>
</div>
</template>

View file

@ -3,30 +3,30 @@
{{#with post}}
<form class="grid-block form-horizontal">
<div class="control-group">
<label class="control-label post-form-headline">{{i18n "Created"}}</label>
<label class="control-label post-form-headline">{{_ "created"}}</label>
<div class="controls"><p>{{created}}</p></div>
</div>
<div class="control-group">
<label class="control-label post-form-headline">{{i18n "Title"}}</label>
<label class="control-label post-form-headline">{{_ "title"}}</label>
<div class="controls"><input id="title" type="text" value="{{title}}" /></div>
</div>
<div class="control-group">
<label class="control-label post-form-url">{{i18n "URL"}}</label>
<label class="control-label post-form-url">{{_ "url"}}</label>
<div class="controls"><input id="url" type="text" value="{{url}}" /></div>
</div>
{{#if shorten}}
<div class="control-group">
<label class="control-label post-form-url">{{i18n "Short URL"}}</label>
<label class="control-label post-form-url">{{_ "short_url"}}</label>
<div class="controls"><input id="short-url" type="text" value="{{shortUrl}}" /></div>
</div>
{{/if}}
<div class="control-group">
<label class="control-label post-form-body">{{i18n "Body"}}</label>
<label class="control-label post-form-body">{{_ "body"}}</label>
<div class="controls" id="editor"><textarea id="body" value="" class="input-xlarge">{{body}}</textarea></div>
</div>
{{#if categoriesEnabled}}
<div class="control-group post-form-category">
<label class="control-label">{{i18n "Categories"}}</label>
<label class="control-label">{{_ "categories"}}</label>
<div class="controls">
{{#each categories}}
<label class="radio inline">
@ -38,19 +38,19 @@
{{/if}}
{{#if isAdmin}}
<div class="control-group post-form-sticky">
<label class="control-label">{{i18n "Inactive?"}}</label>
<label class="control-label">{{_ "inactive_"}}</label>
<div class="controls">
{{inactive}}
</div>
</div>
<div class="control-group post-form-sticky">
<label class="control-label">{{i18n "Sticky?"}}</label>
<label class="control-label">{{_ "sticky_"}}</label>
<div class="controls">
<input type="checkbox" name="sticky" id="sticky" {{isSticky}} />
</div>
</div>
<div class="control-group post-form-user">
<label class="control-label">{{i18n "User"}}</label>
<label class="control-label">{{_ "user"}}</label>
<div class="controls">
<select id="postUser">
{{#each users}}
@ -60,33 +60,33 @@
</div>
</div>
<div class="control-group post-form-status">
<label class="control-label">{{i18n "Status"}}</label>
<label class="control-label">{{_ "status_"}}</label>
<div class="controls">
<label class="radio inline">
<input id="status_pending" type="radio" value="1" name="status" {{hasStatusPending}} /> {{i18n "Pending"}}
<input id="status_pending" type="radio" value="1" name="status" {{hasStatusPending}} /> {{_ "pending"}}
</label>
<label class="radio inline">
<input id="status_approved" type="radio" value="2" name="status" {{hasStatusApproved}} /> {{i18n "Approved"}}
<input id="status_approved" type="radio" value="2" name="status" {{hasStatusApproved}} /> {{_ "approved"}}
</label>
<label class="radio inline">
<input id="status_rejected" type="radio" value="3" name="status" {{hasStatusRejected}} /> {{i18n "Rejected"}}
<input id="status_rejected" type="radio" value="3" name="status" {{hasStatusRejected}} /> {{_ "rejected"}}
</label>
</div>
</div>
<div id="postedAt" class={{showPostedAt}}>
<div class="control-group">
<label class="control-label post-form-date">{{i18n "Posted Date"}}</label>
<label class="control-label post-form-date">{{_ "posted_date"}}</label>
<div class="controls"><input id="postedAtDate" type="text" value="{{postedAtDate}}" /></div>
</div>
<div class="control-group">
<label class="control-label post-form-time">{{i18n "Posted Time"}}</label>
<label class="control-label post-form-time">{{_ "posted_time"}}</label>
<div class="controls"><input id="postedAtTime" type="text" value="{{postedAtTime}}" /></div>
</div>
</div>
{{/if}}
<div class="form-actions">
<a class="delete-link" href="/posts/deleted">{{i18n "Delete Post"}}</a>
<input type="submit" class="button" value="{{i18n "Submit"}}" />
<a class="delete-link" href="/posts/deleted">{{_ "delete_post"}}</a>
<input type="submit" class="button" value="{{_ "submit"}}" />
</div>
</form>
{{/with}}

View file

@ -80,6 +80,7 @@ Template[getTemplate('post_edit')].events({
},
'click input[type=submit]': function(e, instance){
var post = this;
var updateObject = {};
e.preventDefault();
@ -107,6 +108,9 @@ Template[getTemplate('post_edit')].events({
var url = $('#url').val();
if(!!url){
properties.url = (url.substring(0, 7) == "http://" || url.substring(0, 8) == "https://") ? url : "http://"+url;
} else {
// if URL is empty, unset it
updateObject.$unset = {url: ""};
}
// ShortURL
@ -175,13 +179,14 @@ Template[getTemplate('post_edit')].events({
// ------------------------------ Update ------------------------------ //
if (properties) {
Posts.update(post._id,{
$set: properties
}, function(error){
if (properties) {
updateObject.$set = properties;
Posts.update(post._id, updateObject, function(error){
if(error){
console.log(error);
throwError(error.reason);
throwError(error.message);
clearSeenErrors();
$(e.target).removeClass('disabled');
}else{

View file

@ -7,20 +7,20 @@
<!-- <div class="grid submit">
<form class="grid-block form-horizontal">
<div class="control-group">
<label class="control-label">{{i18n "URL"}}</label>
<label class="control-label">{{_ "url"}}</label>
<div class="controls"><input id="url" type="text" value="" /></div>
</div>
<div class="control-group">
<label class="control-label">{{i18n "Title"}}</label>
<div class="controls"><input id="title" type="text" value="" /><a href="#" class="get-title-link inline-link">{{i18n "Suggest title"}}</a></div>
<label class="control-label">{{_ "title"}}</label>
<div class="controls"><input id="title" type="text" value="" /><a href="#" class="get-title-link inline-link">{{_ "suggest_title"}}</a></div>
</div>
<div class="control-group">
<label class="control-label">{{i18n "Body"}}</label>
<label class="control-label">{{_ "body"}}</label>
<div class="controls" id="editor"><textarea id="body" value="" class="input-xlarge"></textarea></div>
</div>
{{#if categoriesEnabled}}
<div class="control-group">
<label class="control-label">{{i18n "Category"}}</label>
<label class="control-label">{{_ "category"}}</label>
<div class="controls">
{{#each categories}}
<label class="radio inline">
@ -32,13 +32,13 @@
{{/if}}
{{#if isAdmin}}
<div class="control-group">
<label class="control-label">{{i18n "Sticky?"}}</label>
<label class="control-label">{{_ "sticky_"}}</label>
<div class="controls">
<input type="checkbox" name="sticky" id="sticky" />
</div>
</div>
<div class="control-group">
<label class="control-label">{{i18n "User"}}</label>
<label class="control-label">{{_ "user"}}</label>
<div class="controls">
<select id="postUser">
{{#each users}}
@ -48,33 +48,33 @@
</div>
</div>
<div class="control-group">
<label class="control-label">{{i18n "Status"}}</label>
<label class="control-label">{{_ "status_"}}</label>
<div class="controls">
<label class="radio inline">
<input id="status_pending" type="radio" value="1" name="status"/> {{i18n "Pending"}}
<input id="status_pending" type="radio" value="1" name="status"/> {{_ "pending"}}
</label>
<label class="radio inline">
<input id="status_approved" type="radio" value="2" name="status" checked /> {{i18n "Approved"}}
<input id="status_approved" type="radio" value="2" name="status" checked /> {{_ "approved"}}
</label>
<label class="radio inline">
<input id="status_rejected" type="radio" value="3" name="status"/> {{i18n "Rejected"}}
<input id="status_rejected" type="radio" value="3" name="status"/> {{_ "rejected"}}
</label>
</div>
</div>
<div id="postedAt" class={{showPostedAt}}>
<div class="control-group">
<label class="control-label post-form-date">{{i18n "Posted Date"}}</label>
<label class="control-label post-form-date">{{_ "posted_date"}}</label>
<div class="controls"><input id="postedAtDate" type="text" value="{{postedAtDate}}" /></div>
</div>
<div class="control-group">
<label class="control-label post-form-time">{{i18n "Posted Time"}}</label>
<label class="control-label post-form-time">{{_ "posted_time"}}</label>
<div class="controls"><input id="postedAtTime" type="text" value="{{postedAtTime}}" /></div>
</div>
<p class="help-block">Leave blank to post at current time.</p>
<p class="help-block">{{_ "leave_blank_to_post_at_current_time"}}</p>
</div>
{{/if}}
<div class="form-actions">
<input type="submit" class="button" value="{{i18n "Submit"}}" />
<input type="submit" class="button" value="{{_ "submit"}}" />
</div>
</form>
</div> -->

View file

@ -54,7 +54,7 @@ Template[getTemplate('post_submit')].events({
// ------------------------------ Checks ------------------------------ //
if(!Meteor.user()){
throwError(i18n.t('You must be logged in.'));
throwError(i18n.t('you_must_be_logged_in'));
return false;
}

View file

@ -1,13 +1,13 @@
<template name="posts_digest">
<div class="grid">
<div class="grid-block">
{{i18n "The top 5 posts of each day."}} |
{{_ "the_top_5_posts_of_each_day"}} |
{{#if showPreviousDate}}
<a href="{{previousDateURL}}" class="prev-link">{{i18n "Previous Day"}}</a> |
<a href="{{previousDateURL}}" class="prev-link">{{_ "previous_day"}}</a> |
{{/if}}
{{currentDate}} |
{{#if showNextDate}}
<a href="{{nextDateURL}}" class="next-link">{{i18n "Next Day"}}</a>
<a href="{{nextDateURL}}" class="next-link">{{_ "next_day"}}</a>
{{/if}}
</div>
</div>
@ -22,7 +22,7 @@
</div>
{{else}}
<div class="grid-small grid-block dialog">
<p>{{i18n "Sorry, no posts for"}} {{currentDate}}.</p>
<p>{{_ "sorry_no_posts_for"}} {{currentDate}}.</p>
</div>
{{/if}}
</template>

View file

@ -27,9 +27,9 @@ Template[getTemplate('posts_digest')].helpers({
var today=moment(new Date());
var diff=today.diff(currentDate, 'days');
if(diff === 0)
return i18n.t("Today");
return i18n.t("today");
if(diff === 1)
return i18n.t("Yesterday");
return i18n.t("yesterday");
return currentDate.format("dddd, MMMM Do YYYY");
},
previousDateURL: function(){

View file

@ -2,7 +2,7 @@
{{#if count}}
<a class="more-button show-new grid-module" href="">
<span>
{{i18n "View"}} {{count}} {{i18n "new"}} {{pluralize count "post"}}
{{_ "view"}} {{count}} {{_ "new"}} {{pluralize count "post"}}
</span>
</a>
{{/if}}

View file

@ -1,6 +1,6 @@
<template name="postsLoadMore">
{{#if hasMorePosts}}
<a class="more-button grid-module" href="{{loadMoreUrl}}"><span>{{i18n "Load more"}}</span></a>
<a class="more-button grid-module" href="{{loadMoreUrl}}"><span>{{_ "load_more"}}</span></a>
{{else}}
{{#unless ready}}
<div class="grid loading-module">

View file

@ -1,7 +1,7 @@
Template[getTemplate('postsLoadMore')].helpers({
hasMorePosts: function(){
// as long as we ask for N posts and all N posts showed up, then keep showing the "load more" button
return parseInt(Session.get('postsLimit')) == this.postsCount
return parseInt(Session.get('postsLimit')) == this.postCount
},
loadMoreUrl: function () {
var count = parseInt(Session.get('postsLimit')) + parseInt(getSetting('postsPerPage', 10));

View file

@ -0,0 +1,97 @@
<template name="quickForm_settings">
{{#autoForm qfAutoFormContext}}
{{#each afFieldsets}}
<fieldset>
<h3 class="fieldset-heading">{{this}}</h3>
{{> afQuickFields fields=fieldsForFieldset omitFields=../atts.omitFields template="settings" input-col-class=inputClass label-class=labelClass}}
</fieldset>
{{/each}}
{{#if qfShouldRenderButton}}
<div class="form-group">
<div class="{{labelClass}}"></div>
<div class="{{inputClass}}">
<button {{submitButtonAtts}}>
{{#with ../atts.buttonContent}}
{{this}}
{{else}}
Submit
{{/with}}
</button>
</div>
</div>
{{/if}}
{{/autoForm}}
</template>
<template name="afFormGroup_settings">
{{#if showField}}
<div class="form-group {{#if afFieldIsInvalid name=this.atts.name}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name=this.atts.name}}</label>
<div class="{{rightColumnClass}}">
{{> afFieldInput afFieldInputAtts}}
{{#if afFieldInstructions}}
<span class="instructions-block">{{afFieldInstructions}}</span>
{{/if}}
<span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
</div>
</div>
{{/if}}
</template>
<template name="afObjectField_settings">
<div class="form-group {{#if afFieldIsInvalid name=this.atts.name}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name=this.atts.name}}</label>
<div class="{{rightColumnClass}}">
<div class="panel panel-default autoform-padding-fix">
<div class="panel-body">
{{> afQuickFields name=this.atts.name fields=this.atts.fields omitFields=this.atts.omitFields template="bootstrap3"}}
</div>
</div>
</div>
</div>
</template>
<template name="afArrayField_settings">
<div class="form-group {{#if afFieldIsInvalid name=this.atts.name}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name=this.atts.name}}</label>
<div class="{{rightColumnClass}}">
<div class="panel panel-default autoform-padding-fix">
{{#if afFieldIsInvalid name=this.atts.name}}
<div class="panel-body has-error">
<span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
</div>
{{/if}}
<ul class="list-group">
{{#afEachArrayItem name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item autoform-array-item">
<div class="media">
{{#if afArrayFieldHasMoreThanMinimum name=../atts.name minCount=../atts.minCount maxCount=../atts.maxCount}}
<button class="btn btn-primary autoform-remove-item pull-left"><span class="glyphicon glyphicon-minus"></span></button>
{{/if}}
<div class="media-body">
{{> afQuickField name=this.name label=false}}
</div>
</div>
</li>
{{/afEachArrayItem}}
{{#if afArrayFieldHasLessThanMaximum name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item">
<button class="btn btn-primary autoform-add-item" data-autoform-field="{{this.atts.name}}" data-autoform-minCount="{{this.atts.minCount}}" data-autoform-maxCount="{{this.atts.maxCount}}"><span class="glyphicon glyphicon-plus"></span></button>
</li>
{{/if}}
</ul>
</div>
</div>
</div>
</template>
<template name="afCheckbox_settings">
<div class="checkbox">
<label>
<input type="checkbox" value="{{this.value}}" {{atts}} />aaaa
</label>
</div>
</template>

View file

@ -3,13 +3,13 @@
{{#with user}}
{{#if profileIncomplete}}
<div>
{{i18n "Please complete your profile below before continuing."}}
{{_ "please_complete_your_profile_below_before_continuing"}}
</div>
{{/if}}
<form id="account-form">
<h2>{{i18n "Account"}}</h2>
<h2>{{_ "account"}}</h2>
<div class="control-group">
<label>{{i18n "Username"}}</label>
<label>{{_ "username"}}</label>
<div class="controls">
<input id="username" name="username" disabled="disabled" type="text" value="{{userName}}" />
</div>
@ -22,19 +22,19 @@
</div>
</div> -->
<div class="control-group">
<label>{{i18n "Display Name"}}</label>
<label>{{_ "display_name"}}</label>
<div class="controls">
<input name="name" type="text" value="{{profile.name}}" />
</div>
</div>
<div class="control-group">
<label>{{i18n "Email"}}</label>
<label>{{_ "email"}}</label>
<div class="controls">
<input name="email" type="text" value="{{userEmail}}" />
</div>
</div>
<div class="control-group">
<label>{{i18n "Bio"}}</label>
<label>{{_ "bio"}}</label>
<div class="controls"><textarea name="bio" type="text">{{profile.bio}}</textarea></div>
</div>
<div class="control-group">
@ -56,18 +56,18 @@
</div>
</div>
{{#if hasPassword}}
<h3>{{i18n "Change Password?"}}</h3>
<h3>{{_ "change_password"}}</h3>
<div class="control-group">
<label>{{i18n "Old Password"}}</label>
<label>{{_ "old_password"}}</label>
<div class="controls"><input name="old_password" type="password" value="" /></div>
</div>
<div class="control-group">
<label>{{i18n "New Password"}}</label>
<label>{{_ "new_password"}}</label>
<div class="controls"><input name="new_password" type="password" value="" /></div>
</div>
{{/if}}
<div class="control-group">
<label class="control-label">{{i18n "Email Notifications"}}</label>
<label class="control-label">{{_ "email_notifications"}}</label>
<div class="controls">
{{#if isAdmin}}
<label class="checkbox">
@ -75,13 +75,13 @@
</label>
{{/if}}
<label class="checkbox">
<input id="notifications_posts" type="checkbox" name="notifications_posts" {{hasNotificationsPosts}} /> {{i18n "New Posts"}}
<input id="notifications_posts" type="checkbox" name="notifications_posts" {{hasNotificationsPosts}} /> {{_ "new_posts"}}
</label>
<label class="checkbox">
<input id="notifications_comments" type="checkbox" name="notifications_comments" {{hasNotificationsComments}} /> {{i18n "Comments on my posts"}}
<input id="notifications_comments" type="checkbox" name="notifications_comments" {{hasNotificationsComments}} /> {{_ "comments_on_my_posts"}}
</label>
<label class="checkbox">
<input id="notifications_replies" type="checkbox" name="notifications_replies" {{hasNotificationsReplies}} /> {{i18n "Replies to my comments"}}
<input id="notifications_replies" type="checkbox" name="notifications_replies" {{hasNotificationsReplies}} /> {{_ "replies_to_my_comments"}}
</label>
</div>
</div>
@ -95,8 +95,8 @@
</div>
{{/if}}
<div class="form-actions">
<a href="/forgot-password">{{i18n "Forgot password?"}}</a>
<input type="submit" class="button" value="{{i18n "Submit"}}" />
<a href="/forgot-password">{{_ "forgot_password"}}</a>
<input type="submit" class="button" value="{{_ "submit"}}" />
</div>
</form>
{{/with}}

View file

@ -40,16 +40,17 @@ Template[getTemplate('user_edit')].events({
clearSeenErrors();
if(!Meteor.user())
throwError(i18n.t('You must be logged in.'));
throwError(i18n.t('you_must_be_logged_in'));
var $target=$(e.target);
var name = $target.find('[name=name]').val();
var email = $target.find('[name=email]').val();
var user = this;
var update = {
"profile.name": name,
"profile.slug": slugify(name),
"profile.bio": $target.find('[name=bio]').val(),
"profile.email": $target.find('[name=email]').val(),
"profile.email": email,
"profile.twitter": $target.find('[name=twitter]').val(),
"profile.github": $target.find('[name=github]').val(),
"profile.site": $target.find('[name=site]').val(),
@ -76,7 +77,7 @@ Template[getTemplate('user_edit')].events({
if(error){
throwError(error.reason);
} else {
throwError(i18n.t('Profile updated'));
throwError(i18n.t('profile_updated'));
}
Deps.afterFlush(function() {
var element = $('.grid > .error');
@ -84,7 +85,7 @@ Template[getTemplate('user_edit')].events({
});
});
Meteor.call('setEmailHash', user);
Meteor.call('changeEmail', email);
}

View file

@ -2,22 +2,22 @@
<div class="grid-small grid-block dialog user-edit">
{{#with user}}
<div>
{{i18n "Please fill in your email below to finish signing up."}}
{{_ "please_fill_in_your_email_below_to_finish_signing_up"}}
</div>
<form>
<div class="control-group">
<label>{{i18n "Username"}}</label>
<label>{{_ "username"}}</label>
<div class="controls">
<input name="username" type="text" value="{{username}}" />
</div>
<br>
<label>{{i18n "Email"}}</label>
<label>{{_ "email"}}</label>
<div class="controls">
<input name="email" type="text" value="{{profile.email}}" />
</div>
</div>
<div class="form-actions">
<input type="submit" class="button" value="{{i18n "Submit"}}" />
<input type="submit" class="button" value="{{_ "submit"}}" />
</div>
</form>
{{/with}}

View file

@ -10,7 +10,7 @@ Template[getTemplate('user_email')].helpers({
Template[getTemplate('user_email')].events({
'submit form': function(e){
e.preventDefault();
if(!Meteor.user()) throwError(i18n.t('You must be logged in.'));
if(!Meteor.user()) throwError(i18n.t('you_must_be_logged_in'));
var $target=$(e.target);
var user=Session.get('selectedUserId')? Meteor.users.findOne(Session.get('selectedUserId')) : Meteor.user();
var update = {
@ -28,7 +28,7 @@ Template[getTemplate('user_email')].events({
if(error){
throwError(error.reason);
} else {
throwError(i18n.t('Thanks for signing up!'));
throwError(i18n.t('thanks_for_signing_up'));
// Meteor.call('addCurrentUserToMailChimpList');
trackEvent("new sign-up", {'userId': user._id, 'auth':'twitter'});
Router.go('/');

View file

@ -1,6 +1,6 @@
<template name="user_item">
<tr class="user">
<td>{{>avatar user=this cssClass="avatar circle"}}</td>
<td>{{> avatar user=this shape="circle"}}</td>
<td>
<a href="{{getProfileUrl}}">{{displayName}}</a>
<br/>
@ -12,23 +12,23 @@
<td>{{getKarma}}</td>
<td>
{{#if invites}}
<h4>{{i18n "Invited"}} {{invitedCount}} {{i18n "users"}}:</h4>
<h4>{{_ "invited"}} {{invitedCount}} {{_ "users"}}:</h4>
<ul>
{{#each invites}}
<li><a href="{{getInvitedUserProfileUrl}}">{{invitedName}}</a></li>
{{/each}}
</ul>
{{/if}}
<p>({{inviteCount}} {{i18n "invites left"}})</p>
<p>({{inviteCount}} {{_ "invites_left"}})</p>
</td>
<td>{{#if isInvited}}<i class="icon-check"></i>{{/if}}</td>
<td>{{#if userIsAdmin}}<i class="icon-check"></i>{{/if}}</td>
<td>
<ul>
<li>{{#if isInvited}}<a class="uninvite-link" href="#">{{i18n "Uninvite"}}</a>{{else}}<a href="#" class="invite-link">{{i18n "Invite"}}</a>{{/if}}</li>
<li>{{#if userIsAdmin}}<a class="unadmin-link" href="#">{{i18n "Unadmin"}}</a>{{else}}<a href="#" class="admin-link">{{i18n "Make admin"}}</a>{{/if}}</li>
<li><a class="delete-link" href="#">{{i18n "Delete User"}}</a></li>
<li>{{#if isInvited}}<a class="uninvite-link" href="#">{{_ "uninvite"}}</a>{{else}}<a href="#" class="invite-link">{{_ "invite"}}</a>{{/if}}</li>
<li>{{#if userIsAdmin}}<a class="unadmin-link" href="#">{{_ "unadmin"}}</a>{{else}}<a href="#" class="admin-link">{{_ "make_admin"}}</a>{{/if}}</li>
<li><a class="delete-link" href="#">{{_ "delete_user"}}</a></li>
</ul>
</td>
</tr>
</template>
</template>

View file

@ -52,7 +52,7 @@ Template[getTemplate('user_item')].events({
},
'click .delete-link': function(e, instance){
e.preventDefault();
if(confirm(i18n.t("Are you sure you want to delete ")+getDisplayName(instance.data)+"?"))
if(confirm(i18n.t("are_you_sure_you_want_to_delete")+getDisplayName(instance.data)+"?"))
Meteor.users.remove(instance.data._id);
}
});

View file

@ -3,24 +3,24 @@
<div class="user-profile grid grid-module">
<table>
<tr>
<td colspan="2">{{>avatar user=this cssClass="avatar large circle"}}</td>
<td colspan="2">{{> avatar user=this size="large" shape="circle"}}</td>
</tr>
{{#if isAdmin}}
<tr>
<td>{{i18n "ID"}}: </td>
<td>{{_ "id"}}: </td>
<td>{{_id}}</td>
</tr>
{{/if}}
<tr>
<td>{{i18n "Name:"}}</td>
<td>{{_ "name"}}</td>
<td>{{profile.name}}</td>
</tr>
<tr>
<td>{{i18n "Member since"}}:</td>
<td>{{_ "member_since"}}:</td>
<td>{{createdAtFormatted}}</td>
</tr>
<tr>
<td>{{i18n "Bio:"}}</td>
<td>{{_ "bio"}}</td>
<td>{{profile.bio}}</td>
</tr>
{{#if getTwitterName}}
@ -31,31 +31,31 @@
{{/if}}
{{#if getGitHubName}}
<tr>
<td>{{i18n "GitHub"}}:</td>
<td>{{_ "github"}}:</td>
<td><a href="http://github.com/{{getGitHubName}}">{{getGitHubName}}</a></td>
</tr>
{{/if}}
{{#if profile.site}}
<tr>
<td>{{i18n "Site"}}:</td>
<td>{{_ "site"}}:</td>
<td><a href="{{profile.site}}">{{profile.site}}</a></td>
</tr>
{{/if}}
</table>
{{#if canEditProfile}}
<a class="button inline" href="/users/{{slug}}/edit">{{i18n "Edit profile"}}</a>
<a class="button inline" href="/users/{{slug}}/edit">{{_ "edit_profile"}}</a>
{{/if}}
{{#if canInvite}}
{{#if inviteCount}}
<a class="button inline invite-link" href="#">{{i18n "Invite"}} ({{inviteCount}} {{i18n "left"}})</a>
<a class="button inline invite-link" href="#">{{_ "invite"}} ({{inviteCount}} {{_ "left"}})</a>
{{else}}
<a class="button inline disabled" href="#">{{i18n "Invite (none left)"}}</a>
<a class="button inline disabled" href="#">{{_ "invite_none_left"}}</a>
{{/if}}
{{/if}}
</div>
<div class="user-profile-posts grid grid-module">
<h3>{{i18n "Posts"}}</h3>
<h3>{{_ "posts"}}</h3>
<table>
<thead>
<tr>
@ -72,7 +72,7 @@
{{#if hasMorePosts}}
<tr>
<td colspan="2">
<a class="posts-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
<a class="posts-more more-button grid-module" href="#"><span>{{_ "load_more"}}</span></a>
</td>
</tr>
{{/if}}
@ -80,7 +80,7 @@
</div>
<div class="user-profile-votes grid grid-module">
<h3>{{i18n "Upvoted Posts"}}</h3>
<h3>{{_ "upvoted_posts"}}</h3>
<table>
<thead>
<tr>
@ -97,7 +97,7 @@
{{#if hasMoreUpvotedPosts}}
<tr>
<td colspan="2">
<a class="upvotedposts-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
<a class="upvotedposts-more more-button grid-module" href="#"><span>{{_ "load_more"}}</span></a>
</td>
</tr>
{{/if}}
@ -105,7 +105,7 @@
</div>
<div class="user-profile-votes grid grid-module">
<h3>{{i18n "Downvoted Posts"}}</h3>
<h3>{{_ "downvoted_posts"}}</h3>
<table>
<thead>
<tr>
@ -122,7 +122,7 @@
{{#if hasMoreDownvotedPosts}}
<tr>
<td colspan="2">
<a class="downvoted-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
<a class="downvoted-more more-button grid-module" href="#"><span>{{_ "load_more"}}</span></a>
</td>
</tr>
{{/if}}
@ -130,7 +130,7 @@
</div>
<div class="user-profile-comments grid grid-module">
<h3>{{i18n "Comments"}}</h3>
<h3>{{_ "comments_"}}</h3>
<table>
<thead>
<tr>
@ -149,7 +149,7 @@
{{#if hasMoreComments}}
<tr>
<td colspan="2">
<a class="comments-more more-button grid-module" href="#"><span>{{i18n "Load more"}}</span></a>
<a class="comments-more more-button grid-module" href="#"><span>{{_ "load_more"}}</span></a>
</td>
</tr>
{{/if}}

View file

@ -1,37 +1,37 @@
<template name="users">
<div class="grid grid-module">
<div class="user-table grid-block">
<h2>{{i18n "Users"}}</h2>
<h2>{{_ "users"}}</h2>
<div class="filter-sort">
<p class="filter">
<span>{{i18n "Filter by"}}: </span>
<a class="{{activeClass 'all'}}" href="{{filterBy 'all'}}">{{i18n "All"}}</a>
<a class="{{activeClass 'invited'}}" href="{{filterBy 'invited'}}">{{i18n "Invited"}}</a>
<a class="{{activeClass 'uninvited'}}" href="{{filterBy 'uninvited'}}">{{i18n "Uninvited"}}</a>
<a class="{{activeClass 'admin'}}" href="{{filterBy 'admin'}}">{{i18n "Admin"}}</a>
<span>{{_ "filter_by"}}: </span>
<a class="{{activeClass 'all'}}" href="{{filterBy 'all'}}">{{_ "all"}}</a>
<a class="{{activeClass 'invited'}}" href="{{filterBy 'invited'}}">{{_ "invited"}}</a>
<a class="{{activeClass 'uninvited'}}" href="{{filterBy 'uninvited'}}">{{_ "uninvited"}}</a>
<a class="{{activeClass 'admin'}}" href="{{filterBy 'admin'}}">{{_ "admin"}}</a>
</p>
<p class="sort">
<span>{{i18n "Sort by"}}: </span>
<a class="{{activeClass 'createdAt'}}" href="{{sortBy 'createdAt'}}">{{i18n "Created"}}</a>
<a class="{{activeClass 'karma'}}" href="{{sortBy 'karma'}}">{{i18n "Karma"}}</a>
<a class="{{activeClass 'username'}}" href="{{sortBy 'username'}}">{{i18n "Username"}}</a>
<a class="{{activeClass 'postCount'}}" href="{{sortBy 'postCount'}}">{{i18n "Posts"}}</a>
<a class="{{activeClass 'commentCount'}}" href="{{sortBy 'commentCount'}}">{{i18n "Comments"}}</a>
<a class="{{activeClass 'invitedCount'}}" href="{{sortBy 'invitedCount'}}">{{i18n "InvitedCount"}}</a>
<span>{{_ "sort_by"}}: </span>
<a class="{{activeClass 'createdAt'}}" href="{{sortBy 'createdAt'}}">{{_ "created"}}</a>
<a class="{{activeClass 'karma'}}" href="{{sortBy 'karma'}}">{{_ "karma"}}</a>
<a class="{{activeClass 'username'}}" href="{{sortBy 'username'}}">{{_ "username"}}</a>
<a class="{{activeClass 'postCount'}}" href="{{sortBy 'postCount'}}">{{_ "posts"}}</a>
<a class="{{activeClass 'commentCount'}}" href="{{sortBy 'commentCount'}}">{{_ "comments_"}}</a>
<a class="{{activeClass 'invitedCount'}}" href="{{sortBy 'invitedCount'}}">{{_ "invitedcount"}}</a>
</p>
</div>
<table>
<thead>
<tr>
<td colspan="2">{{i18n "Name"}}</td>
<td>{{i18n "Member since"}}</td>
<td>{{i18n "Posts"}}</td>
<td>{{i18n "Comments"}}</td>
<td>{{i18n "Karma"}}</td>
<td>{{i18n "Invites"}}</td>
<td>{{i18n "Invited?"}}</td>
<td>{{i18n "Admin?"}}</td>
<td>{{i18n "Actions"}}</td>
<td colspan="2">{{_ "name"}}</td>
<td>{{_ "member_since"}}</td>
<td>{{_ "posts"}}</td>
<td>{{_ "comments_"}}</td>
<td>{{_ "karma"}}</td>
<td>{{_ "invites"}}</td>
<td>{{_ "invited"}}</td>
<td>{{_ "admin"}}</td>
<td>{{_ "actions"}}</td>
</tr>
</thead>
<tbody>
@ -41,7 +41,7 @@
</tbody>
</table>
<div class="grid more-button {{#if allPostsLoaded}} hidden {{/if}}">
<a class="more-link" href="{{loadMoreUrl}}">{{i18n "Load more"}}</a>
<a class="more-link" href="{{loadMoreUrl}}">{{_ "load_more"}}</a>
</div>
</div>
</div>

View file

@ -111,15 +111,15 @@ Meteor.methods({
// check that user can comment
if (!user || !canComment(user))
throw new Meteor.Error(i18n.t('You need to login or be invited to post new comments.'));
throw new Meteor.Error(i18n.t('you_need_to_login_or_be_invited_to_post_new_comments'));
// check that user waits more than 15 seconds between comments
if(!this.isSimulation && (timeSinceLastComment < commentInterval))
throw new Meteor.Error(704, i18n.t('Please wait ')+(commentInterval-timeSinceLastComment)+i18n.t(' seconds before commenting again'));
throw new Meteor.Error(704, i18n.t('please_wait')+(commentInterval-timeSinceLastComment)+i18n.t('seconds_before_commenting_again'));
// Don't allow empty comments
if (!text)
throw new Meteor.Error(704,i18n.t('Your comment is empty.'));
throw new Meteor.Error(704,i18n.t('your_comment_is_empty'));
var comment = {
postId: postId,
@ -158,11 +158,11 @@ Meteor.methods({
// increment comment count
Meteor.users.update({_id: user._id}, {
$inc: {'data.commentsCount': 1}
$inc: {'commentCount': 1}
});
Posts.update(postId, {
$inc: {commentsCount: 1},
$inc: {commentCount: 1},
$set: {lastCommentedAt: now},
$addToSet: {commenters: user._id}
});
@ -176,13 +176,13 @@ Meteor.methods({
if(canEdit(Meteor.user(), comment)){
// decrement post comment count and remove user ID from post
Posts.update(comment.postId, {
$inc: {commentsCount: -1},
$inc: {commentCount: -1},
$pull: {commenters: comment.userId}
});
// decrement user comment count and remove comment ID from user
Meteor.users.update({_id: comment.userId}, {
$inc: {'data.commentsCount': -1}
$inc: {'commentCount': -1}
});
// note: should we also decrease user's comment karma ?

View file

@ -58,13 +58,20 @@ postSchemaObject = {
omit: true
}
},
commentsCount: {
viewCount: {
type: Number,
optional: true,
autoform: {
omit: true
}
},
commentCount: {
type: Number,
optional: false,
autoform: {
omit: true
}
},
commenters: {
type: [String],
optional: true,
@ -79,7 +86,7 @@ postSchemaObject = {
omit: true
}
},
clicks: {
clickCount: {
type: Number,
optional: true,
autoform: {
@ -200,7 +207,8 @@ Posts.allow({
remove: canEditById
});
clickedPosts = [];
postClicks = [];
postViews = [];
getPostProperties = function(post) {
@ -266,11 +274,11 @@ Meteor.methods({
// check that user can post
if (!user || !canPost(user))
throw new Meteor.Error(601, i18n.t('You need to login or be invited to post new stories.'));
throw new Meteor.Error(601, i18n.t('you_need_to_login_or_be_invited_to_post_new_stories'));
// check that user provided a title
if(!post.title)
throw new Meteor.Error(602, i18n.t('Please fill in a title'));
throw new Meteor.Error(602, i18n.t('please_fill_in_a_title'));
if(!!post.url){
@ -280,18 +288,18 @@ Meteor.methods({
if(typeof postWithSameLink !== 'undefined'){
Meteor.call('upvotePost', postWithSameLink);
throw new Meteor.Error(603, i18n.t('This link has already been posted'), postWithSameLink._id);
throw new Meteor.Error(603, i18n.t('this_link_has_already_been_posted'), postWithSameLink._id);
}
}
if(!isAdmin(Meteor.user())){
// check that user waits more than X seconds between posts
if(!this.isSimulation && timeSinceLastPost < postInterval)
throw new Meteor.Error(604, i18n.t('Please wait ')+(postInterval-timeSinceLastPost)+i18n.t(' seconds before posting again'));
throw new Meteor.Error(604, i18n.t('please_wait')+(postInterval-timeSinceLastPost)+i18n.t('seconds_before_posting_again'));
// check that the user doesn't post more than Y posts per day
if(!this.isSimulation && numberOfPostsInPast24Hours > maxPostsPer24Hours)
throw new Meteor.Error(605, i18n.t('Sorry, you cannot submit more than ')+maxPostsPer24Hours+i18n.t(' posts per day'));
throw new Meteor.Error(605, i18n.t('sorry_you_cannot_submit_more_than')+maxPostsPer24Hours+i18n.t('posts_per_day'));
}
// ------------------------------ Properties ------------------------------ //
@ -304,7 +312,9 @@ Meteor.methods({
author: getDisplayNameById(userId),
upvotes: 0,
downvotes: 0,
commentsCount: 0,
commentCount: 0,
clickCount: 0,
viewCount: 0,
baseScore: 0,
score: 0,
inactive: false
@ -394,12 +404,26 @@ Meteor.methods({
throwError('You need to be an admin to do that.');
}
},
clickedPost: function(post, sessionId){
increasePostViews: function(postId, sessionId){
this.unblock();
// only let users increment a post's view counter once per session
var view = {_id: postId, userId: this.userId, sessionId: sessionId};
if(_.where(postViews, view).length == 0){
postViews.push(view);
Posts.update(postId, { $inc: { viewCount: 1 }});
}
},
increasePostClicks: function(postId, sessionId){
this.unblock();
// only let clients increment a post's click counter once per session
var click = {_id: post._id, sessionId: sessionId};
if(_.where(clickedPosts, click).length == 0){
clickedPosts.push(click);
Posts.update(post._id, { $inc: { clicks: 1 }});
var click = {_id: postId, userId: this.userId, sessionId: sessionId};
if(_.where(postClicks, click).length == 0){
postClicks.push(click);
Posts.update(postId, { $inc: { clickCount: 1 }});
}
},
deletePostById: function(postId) {

View file

@ -168,7 +168,16 @@ settingsSchemaObject = {
optional: true,
autoform: {
group: 'general',
instructions: 'The two-letter code for the app\'s language. Defaults to "en".'
instructions: 'The app\'s language. Defaults to English.',
options: function () {
var languages = _.map(TAPi18n.languages_available_for_project, function (item, key) {
return {
value: key,
label: item[0]
}
});
return languages
}
}
},
backgroundCSS: {
@ -308,11 +317,11 @@ if (Meteor.isClient){
var handle = query.observeChanges({
added: function (id, fields) {
if (fields.language)
T9n.setLanguage(fields.language);
setLanguage(fields.language)
},
changed: function (id, fields) {
if (fields.language)
T9n.setLanguage(fields.language);
setLanguage(fields.language)
}
});
}

View file

@ -48,7 +48,6 @@ Schema.User = new SimpleSchema({
Meteor.users.deny({
update: function(userId, post, fieldNames) {
console.log(fieldNames)
if(isAdminById(userId))
return false;
// deny the update if it contains something other than the profile field

216
i18n/de.i18n.json Normal file
View file

@ -0,0 +1,216 @@
{
//Navigation
"menu": "Menü",
"top": "Top",
"new": "Neu",
"digest": "Zusammenfassung",
"users": "Benutzer",
"settings": "Einstellungen",
"admin": "Admin",
"post": "Link eintragen",
"toolbox": "Werkzeuge",
"sign_up_sign_in": "Registrieren/Anmelden",
"my_account": "Mein Konto",
"view_profile": "Profil anzeigen",
"edit_account": "Konto bearbeiten",
//Main
"new_posts": "Neue Links",
//Commments
"your_comment_has_been_deleted": "Dein Kommentar wurde gelöscht.",
"comment_": "Kommentieren",
"delete_comment": "Kommentar löschen",
"add_comment": "Kommentar hinzufügen",
"upvote": "+1",
"downvote": "-1",
"link": "link",
"edit": "bearbeiten",
"reply": "antworten",
"no_comments": "Keine Kommentare.",
//Errors
"you_are_already_logged_in": "Du bist bereits eingeloggt",
"sorry_this_is_a_private_site_please_sign_up_first": "Dies ist ein privates Angebot. Du musst dich erst registrieren.",
"thanks_for_signing_up": "Vielen Dank für Deine Registrierung!",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "Derzeit sind Neuregistrierungen nur mit einer Einladung möglich, aber wir werden dich wissen lassen, wenn wir unsere Registrierung wieder öffnen.",
"sorry_you_dont_have_the_rights_to_view_this_page": "Entschuldigung, Du hast leider keine Rechte diese Seite anzuzeigen.",
"not_found": "Nichts gefunden!",
"were_sorry_whatever_you_were_looking_for_isnt_here": "Es tut uns leid, wonach auch immer Du gesucht hast, hier ist es nicht.",
//Notifications
"no_notifications": "Keine Benachrichtigungen",
"1_notification": "1 Benachrichtigung",
"notifications": "Benachrichtigungen",
"mark_all_as_read": "Alle als gelesen markieren",
// Post deleted
"your_post_has_been_deleted": "Dein Link wurde gelöscht.",
// Post digest
"the_top_5_posts_of_each_day": "Die Top-5-Links eines jeden Tages.",
"previous_day": "Einen Tag zurück",
"next_day": "Einen Tag vor",
"sorry_no_posts_for_today": "Heute gibt es keine Links.",
"sorry_no_posts_for": "Keine Links für",
"today": "Heute",
"yesterday": "Gestern",
// Post submit & edit
"created": "Erstellt",
"title": "Titel",
"suggest_title": "Titelvorschlag",
"url": "URL",
"short_url": "Kurz-URL",
"body": "Beschreibung",
"category": "Kategorie",
"inactive_": "Inaktiv?",
"sticky_": "Anheften?",
"submission_date": "Eintragsdatum",
"submission_time": "Eintragszeit",
"date": "Datum",
"submission": "Eintragung",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Hinweis: Dieser Beitrag wartet noch auf Freischaltung, daher gibt es noch kein Datum und keine Uhrzeit.",
"user": "Benutzer",
"status_": "Status",
"approved": "Genehmigt",
"rejected": "Abgelehnt",
"delete_post": "Link löschen",
"thanks_your_post_is_awaiting_approval": "Vielen Dank, Dein Beitrag wartet auf Freischaltung.",
"sorry_couldnt_find_a_title": "Du hast vergessen einen Titel anzugeben...",
"please_fill_in_an_url_first": "Du musst eine URL/einen Link angeben!",
// Post item
"share": "Teilen",
"discuss": "Kommentare",
"upvote_": "Abstimmen",
"sticky": "Angeheftet",
"status": "status",
"votes": "Stimmen",
"basescore": "Punktebasis",
"score": "Punkte",
"clicks": "klicks",
"views": "views",
"inactive": "inaktiv",
"comment": "Kommentar",
"comments": "Kommentare",
"point": "Punkt",
"points": "Punkte",
//User
"please_complete_your_profile_below_before_continuing": "Bitte füllen Dein Profil vollständig aus bevor du fortfährst.",
"account": "Konto",
"username": "Benutzername",
"display_name": "Angezeigter Name",
"email": "Email",
"bio": "Bio",
"password": "Passwort",
"change_password": "Passwort ändern?",
"old_password": "Altes Passwort",
"new_password": "Neues Passwort",
"email_notifications": "Email-Benachrichtigung",
"new_posts": "Neue Links",
"comments_on_my_posts": "Kommentare zu meinen Links",
"replies_to_my_comments": "Antworten auf meine Kommentare",
"forgot_password": "Passwort vergessen?",
"profile_updated": "Profil aktualisiert",
"please_fill_in_your_email_below_to_finish_signing_up": "Bitte trage Deine Email-Adresse ein um die Registrierung abzuschließen.",
"invite": "Einladen",
"uninvite": "Ausladen",
"make_admin": "Zum Admin ernennen",
"unadmin": "Als Admin entfernen",
"delete_user": "Benutzer löschen",
"are_you_sure_you_want_to_delete": "Bist du Dir sicher, dass du folgendes löschen willst: ",
"reset_password": "Passwort zurücksetzen",
"password_reset_link_sent": "Ein Link zum zurücksetzen des Passworts wurde versendet!",
"name": "Name",
"posts": "Links",
"comments_": "Kommentare",
"karma": "Karma",
"is_invited": "Wurde eingeladen?",
"is_admin": "Ist Admin?",
"delete": "Löschen",
"member_since": "Mitglied seit",
"edit_profile": "Profil bearbeiten",
"sign_in": "Einloggen",
"sign_in_": "Einloggen!",
"sign_up_": "Registrieren!",
"dont_have_an_account": "Du hast noch kein Konto?",
"already_have_an_account": "Du hast bereits ein Konto?",
"sign_up": "Registrieren",
"please_fill_in_all_fields": "Bitte fülle alle Felder aus",
"invite_": "Einladung(en) ",
"left": " übrig",
"invite_none_left": "Einladungen (keine übrig)",
"all": "Alle",
"invited": "Eingeladen",
"uninvited": "Nicht eingeladen",
"filter_by": "Filtern nach",
"sort_by": "Sortieren nach",
//helpers
"sorry_you_do_not_have_access_to_this_page": "Sorry, Du hast keinen Zugang zu dieser Seite",
"please_sign_in_first": "Bitte melde Dich zuerst an.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Sorry, Du musst Admin sein um diese Seite anzeigen zu können.",
"sorry_you_dont_have_permissions_to_add_new_items": "Sorry, Du hast keine Berechtigung neue Einträge zu erstellen.",
"sorry_you_cannot_edit_this_post": "Sorry, Du kannst diesen Beitrag nicht bearbeiten.",
"sorry_you_cannot_edit_this_comment": "Sorry, Du kannst diesen Kommentar nicht bearbeiten.",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "Du musst Dich anmelden und ein Admin sein um eine neue Kategorien hinzuzufügen.",
"you_need_to_login_or_be_invited_to_post_new_comments": "Du musst dich einloggen oder eingeladen sein um neue Kommentare schreiben zu können.",
"please_wait": "Bitte warte ",
"seconds_before_commenting_again": " Sekunden, bevor du wieder kommentierst.",
"your_comment_is_empty": "Dein Kommentar ist leer.",
"you_dont_have_permission_to_delete_this_comment": "Du hast keine Berechtigung diesen Kommentar zu löschen.",
"you_need_to_login_or_be_invited_to_post_new_stories": "Du musst eingeloggt oder eingeladen sein um einen neuen Link zu posten.",
"please_fill_in_a_headline": "Bitte fülle den Titel aus",
"this_link_has_already_been_posted": "Dieser Link wurde bereits gepostet",
"sorry_you_cannot_submit_more_than": "Es tut uns leid, Du kannst nicht mehr als ",
"posts_per_day": " Links pro Tag eintragen",
"someone_replied_to_your_comment_on": "Jemand hat auf Deinen Kommentar geantwortet bei",
"has_replied_to_your_comment_on": " hat auf Deinen Kommentar geantwortet bei",
"read_more": "weiterlesen",
"a_new_comment_on_your_post": "Ein neuer Kommentar zu Deinem Link",
"you_have_a_new_comment_by": "Du hast einen neuen Kommentar von ",
"on_your_post": " bei Deinem Link",
"has_created_a_new_post": " hat einen neuen Link erstellt",
"your_account_has_been_approved": "Dein Konto wurde freigeschaltet.",
"welcome_to": "Willkommen bei ",
"start_posting": "Fang an Links einzutragen.",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Please fill in a title",
"seconds_before_posting_again": " seconds before posting again",
"upvoted": "Upvoted",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"profile": "Profile",
"sign_out": "Sign Out",
"invitedcount": "InvitedCount",
"invites": "Invites",
"invited": "Invited?",
"admin": "Admin?",
"actions": "Actions",
"invites_left": "invites left",
"id": "ID",
"name": "Name:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Upvoted Posts",
"downvoted_posts": "Downvoted Posts",
"mark_as_read": "Mark as read",
//Common
"pending": "Wartet",
"loading": "lädt...",
"submit": "Abschicken",
"you_must_be_logged_in": "Du musst angemeldet sein.",
"are_you_sure": "Bist Du sicher?",
"please_log_in_first": "Bitte melde Dich zuerst an",
"sign_in_sign_up_with_twitter": "Anmelden/Registrieren mit Twitter",
"load_more": "Mehr Laden"
}

216
i18n/en.i18n.json Normal file
View file

@ -0,0 +1,216 @@
{
//Navigation
"menu": "Menu",
"top": "Top",
"new": "New",
"digest": "Digest",
"users": "Users",
"settings": "Settings",
"admin": "Admin",
"post": "Post",
"toolbox": "Toolbox",
"sign_up_sign_in": "Sign Up/Sign In",
"my_account": "My Account",
"view_profile": "View Profile",
"edit_account": "Edit Account",
//Main
"new_posts": "New Posts",
//Commments
"your_comment_has_been_deleted": "Your comment has been deleted.",
"comment_": "Comment",
"delete_comment": "Delete Comment",
"add_comment": "Add Comment",
"upvote": "upvote",
"downvote": "downvote",
"link": "link",
"edit": "Edit",
"reply": "Reply",
"no_comments": "No comments.",
//Errors
"you_are_already_logged_in": "You are already logged in",
"sorry_this_is_a_private_site_please_sign_up_first": "Sorry, this is a private site. Please sign up first.",
"thanks_for_signing_up": "Thanks for signing up!",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "The site is currently invite-only, but we will let you know as soon as a spot opens up.",
"sorry_you_dont_have_the_rights_to_view_this_page": "Sorry, you don't have the rights to view this page.",
"not_found": "Not Found!",
"were_sorry_whatever_you_were_looking_for_isnt_here": "We're sorry; whatever you were looking for isn't here..",
//Notifications
"no_notifications": "No notifications",
"1_notification": "1 notification",
"notifications": "notifications",
"mark_all_as_read": "Mark all as read",
// Post deleted
"your_post_has_been_deleted": "Your post has been deleted.",
// Post digest
"the_top_5_posts_of_each_day": "The top 5 posts of each day.",
"previous_day": "Previous Day",
"next_day": "Next Day",
"sorry_no_posts_for_today": "Sorry, no posts for today",
"sorry_no_posts_for": "Sorry, no posts for",
"today": "Today",
"yesterday": "Yesterday",
// Post submit & edit
"created": "Created",
"title": "Title",
"suggest_title": "Suggest title",
"url": "URL",
"short_url": "Short URL",
"body": "Body",
"category": "Category",
"inactive_": "Inactive?",
"sticky_": "Sticky?",
"submission_date": "Submission Date",
"submission_time": "Submission Time",
"date": "Date",
"submission": "Submission",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Note: this post is still pending so it has no submission timestamp yet.",
"user": "User",
"status_": "Status",
"approved": "Approved",
"rejected": "Rejected",
"delete_post": "Delete Post",
"thanks_your_post_is_awaiting_approval": "Thanks, your post is awaiting approval.",
"sorry_couldnt_find_a_title": "Sorry, couldn't find a title...",
"please_fill_in_an_url_first": "Please fill in an URL first!",
// Post item
"share": "Share",
"discuss": "Discuss",
"upvote_": "Upvote",
"sticky": "Sticky",
"status": "status",
"votes": "votes",
"basescore": "baseScore",
"score": "score",
"clicks": "clicks",
"views": "views",
"inactive": "inactive",
"comment": "comment",
"comments": "comments",
"point": "point",
"points": "points",
//User
"please_complete_your_profile_below_before_continuing": "Please complete your profile below before continuing.",
"account": "Account",
"username": "Username",
"display_name": "Display Name",
"email": "Email",
"bio": "Bio",
"password": "Password",
"change_password": "Change Password?",
"old_password": "Old Password",
"new_password": "New Password",
"email_notifications": "Email Notifications",
"new_posts": "New Posts",
"comments_on_my_posts": "Comments on my posts",
"replies_to_my_comments": "Replies to my comments",
"forgot_password": "Forgot password?",
"profile_updated": "Profile updated",
"please_fill_in_your_email_below_to_finish_signing_up": "Please fill in your email below to finish signing up.",
"invite": "Invite",
"uninvite": "Uninvite",
"make_admin": "Make admin",
"unadmin": "Unadmin",
"delete_user": "Delete User",
"are_you_sure_you_want_to_delete": "Are you sure you want to delete ",
"reset_password": "Reset Password",
"password_reset_link_sent": "Password reset link sent!",
"name": "Name",
"posts": "Posts",
"comments_": "Comments",
"karma": "Karma",
"is_invited": "Is Invited?",
"is_admin": "Is Admin?",
"delete": "Delete",
"member_since": "Member since",
"edit_profile": "Edit profile",
"sign_in": "Sign In",
"sign_in_": "Sign in!",
"sign_up_": "Sign up!",
"dont_have_an_account": "Don't have an account?",
"already_have_an_account": "Already have an account?",
"sign_up": "Sign Up",
"please_fill_in_all_fields": "Please fill in all fields",
"invite_": "Invite ",
"left": " left",
"invite_none_left": "Invite (none left)",
"all": "All",
"invited": "Invited",
"uninvited": "Uninvited",
"filter_by": "Filter by",
"sort_by": "Sort by",
//helpers
"sorry_you_do_not_have_access_to_this_page": "Sorry, you do not have access to this page",
"please_sign_in_first": "Please Sign In First.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Sorry, you have to be an admin to view this page.",
"sorry_you_dont_have_permissions_to_add_new_items": "Sorry, you don't have permissions to add new items.",
"sorry_you_cannot_edit_this_post": "Sorry, you cannot edit this post.",
"sorry_you_cannot_edit_this_comment": "Sorry, you cannot edit this comment.",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "You need to login and be an admin to add a new category.",
"you_need_to_login_or_be_invited_to_post_new_comments": "You need to login or be invited to post new comments.",
"please_wait": "Please wait ",
"seconds_before_commenting_again": " seconds before commenting again",
"your_comment_is_empty": "Your comment is empty.",
"you_dont_have_permission_to_delete_this_comment": "You don't have permission to delete this comment.",
"you_need_to_login_or_be_invited_to_post_new_stories": "You need to login or be invited to post new stories.",
"please_fill_in_a_headline": "Please fill in a headline",
"this_link_has_already_been_posted": "This link has already been posted",
"sorry_you_cannot_submit_more_than": "Sorry, you cannot submit more than ",
"posts_per_day": " posts per day",
"someone_replied_to_your_comment_on": "Someone replied to your comment on",
"has_replied_to_your_comment_on": " has replied to your comment on",
"read_more": "Read more",
"a_new_comment_on_your_post": "A new comment on your post",
"you_have_a_new_comment_by": "You have a new comment by ",
"on_your_post": " on your post",
"has_created_a_new_post": " has created a new post",
"your_account_has_been_approved": "Your account has been approved.",
"welcome_to": "Welcome to ",
"start_posting": "Start posting.",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Please fill in a title",
"seconds_before_posting_again": " seconds before posting again",
"upvoted": "Upvoted",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"profile": "Profile",
"sign_out": "Sign Out",
"invitedcount": "InvitedCount",
"invites": "Invites",
"invited": "Invited?",
"admin": "Admin",
"actions": "Actions",
"invites_left": "invites left",
"id": "ID",
"name": "Name:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Upvoted Posts",
"downvoted_posts": "Downvoted Posts",
"mark_as_read": "Mark as read",
//Common
"pending": "Pending",
"loading": "Loading...",
"submit": "Submit",
"you_must_be_logged_in": "You must be logged in.",
"are_you_sure": "Are you sure?",
"please_log_in_first": "Please log in first",
"sign_in_sign_up_with_twitter": "Sign In/Sign Up with Twitter",
"load_more": "Load more"
}

215
i18n/es.i18n.json Normal file
View file

@ -0,0 +1,215 @@
{
//Navigation
"view": "Vista",
"menu": "Menu",
"top": "Todos",
"new": "Nuevos",
"digest": "Resumen",
"users": "Usuarios",
"settings": "Configuración",
"admin": "Admin",
"post": "Post",
"toolbox": "Herramientas",
"sign_up_sign_in": "Connectarse/Crear una cuenta",
"my_account": "Mi Cuenta",
"view_profile": "Ver perfil",
"edit_account": "Editar cuenta",
//Main
"new_posts": "Nuevos Posts",
//Commments
"your_comment_has_been_deleted": "Tu comentario ha sido borrado",
"comment_": "Comentario",
"delete_comment": "Borrar el comentario",
"add_comment": "Añadir comentario",
"upvote": "Voto Positivo",
"downvote": "Voto Negativo",
"link": "link",
"edit": "Editar",
"reply": "Contestar",
"no_comments": "No hay comentarios.",
//Errors
"you_are_already_logged_in": "Ya estás conectado",
"sorry_this_is_a_private_site_please_sign_up_first": "Lo sentimos pero esta pagina es privada. Por favor, conéctese para verla",
"thanks_for_signing_up": "Gracias por registrarte",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "El sitio solo es accesible mediante invitación, pero te lo haremos saber tan pronto como abra al público.",
"sorry_you_dont_have_the_rights_to_view_this_page": "Lo sentimos pero no tienes los derechos suficientes para ver esta pagina",
"not_found": "No encontramos nada!",
"were_sorry_whatever_you_were_looking_for_isnt_here": "Lo sentimos pero aqui no hay nada.. ",
//Notifications
"no_notifications": "Ninguna notificación",
"1_notification": "1 notificación",
"notifications": "notificaciones",
"mark_all_as_read": "Marcar todas como leídas",
// Post deleted
"your_post_has_been_deleted": "Tu post ha sido borrado.",
// Post digest
"the_top_5_posts_of_each_day": "Los 5 mejores posts de cada día",
"previous_day": "Dia anterior",
"next_day": "Dia siguiente",
"sorry_no_posts_for_today": "Lo sentimos, no hay post para hoy",
"today": "Hoy",
"yesterday": "Ayer",
// Post submit & edit
"created": "Creado",
"title": "Título",
"suggest_title": "Proponer un titulo",
"url": "URL",
"short_url": "URL Corta",
"body": "Descripción",
"category": "Categoría",
"inactive_": "Inactivo?",
"sticky_": "Pegado?",
"submission_date": "Fecha de entrega",
"submission_time": "Hora de entrega",
"date": "Fecha",
"submission": "Entrega",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Nota : Este post esta en proceso de validación entonces no tiene fecha de entrega todavía.",
"user": "Usuario",
"status_": "Estado",
"approved": "Aprobado",
"rejected": "Rechezado",
"delete_post": "Borrar este post",
"thanks_your_post_is_awaiting_approval": "Gracias, su post esta esperando validación.",
"sorry_couldnt_find_a_title": "Lo sentimos, impossible de encontrar este título.",
"please_fill_in_an_url_first": "Tienes que poner una URL.",
// Post item
"share": "Compartir",
"discuss": "Comentar",
"upvote_": "Votar",
"sticky": "Pegado",
"status": "Estado",
"votes": "votos",
"basescore": "baseScore",
"score": "puntuación",
"clicks": "clicks",
"views": "views",
"inactive": "inactivo",
"comment": "comentario",
"comments": "comentarios",
"point": "punto",
"points": "puntos",
//User
"please_complete_your_profile_below_before_continuing": "Por favor complete su perfil antes de seguir.",
"account": "Cuenta",
"username": "Nombre de usuario",
"display_name": "Nombre",
"email": "Email",
"bio": "Bio",
"password": "Contraseña",
"change_password": "Cambiar de contraseña",
"old_password": "Antigua Contraseña",
"new_password": "Nueva Contraseña",
"email_notifications": "Notificaciónes por Email",
"new_posts": "Nuevo Post",
"comments_on_my_posts": "Comentarios de mi post",
"replies_to_my_comments": "Respuestas a mis comentarios",
"forgot_password": "Olvidaste tu contraseña?",
"profile_updated": "Perfil actualizado",
"please_fill_in_your_email_below_to_finish_signing_up": "Por favor, introduzca su email para terminar de inscribirse.",
"invite": "Invitar",
"uninvite": "Cancelar la invitación",
"make_admin": "Hacer admin",
"unadmin": "Borrar de admin",
"delete_user": "Borrar usuario",
"are_you_sure_you_want_to_delete": "Está seguro de que desea eliminar",
"reset_password": "Restablecer contraseña",
"password_reset_link_sent": "Enlace de restablecimiento de contraseña enviado!!",
"name": "Nombre",
"posts": "Posts",
"comments_": "Comentarios",
"karma": "Karma",
"is_invited": "Esta invitado?",
"is_admin": "Es admin?",
"delete": "Borrar",
"member_since": "Miembro desde",
"edit_profile": "Modificar el perfil",
"sign_in": "Registrarse",
"sign_in_": "Registrarse",
"sign_up_": "Inscribirse",
"dont_have_an_account": "¿No tiene cuenta de usuario?",
"already_have_an_account": "¿Ya tiene cuenta?",
"sign_up": "Inscribirse",
"please_fill_in_all_fields": "Tiene que rellenar todos los campos",
"invite_": "Invitación ",
"left": " restante",
"invite_none_left": "Invitación (no queda)",
"all": "Todos",
"invited": "Invitados",
"uninvited": "No invitado",
"filter_by": "Filtrar por",
"sort_by": "Ordenar por",
//Helpers
"sorry_you_do_not_have_access_to_this_page": "Lo sentimos, usted no tiene acceso a esta página",
"please_sign_in_first": "Tiene que registrarse primero.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Lo sentimos, usted tiene que ser un administrador para ver esta página.",
"sorry_you_dont_have_permissions_to_add_new_items": "Lo sentimos, usted no tiene permisos para agregar nuevos elementos.",
"sorry_you_cannot_edit_this_post": "Lo sentimos, no puede editar este post.",
"sorry_you_cannot_edit_this_comment": "Lo sentimos, no puede editar este comentario.",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "Usted tiene que entrar y ser un administrador para añadir una nueva categoría",
"you_need_to_login_or_be_invited_to_post_new_comments": "¡Tienes que iniciar sesión o ser invitado a publicar nuevos comentarios.",
"please_wait": "Espera por favor",
"seconds_before_commenting_again": " segundos antes de comentar de nuevo",
"your_comment_is_empty": "Tu comentario está vacío",
"you_dont_have_permission_to_delete_this_comment": "Usted no tiene permiso para eliminar este comentario.",
"you_need_to_login_or_be_invited_to_post_new_stories": "¡Tienes que iniciar sesión o ser invitado para publicar nuevas historias.",
"please_fill_in_a_headline": "Por favor rellene el titulo",
"this_link_has_already_been_posted": "Este enlace ya ha sido publicado",
"sorry_you_cannot_submit_more_than": "Lo sentimos, usted no puede presentar más de ",
"posts_per_day": " posts por dia",
"someone_replied_to_your_comment_on": "Alguien respondió a tu comentario en",
"has_replied_to_your_comment_on": " ha respondido a su comentario sobre",
"read_more": "Leer más",
"a_new_comment_on_your_post": "Un nuevo comentario en su post",
"you_have_a_new_comment_by": "Usted tiene un nuevo comentario de ",
"on_your_post": " en su post",
"has_created_a_new_post": " ha creado un nuevo post",
"your_account_has_been_approved": "Su cuenta ha sido aprobada.",
"start_posting": "Empezar a publicar",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Please fill in a title",
"seconds_before_posting_again": " seconds before posting again",
"upvoted": "Upvoted",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"profile": "Profile",
"sign_out": "Sign Out",
"invitedcount": "InvitedCount",
"invites": "Invites",
"invited": "Invited?",
"admin": "Admin?",
"actions": "Actions",
"invites_left": "invites left",
"id": "ID",
"name": "Name:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Upvoted Posts",
"downvoted_posts": "Downvoted Posts",
"mark_as_read": "Mark as read",
//Common
"pending": "Pendiente",
"loading": "Cargando...",
"submit": "Enviar",
"you_must_be_logged_in": "Debe estar conectado",
"are_you_sure": "¿Está seguro? ",
"please_log_in_first": "Por favor, inicia sesión",
"sign_in_sign_up_with_twitter": "Inicia sesión/Inscribete con Twitter",
"load_more": "Cargar más"
}

211
i18n/fr.i18n.json Normal file
View file

@ -0,0 +1,211 @@
{
//Navigation
"view": "Vue",
"menu": "Menu",
"top": "Top",
"new": "Nouveau",
"best": "Meilleur",
"digest": "Résumé",
"users": "Utilisateurs",
"settings": "Paramètres",
"admin": "Admin",
"post": "Poster",
"toolbox": "Outils",
"sign_up_sign_in": "Connexion/Créer un compte",
"my_account": "Mon compte",
"view_profile": "Voir le profil",
"edit_account": "Editer le compte",
//Main
"new_posts": "Nouveaux Posts",
//Commments
"your_comment_has_been_deleted": "Votre commentaire a été supprimé.",
"comment_": "Commentaire",
"delete_comment": "Supprimer le commentaire",
"add_comment": "Ajouter un commentaire",
"upvote": "upvote",
"downvote": "downvote",
"link": "lien",
"edit": "Editer",
"reply": "Répondre",
"no_comments": "Aucun commentaire.",
//Errors
"you_are_already_logged_in": "Vous êtes déjà connecté",
"sorry_this_is_a_private_site_please_sign_up_first": "Désolé mais ce site est privé, vous devez d'abord vous connecter",
"thanks_for_signing_up": "Merci pour votre inscription !",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "L'accès au site se fait uniquement par invitation. Nous vous informerons dès qu'une place se libère.",
"sorry_you_dont_have_the_rights_to_view_this_page": "Désolé, vous n'avez pas le droit de voir cette page.",
"not_found": "Oups",
"were_sorry_whatever_you_were_looking_for_isnt_here": "Désolé, mais ce que vous cherchez ne se trouve pas ici...",
// Post deleted
"your_post_has_been_deleted": "Votre post a été supprimé.",
// Post digest
"the_top_5_posts_of_each_day": "5 meilleurs post par jours",
"previous_day": "Jour précédent",
"next_day": "Jour suivant",
"sorry_no_posts_for_today": "Désolé, aucun post aujourd'hui",
"sorry_no_posts_for": "Désolé, aucun post pour",
"today": "Aujourd'hui",
"yesterday": "Hier",
// Post submit & edit
"created": "Crée",
"title": "Titre",
"suggest_title": "Suggérer un titre",
"url": "URL",
"short_url": "URL Courte",
"body": "Description",
"category": "Catégorie",
"inactive_": "Inactif ?",
"sticky_": "Mis en avant ?",
"submission_date": "Date de soumission",
"submission_time": "Heure de soumission",
"date": "Date",
"submission": "Soumission",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Note : ce post est en cours de validation, il n'a pas encore de timestamp.",
"user": "Utilisateur",
"status_": "Status",
"approved": "Approuvé",
"rejected": "Rejeté",
"delete_post": "Supprimer le post",
"thanks_your_post_is_awaiting_approval": "Merci, votre post est en cours de validation",
"sorry_couldnt_find_a_title": "Désolé, impossible de trouver un titre...",
"please_fill_in_an_url_first": "Vous devez saisir une URL.",
// Post item
"share": "Partager",
"discuss": "Discuter",
"upvote_": "Voter",
"sticky": "Mis en avant",
"status": "status",
"votes": "votes",
"basescore": "baseScore",
"score": "score",
"clicks": "clics",
"views": "views",
"inactive": "inactif",
"comment": "commentaire",
"comments": "commentaires",
"point": "point",
"points": "points",
//User
"please_complete_your_profile_below_before_continuing": "Merci de compléter votre profil avant de continuer.",
"account": "Compte",
"username": "Nom d'utilisateur",
"display_name": "Nom réel",
"email": "Email",
"bio": "Bio",
"password": "Mot de passe",
"change_password": "Changer de mot de passe",
"old_password": "Ancien mot de passe",
"new_password": "Nouveau mot de passe",
"email_notifications": "Notifications par email",
"new_posts": "Nouveau Post",
"comments_on_my_posts": "Commentaires sur mes posts",
"replies_to_my_comments": "Reponses à mes commentaires",
"forgot_password": "Mot de passe oublié ?",
"profile_updated": "Profil mis à jour",
"please_fill_in_your_email_below_to_finish_signing_up": "Merci de saisir votre email pour finir la création de votre compte",
"invite": "Inviter",
"uninvite": "Annuler l'invitation",
"make_admin": "Rendre admin",
"unadmin": "Supprimer les droits d'admin",
"delete_user": "Supprimer l'utilisateur",
"are_you_sure_you_want_to_delete": "Etes-vous sur de vouloir supprimer ",
"reset_password": "Redéfinir le mot de passe",
"password_reset_link_sent": "Un lien pour redéfinir votre mot de passe a été envoyé !",
"name": "Nom",
"posts": "Posts",
"comments_": "Commentaires",
"karma": "Karma",
"is_invited": "Est-il invité ?",
"is_admin": "Est-il Administrateur ?",
"delete": "Supprimer",
"member_since": "Membre depuis",
"edit_profile": "Modifier le profil",
"sign_in": "Connexion",
"sign_in_": "Connexion",
"sign_up_": "Créer un compte !",
"dont_have_an_account": "Pas encore de compte ?",
"already_have_an_account": "Déjà un compte ?",
"sign_up": "Créer un compte",
"please_fill_in_all_fields": "Vous devez remplir tous les champs",
"invite_": "Invitation ",
"left": " restante",
"invite_none_left": "Invitation (aucune restante)",
"all": "All",
"invited": "Invité",
"uninvited": "Pas invité",
"filter_by": "Filtrer par",
"sort_by": "Trier par",
//Helpers
"sorry_you_do_not_have_access_to_this_page": "Désolé, vous n'avez pas accès à cette page",
"please_sign_in_first": "Vous devez d'abord vous connecter.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Désolé, vous devez être administrateur pour voir cette page.",
"sorry_you_dont_have_permissions_to_add_new_items": "Désolé, vous n'avez pas la permission d'ajouter de nouveaux posts.",
"sorry_you_cannot_edit_this_post": "Désolé, vous ne pouvez pas modifier ce post.",
"sorry_you_cannot_edit_this_comment": "Désolé, vous ne pouvez pas modifier ce commentaire.",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "Vous devez être administrateur et connecté pour ajouter une catégorie",
"you_need_to_login_or_be_invited_to_post_new_comments": "Vous devez être connecté et invité pour poster des commentaires",
"please_wait": "Merci de patienter ",
"seconds_before_commenting_again": " secondes avant de poster un nouveau commentaire",
"your_comment_is_empty": "Votre commentaire est vide",
"you_dont_have_permission_to_delete_this_comment": "Vous n'avez pas la permission de supprimer ce commentaire",
"you_need_to_login_or_be_invited_to_post_new_stories": "Vous devez être connecté ou invité pour créer un nouveau post",
"please_fill_in_a_headline": "Merci de saisir un titre",
"this_link_has_already_been_posted": "Ce lien a déjà été posté",
"sorry_you_cannot_submit_more_than": "Désolé, vous ne pouvez pas créer plus de ",
"posts_per_day": " posts par jour",
"someone_replied_to_your_comment_on": "Quelqu'un à répondu à votre commentaire sur",
"has_replied_to_your_comment_on": " a répondu à votre commentaire sur",
"read_more": "Lire la suite",
"a_new_comment_on_your_post": "Un nouveau commentaire sur votre post",
"you_have_a_new_comment_by": "Vous avez un nouveau commentaire de ",
"on_your_post": " sur votre post",
"has_created_a_new_post": " a créer un nouveau post",
"your_account_has_been_approved": "Votre compte a été validé.",
"welcome_to": "Bienvenu sur ",
"start_posting": "Commencer à poster.",
// Other
"please_fill_in_a_title": "Veuillez remplir un titre.",
"seconds_before_posting_again": " secondes avant de poster à nouveau.",
"upvoted": "Upvoté",
"posted_date": "Date de Soumission",
"posted_time": "Heure de Soumission",
"profile": "Profil",
"sign_out": "Déconnexion",
"invitedcount": "Membres Invités",
"invites": "Invitations",
"invited": "Invité?",
"admin": "Admin",
"actions": "Actions",
"invites_left": "Invitations restantes",
"id": "ID",
"name": "Nom:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Posts Upvotés",
"downvoted_posts": "Posts Downvotés",
"mark_as_read": "Marquer comme lu",
//Common
"pending": "En attente",
"loading": "Chargement...",
"submit": "Envoyer",
"you_must_be_logged_in": "Vous devez être connecté",
"are_you_sure": "Etes-vous sur ?",
"please_log_in_first": "Vous devez être connecté",
"sign_in_sign_up_with_twitter": "Connexion/Créer un compte avec Twitter",
"load_more": "Charger plus"
}

216
i18n/it.i18n.json Normal file
View file

@ -0,0 +1,216 @@
{
//Navigation
"menu": "Menu",
"top": "Migliori",
"new": "Nuovi",
"digest": "Selezione",
"users": "Utenti",
"settings": "Impostazioni",
"admin": "Amministrazione",
"post": "Posta",
"toolbox": "Toolbox",
"sign_up_sign_in": "Registrati/Accedi",
"my_account": "Il Mio Account",
"view_profile": "Vedi Profilo",
"edit_account": "Modifica Account",
//Main
"new_posts": "Nuovi Post",
//Commments
"your_comment_has_been_deleted": "Il tuo commento è stato rimosso.",
"comment_": "Commenta",
"delete_comment": "Elimina Commento",
"add_comment": "Aggiungi Commento",
"upvote": "promuovi",
"downvote": "sconsiglia",
"link": "link",
"edit": "Modifica",
"reply": "Rispondi",
"no_comments": "Nessun commento.",
//Errors
"you_are_already_logged_in": "Hai già eseguito l'accesso",
"sorry_this_is_a_private_site_please_sign_up_first": "Ci spiace, questo è un sito privato. Per favore registrati.",
"thanks_for_signing_up": "Grazie per esserti registrato!",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "Questo sito al momento è solo per chi è stato invitato, ma ti faremo sapere non appena ci sarà la possibilità di accedere.",
"sorry_you_dont_have_the_rights_to_view_this_page": "Ci spiace, non hai i permessi per visualizzare questa pagina.",
"not_found": "Non Trovato!",
"were_sorry_whatever_you_were_looking_for_isnt_here": "Ci spiace; qualsiasi cosa stessi cercando non è qua..",
//Notifications
"no_notifications": "Nessuna notifica",
"1_notification": "1 notifica",
"notifications": "notifiche",
"mark_all_as_read": "Segna tutte come lette",
// Post deleted
"your_post_has_been_deleted": "Il tuo post è stato rimosso.",
// Post digest
"the_top_5_posts_of_each_day": "I 5 migliori post di ogni giorno.",
"previous_day": "Giorno Precedente",
"next_day": "Giorno Successivo",
"sorry_no_posts_for_today": "Ci spiace, non ci sono post per oggi",
"sorry_no_posts_for": "Ci spiace, non ci sono post per",
"today": "Oggi",
"yesterday": "Ieri",
// Post submit & edit
"created": "Creato",
"title": "Titolo",
"suggest_title": "Titolo suggerito",
"url": "URL",
"short_url": "URL breve",
"body": "Corpo",
"category": "Categoria",
"inactive_": "Inattivo?",
"sticky_": "Persistente?",
"submission_date": "Data di Invio",
"submission_time": "Ora di Invio",
"date": "Data",
"submission": "Invio",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Nota: questo post è ancora in attesa quindi non ha ancora una data di invio.",
"user": "Utente",
"status_": "Stato",
"approved": "Approvato",
"rejected": "Rifiutato",
"delete_post": "Elimina Post",
"thanks_your_post_is_awaiting_approval": "Grazie, il tuo post è in attesa di approvazione.",
"sorry_couldnt_find_a_title": "Ci spiace, non riusciamo a trovare un titolo...",
"please_fill_in_an_url_first": "Per favore riempi prima l'URL!",
// Post item
"share": "Condividi",
"discuss": "Discuti",
"upvote_": "Promuovi",
"sticky": "Persistente",
"status": "stato",
"votes": "voti",
"basescore": "punteggioBase",
"score": "punteggio",
"clicks": "clicks",
"views": "views",
"inactive": "inattivo",
"comment": "commento",
"comments": "commenti",
"point": "punto",
"points": "punti",
//User
"please_complete_your_profile_below_before_continuing": "Per favore completa il tuo profilo qua sotto prima di proseguire.",
"account": "Account",
"username": "Nome Utente",
"display_name": "Nome Visualizzato",
"email": "Email",
"bio": "Biografia",
"password": "Password",
"change_password": "Cambio Password?",
"old_password": "Vecchia Password",
"new_password": "Nuova Password",
"email_notifications": "Notifiche via Email",
"new_posts": "Nuovi Posts",
"comments_on_my_posts": "Commenti ai miei post",
"replies_to_my_comments": "Risposte ai miei commenti",
"forgot_password": "Password dimenticata?",
"profile_updated": "Profilo aggiornato",
"please_fill_in_your_email_below_to_finish_signing_up": "Per favore inserisci qua sotto la tua email per completare la registrazione.",
"invite": "Invita",
"uninvite": "Annulla l'invito",
"make_admin": "Rendi amministratore",
"unadmin": "Annulla amministratore",
"delete_user": "Elimina Utente",
"are_you_sure_you_want_to_delete": "Sei sicuro di voler eliminare ",
"reset_password": "Reimposta Password",
"password_reset_link_sent": "Link per reimpostare la password inviato!",
"name": "Nome",
"posts": "Post",
"comments_": "Commenti",
"karma": "Karma",
"is_invited": "È Invitato?",
"is_admin": "È Amministratore?",
"delete": "Elimina",
"member_since": "Membro dal",
"edit_profile": "Modifica profilo",
"sign_in": "Accedi",
"sign_in_": "Accedi!",
"sign_up_": "Registrati!",
"dont_have_an_account": "Non hai un account?",
"already_have_an_account": "Hai già un account?",
"sign_up": "Registrati",
"please_fill_in_all_fields": "Per favore compila tutti i campi",
"invite_": "Invita ",
"left": " sinistra",
"invite_none_left": "Invita (nessuno rimasto)",
"all": "Tutti",
"invited": "Invitati",
"uninvited": "Non invitati",
"filter_by": "Filtra per",
"sort_by": "Ordina per",
//helpers
"sorry_you_do_not_have_access_to_this_page": "Ci spiace, non hai accesso a questa pagina",
"please_sign_in_first": "Per favore prima accedi.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Ci spiace, devi essere un amministratore per vedere questa pagina.",
"sorry_you_dont_have_permissions_to_add_new_items": "Ci spiace, non hai i permessi per aggiungere nuovi elementi.",
"sorry_you_cannot_edit_this_post": "Ci spiace, non puoi modificare questo post.",
"sorry_you_cannot_edit_this_comment": "Ci spiace, non puoi modificare questo commento.",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "Devi accedere ed essere un amministratore per aggiungere una nuova categoria.",
"you_need_to_login_or_be_invited_to_post_new_comments": "Devi accedere od essere invitato per postare nuovi commenti.",
"please_wait": "Per favore attendi ",
"seconds_before_commenting_again": " secondi prima di fare un altro commento",
"your_comment_is_empty": "Il tuo commento è vuoto.",
"you_dont_have_permission_to_delete_this_comment": "Non hai i permessi per eliminare questo commento.",
"you_need_to_login_or_be_invited_to_post_new_stories": "Devi accedere o essere invitato per postare nuove storie.",
"please_fill_in_a_headline": "Per favore inserisci un titolo",
"this_link_has_already_been_posted": "Questo link è già stato postato",
"sorry_you_cannot_submit_more_than": "Ci spiace, non puoi inviare più di ",
"posts_per_day": " post al giorno",
"someone_replied_to_your_comment_on": "Qualcuno ha risposto al tuo commento su",
"has_replied_to_your_comment_on": " ha risposto al tuo commento su",
"read_more": "Leggi di più",
"a_new_comment_on_your_post": "Un nuovo commento sul tuo post",
"you_have_a_new_comment_by": "Hai un nuovo commento di ",
"on_your_post": " sul tuo post",
"has_created_a_new_post": " ha creato un nuovo post",
"your_account_has_been_approved": "Il tuo account è stato approvato.",
"welcome_to": "Benvenuto a ",
"start_posting": "Inizia a postare.",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Please fill in a title",
"seconds_before_posting_again": " seconds before posting again",
"upvoted": "Upvoted",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"profile": "Profile",
"sign_out": "Sign Out",
"invitedcount": "InvitedCount",
"invites": "Invites",
"invited": "Invited?",
"admin": "Admin?",
"actions": "Actions",
"invites_left": "invites left",
"id": "ID",
"name": "Name:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Upvoted Posts",
"downvoted_posts": "Downvoted Posts",
"mark_as_read": "Mark as read",
//Common
"pending": "In attesa",
"loading": "Caricamento...",
"submit": "Invia",
"you_must_be_logged_in": "Devi effettuare l'accesso.",
"are_you_sure": "Sei sicuro?",
"please_log_in_first": "Per favore esegui prima l'accesso",
"sign_in_sign_up_with_twitter": "Accedi/Registrati con Twitter",
"load_more": "Carica altro"
}

215
i18n/tr.i18n.json Normal file
View file

@ -0,0 +1,215 @@
{
//Navigation
"menu": "Menü",
"top": "En Yukarı",
"new": "Yeni",
"digest": "Toplu",
"users": "Kullanıcılar",
"settings": "Ayarlar",
"admin": "Admin",
"post": "Paylaş",
"toolbox": "Araç Kutusu",
"sign_up_sign_in": "Kayıt Ol/Giriş Yap",
"my_account": "Hesabım",
"view_profile": "Profili gör",
"edit_account": "Hesabı Ayarla",
//Main
"new_posts": "Yeni Paylaşımlar",
//Commments
"your_comment_has_been_deleted": "Yorumunuz silindi",
"comment_": "Yorum",
"delete_comment": "Yorumu Sil",
"add_comment": "Yorum Ekle",
"upvote": "1",
"downvote": "-1",
"link": "link",
"edit": "Ayarla",
"reply": "Cevap",
"no_comments": "Yorum yok",
//Errors
"you_are_already_logged_in": "Zaten giriş yapmış durumdasınız",
"sorry_this_is_a_private site_please_sign_up_first": "Özür dileriz, bu özel bir site. Lütfen önce giriş yapınız",
"thanks_for_signing_up": "Kayıt olduğunuz için teşekkür ederiz",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "Bu site sadece davetliler için ama bir yer açılınca size haber vereceğiz",
"sorry_you_dont_have_the_rights_to_view_this_page": "Özür dileriz, bu sayfaya erişiminiz yok",
"not_found": "Bulunmadı!",
"ere_sorry_whatever_you_were_looking_for_isnt_here": "Özür dileriz, neye bakıyorsanız burada değil..",
//Notifications
"no_notifications": "Bildirim yok",
"1_notification": "1 bildirim",
"notifications": "Bildirimler",
"mark_all_as_read": "Hepsini okunmuş olarak işaretle",
// Post deleted
"your_post_has_been_deleted": "Paylaşımınız silindi",
// Post digest
"the_top_5_posts_of_each_day": "Her günün en üst 5 paylaşımı",
"previous_day": "Önceki gün",
"next_day": "Sonraki gün",
"Sorry, no posts for today": "Özür dileriz, bugün bir paylaşım yok",
"sorry_no_posts_for_today": "Özür dileriz, paylaşım yok",
"today": "Bugün",
"yesterday": "Dün",
// Post submit & edit
"created": "Oluşturuldu",
"title": "Başlık",
"suggest_title": "Başlık öner",
"url": "URL",
"short_URL": "Kısa URL",
"body": "Metin",
"category": "Kategori",
"inactive_": "Etkin değil?",
"sticky_": "Yapışkan?",
"submission_date": "Yayın tarihi",
"submission_time": "Yayın zamanı",
"date": "Tarih",
"submission": "Yayın",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "Bu paylaşım hala onay bekliyor, onun için yayın tarihi yok",
"user": "Kullanıcı",
"status": "Durum",
"approved": "Onaylandı",
"rejected": "Reddedildi",
"delete_post": "Paylaşımı sil",
"thanks_your_post_is_awaiting_approval": "Teşekkürler, paylaşımınız onay bekliyor",
"sorry_couldnt_find_a_title": "Özür dileriz, bir başlık bulamadık",
"please_fill_in_an_url_first": "Lütfen önce bir URL giriniz",
// Post item
"share": "Paylaş",
"discuss": "Yorum yap",
"upvote_": "Beğen",
"sticky": "Yapışkan",
"status": "Durum",
"votes": "oylar",
"baseScore": "temel skor",
"score": "skor",
"clicks": "tıklamalar",
"inactive": "etkin değil",
"comment": "yorum",
"comments": "yorumlar",
"point": "nokta",
"points": "noktalar",
//User
"please_complete_your_profile_below_before_continuing": "Lütfen devam etmeden önce aşağıdaki profilinizi tamamlayınız",
"account": "Hesap",
"username": "Kullanıcı adı",
"display_name": "Görülen isim",
"email": "Eposta",
"bio": "Bio",
"password": "şifre",
"change_password": "şifreyi değiştir?",
"old_password": "Eski şifre",
"new_password": "Yeni şifre",
"email_notifications": "e-posta bildirimi",
"new_posts": "Yeni paylaşımlar",
"comments_on_my_posts": "Paylaşımımdaki yorumlar",
"replies_to_my_comments": "Yorumlarıma cevaplar",
"forgot_password": "Şifreyi unuttunuz mu?",
"profile_updated": "Profil güncellendi",
"please_fill_in_your_email_below_to_finish_signing_up": "Lütfen kaydınızı tamamlamak için aşağıya e-postanızı giriniz",
"invite": "Davet et",
"uninvite": "Daveti geri al",
"make_admin": "Admin yap",
"unadmin": "Admini kaldır",
"delete_user": "Kullanıcıyı sil",
"are_you_sure_you_want_to_delete": "Silmek istediğinize emin misiniz?",
"reset_password": "Şifreyi sıfırla",
"password_reset_link_sent": "Şifre sıfırlama bağlantısı gönderildi!",
"name": "İsim",
"posts": "Paylaşımlar",
"comments": "Yorumlar",
"karma": "Karma",
"is_invited": "Davet edildi mi?",
"is_admin": "Admin mi?",
"delete": "Sil",
"member_since": "Üyelik başlangıcı",
"edit_profile": "Profili değiştir",
"sign_in": "Giriş yap",
"sign_in_": "Giriş yap!",
"sign_up_": "Kayıt ol!",
"dont_have_an_account": "Hesabınız yok mu?",
"already_have_an_account": "Hesabınız var mı?",
"sign_up": "Kayıt ol",
"please_fill_in_all_fields": "Lütfen bütün alanları doldurunuz",
"invite ": "Davet et",
"left": " kalan",
"invite_none_left": "Davet et (hiç kalmadı)",
"all": "Hepsi",
"invited": "Davet edildi",
"uninvited": "Davet edilmedi",
"filter_by": "Filtreleme kıstası",
"sort_by": "Sıralama kıstası",
//helpers
"sorry_you_do_not_have_access_to_this_page": "Özür dileriz, bu sayfaya erişiminiz yok",
"please_sign_in_first": "Lütfen önce giriş yapın",
"sorry_you_have_to_be_an_admin_to_view_this_page": "Özür dileriz, sadece adminler bu sayfayı görebilir",
"sorry_you_dont_have_permissions_to_add_new_items": "Özür dileriz, yeni birşeyler eklemeye yetkiniz yok",
"sorry_you_cannot_edit_this_post": "Özür dileriz, bu paylaşımı değiştiremezsiniz",
"sorry_you_cannot_edit_this_comment": "Özür dileriz, bu yorumu değiştiremezsiniz",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "Yeni kategori eklemek için admin olarak giriş yapmanız lazım",
"you_need_to_login_or_be_invited_to_post_new_comments": "Yorum yapmak için giriş yapmanız veya davet edilmeniz lazım",
"please_wait": "Lütfen bekleyin ",
"seconds_before_commenting_again": " saniye daha beklemiz lazım tekrar yorum yapmadan önce",
"your_comment_is_empty": "Yorumunuz boş",
"you_dont_have_permission_to_delete_this_comment": "Bu yorumu silmek için izniniz yok",
"you_need_to_login_or_be_invited_to_post_new_stories": "Paylaşım yapmak için giriş yapmanız veya davet edilmeniz lazım",
"please_fill_in_a_headline": "Lütfen bir başlık girin",
"this_link_has_already_been_posted": "Bu bağlantı daha önce paylaşılmıştı",
"sorry_you_cannot_submit_more_than": "Özür dileriz, bundan daha fazla paylaşamazsınız ",
"posts_per_day": " paylaşım / gün",
"someone_replied_to_your_comment_on": "Birisi yorumunuza cevap verdi şu konu hakkında",
"has_replied_to_your_comment_on": " yorumunuza cevap verdi şu konu hakkında",
"read_more": "Daha fazla oku",
"a_new_comment_on_your_post": "Yeni bir yorum paylaşımınızda",
"you_have_a_new_comment_by": "Yeni bir yorum geldi ",
"on_your_post": " paylaşımınızda",
"has_created_a_new_post": " yeni bir paylaşım yaptı",
"your_account_has_been_approved": "Hesabınız onaylandı",
"welcome_to": "Hoşgeldiniz ",
"start_posting": "Paylaşıma başlayın",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Lütfen bir başlık girin",
"seconds_before_posting_again": " saniye kaldı bir paylaşım daha yapmadan önce",
"upvoted": "Yukarı oylandı",
"posted_date": "Paylaşım Tarihi",
"posted_time": "Paylaşım Zamanı",
"profile": "Profil",
"sign_out": ıkış Yap",
"invitedcount": "Davetiye Sayısı",
"invites": "Davetiyeler",
"invited": "Davet edildi mi?",
"admin": "Admin?",
"actions": "Yapılanlar",
"invites_left": "davetiye kaldı",
"id": "ID",
"name": "İsim",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Yukarı oy alan paylaşımlar",
"downvoted_posts": "Aşağı oy alan paylaşımlar",
"mark_as_read": "Okundu gibi işaretle",
//Common
"pending": "Onay bekliyor",
"loading": "Yüklüyor",
"submit": "Gönder",
"you_must_be_logged_in": "Giriş yapmanız lazım",
"are_you_sure": "Emin misiniz?",
"please_log_in_first": "Lütfen önce giriş yapın",
"sign_in_sign_up_with_twitter": "Twitter ile kayıt ol/ giriş yap",
"load_more": "Daha Fazla yükle"
}

219
i18n/zh-CN.i18n.json Normal file
View file

@ -0,0 +1,219 @@
{
//Navigation
"view": "视图",
"menu": "菜单",
"top": "置顶",
"new": "最新",
"digest": "摘要",
"users": "用户",
"settings": "设置",
"admin": "管理",
"post": "提交",
"toolbox": "工具箱",
"sign_up_sign_in": "注册/登录",
"my_account": "帐号",
"view_profile": "个人资料",
"edit_account": "编辑帐号",
//Main
"new_posts": "最新提交",
//Commments
"your_comment_has_been_deleted": "你的评论已经被删除",
"comment_": "评论",
"delete_comment": "删除评论",
"add_comment": "评论",
"upvote": "顶",
"downvote": "踩",
"link": "链接",
"edit": "编辑",
"reply": "回复",
"no_comments": "暂时没有评论",
//Errors
"you_are_already_logged_in": "你已经登录",
"sorry_this_is_a_private_site_please_sign_up_first": "对不起, 请先注册再进行后续操作",
"thanks_for_signing_up": "感谢您的注册!",
"the_site_is_currently_invite_only_but_we_will_let_you_know_as_soon_as_a_spot_opens_up": "该站点暂时只允许邀请访问, 如果开放了我们会让你知道",
"sorry_you_dont_have_the_rights_to_view_this_page": "抱歉你没有权利查看此页面",
"not_found": "页面不存在",
"were_sorry_whatever_you_were_looking_for_isnt_here": "抱歉没有你要查看的内容!",
//Notifications
"no_notifications": "无消息",
"1_notification": "1 个消息",
"notifications": "消息",
"mark_all_as_read": "标记所有",
// Post deleted
"your_post_has_been_deleted": "你的帖子已经被删除",
// Post digest
"the_top_5_posts_of_each_day": "每天前5名的帖子",
"previous_day": "前一天",
"next_day": "后一天",
"sorry_no_posts_for_today": "抱歉今天没有新的帖子",
"today": "今天",
"yesterday": "昨天",
// Post submit & edit
"created": "创建",
"title": "标题",
"suggest_title": "显示标题",
"url": "链接地址",
"short_url": "短网址",
"body": "内容",
"category": "分类",
"inactive_": "Inactive?",
"sticky_": "置顶?",
"submission_date": "提交日期",
"submission_time": "提交时间",
"date": "日期",
"submission": "提交",
"note_this_post_is_still_pending_so_it_has_no_submission_timestamp_yet": "这篇文章没有进行审核.",
"user": "用户",
"status_": "专题",
"approved": "审核",
"rejected": "拒接",
"delete_post": "删除帖子",
"thanks_your_post_is_awaiting_approval": "感谢, 你的帖子正在等待批准.",
"sorry_couldnt_find_a_title": "抱歉找不相关话题",
"please_fill_in_an_url_first": "请在第一栏填写链接",
// Post item
"share": "分享",
"discuss": "讨论",
"upvote_": "顶",
"sticky": "置顶",
"status": "状态",
"votes": "得票",
"basescore": "基础得分",
"score": "得分",
"clicks": "点击",
"views": "views",
"inactive": "不活跃",
"comment": "评论",
"comments": "评论数",
"point": "点击",
"points": "点击数",
//User
"please_complete_your_profile_below_before_continuing": "在继续之前请填写相关资料.",
"account": "帐号",
"username": "用户名",
"display_name": "昵称",
"email": "Email",
"bio": "小传",
"password": "密码",
"change_password": "修改密码?",
"old_password": "旧密码",
"new_password": "新密码",
"email_notifications": "邮箱提醒",
"new_posts": "最新主题",
"comments_on_my_posts": "评论我的主题时",
"replies_to_my_comments": "回复我的回复时",
"forgot_password": "忘记密码?",
"profile_updated": "更新资料",
"please_fill_in_your_email_below_to_finish_signing_up": "请填写你的电子邮件完成注册.",
"invite": "邀请",
"uninvite": "未激活",
"make_admin": "设置为管理员",
"unadmin": "取消管理资格",
"delete_user": "删除用户",
"are_you_sure_you_want_to_delete": "你确定要删除用户吗 ",
"reset_password": "重置密码",
"password_reset_link_sent": "密码重置链接已发送",
"name": "名字",
"posts": "帖子数",
"comments_": "评论数",
"karma": "Karma",
"is_invited": "邀请用户?",
"is_admin": "管理员?",
"delete": "删除",
"member_since": "加入至今",
"edit_profile": "修改个人资料",
"sign_in": "登录",
"sign_in_": "登录!",
"sign_up_": "注册!",
"dont_have_an_account": "还没有帐号?",
"already_have_an_account": "已有帐号?",
"sign_up": "注册",
"please_fill_in_all_fields": "请填写完整",
"invite_": "邀请 ",
"left": " restante",
"invite_none_left": "Invite (none left)",
"all": "全部",
"invited": "邀请",
"uninvited": "未被邀请",
"filter_by": "过滤",
"sort_by": "排序",
//helpers
"sorry_you_do_not_have_access_to_this_page": "抱歉你没有权限访问此页面",
"please_sign_in_first": "请先登录.",
"sorry_you_have_to_be_an_admin_to_view_this_page": "抱歉你必须是管理员才能查看此页面",
"sorry_you_dont_have_permissions_to_add_new_items": "抱歉你没有权限添加新项.",
"sorry_you_cannot_edit_this_post": "对不起你不能编辑这个帖子",
"sorry_you_cannot_edit_this_comment": "对不起你不能编辑这个评论",
//Collections
"you_need_to_login_and_be_an_admin_to_add_a_new_category": "你必须登录并且是管理员才能添加新类别.",
"you_need_to_login_or_be_invited_to_post_new_comments": "你需要登录或被邀请才能发表新的评论.",
"please_wait": "请稍等 ",
"seconds_before_commenting_again": " 秒后在评论",
"your_comment_is_empty": "你的评论是空的.",
"you_dont_have_permission_to_delete_this_comment": "你没有删除此评论的权限.",
"you_need_to_login_or_be_invited_to_post_new_stories": "你需要登录或被邀请才能发布新的内容.",
"please_fill_in_a_headline": "请填写一个标题",
"this_link_has_already_been_posted": "这个链接已发布",
"sorry_you_cannot_submit_more_than": "对不起, 内容不能超过",
"posts_per_day": " 评价每日发帖",
"someone_replied_to_your_comment_on": "有人回复了你的评论",
"has_replied_to_your_comment_on": " 已经有人回复了你的评论",
"read_more": "查看更多",
"a_new_comment_on_your_post": "你发表的主题有新的评论",
"you_have_a_new_comment_by": "你有一个新的评论在 ",
"on_your_post": " 在你的帖子",
"has_created_a_new_post": " 发一个新帖",
"your_account_has_been_approved": "你的帐号已被批准",
"welcome_to": "欢迎来到 ",
"start_posting": "开始发布.",
// Translation needed (found during migration to tap:i18n)
"please_fill_in_a_title": "Please fill in a title",
"seconds_before_posting_again": " seconds before posting again",
"upvoted": "Upvoted",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"posted_date": "Posted Date",
"posted_time": "Posted Time",
"profile": "Profile",
"sign_out": "Sign Out",
"invitedcount": "InvitedCount",
"invites": "Invites",
"invited": "Invited?",
"admin": "Admin",
"actions": "Actions",
"invites_left": "invites left",
"id": "ID",
"name": "Name:",
"bio": "Bio:",
"github": "GitHub",
"site": "Site",
"upvoted_posts": "Upvoted Posts",
"downvoted_posts": "Downvoted Posts",
"mark_as_read": "Mark as read",
//Common
"pending": "悬而未决...",
"loading": "加载中...",
"submit": "提交",
"you_must_be_logged_in": "你必须登录.",
"are_you_sure": "是否确定?",
"please_log_in_first": "请先登录",
"sign_in_sign_up_with_twitter": "使用微博等/注册",
"load_more": "加载更多",
"administration": "管理",
"best": "精华"
}

View file

@ -74,10 +74,4 @@ AccountsTemplates.configure({
showAddRemoveServices: false,
showPlaceholders: true,
*/
});
// Initialization
Meteor.startup(function(){
AccountsTemplates.init();
});

3
lib/config/avatar.js Normal file
View file

@ -0,0 +1,3 @@
Avatar.options = {
emailHashProperty: 'email_hash'
};

View file

@ -6,7 +6,7 @@ getCurrentTemplate = function() {
return Router.current().lookupTemplate();
};
getCurrentRoute = function() {
return Router._currentController.path;
return Router.current().url;
};
t=function(message){
var d=new Date();

View file

@ -1,192 +0,0 @@
i18n.translations.de = {
//Navigation
"Menu": "Menü",
"Top": "Top",
"New": "Neu",
"Digest": "Zusammenfassung",
"Categories": "Kategorien",
"Users": "Benutzer",
"Settings": "Einstellungen",
"Admin": "Admin",
"Post": "Link eintragen",
"Toolbox": "Werkzeuge",
"Sign Up/Sign In": "Registrieren/Anmelden",
"My Account": "Mein Konto",
"View Profile": "Profil anzeigen",
"Edit Account": "Konto bearbeiten",
//Main
"New Posts": "Neue Links",
//Commments
"Your comment has been deleted.": "Dein Kommentar wurde gelöscht.",
"Comment": "Kommentieren",
"Delete Comment": "Kommentar löschen",
"Add Comment": "Kommentar hinzufügen",
"upvote": "+1",
"downvote": "-1",
"link": "link",
"Edit": "bearbeiten",
"Reply": "antworten",
"No comments.": "Keine Kommentare.",
//Errors
"You are already logged in": "Du bist bereits eingeloggt",
"Sorry, this is a private site. Please sign up first.": "Dies ist ein privates Angebot. Du musst dich erst registrieren.",
"Thanks for signing up!": "Vielen Dank für Deine Registrierung!",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "Derzeit sind Neuregistrierungen nur mit einer Einladung möglich, aber wir werden dich wissen lassen, wenn wir unsere Registrierung wieder öffnen.",
"Sorry, you don't have the rights to view this page.": "Entschuldigung, Du hast leider keine Rechte diese Seite anzuzeigen.",
"Not Found!": "Nichts gefunden!",
"We're sorry; whatever you were looking for isn't here..": "Es tut uns leid, wonach auch immer Du gesucht hast, hier ist es nicht.",
//Notifications
"No notifications": "Keine Benachrichtigungen",
"1 notification": "1 Benachrichtigung",
"notifications": "Benachrichtigungen",
"Mark all as read": "Alle als gelesen markieren",
// Post deleted
"Your post has been deleted.": "Dein Link wurde gelöscht.",
// Post digest
"The top 5 posts of each day.": "Die Top-5-Links eines jeden Tages.",
"Previous Day": "Einen Tag zurück",
"Next Day": "Einen Tag vor",
"Sorry, no posts for today": "Heute gibt es keine Links.",
"Sorry, no posts for": "Keine Links für",
"Today": "Heute",
"Yesterday": "Gestern",
// Post submit & edit
"Created": "Erstellt",
"Title": "Titel",
"Suggest title": "Titelvorschlag",
"URL": "URL",
"Short URL": "Kurz-URL",
"Body": "Beschreibung",
"Category": "Kategorie",
"Inactive?": "Inaktiv?",
"Sticky?": "Anheften?",
"Submission Date": "Eintragsdatum",
"Submission Time": "Eintragszeit",
"Date": "Datum",
"Submission": "Eintragung",
"Note: this post is still pending so it has no submission timestamp yet.": "Hinweis: Dieser Beitrag wartet noch auf Freischaltung, daher gibt es noch kein Datum und keine Uhrzeit.",
"User": "Benutzer",
"Status": "Status",
"Approved": "Genehmigt",
"Rejected": "Abgelehnt",
"Delete Post": "Link löschen",
"Thanks, your post is awaiting approval.": "Vielen Dank, Dein Beitrag wartet auf Freischaltung.",
"Sorry, couldn't find a title...": "Du hast vergessen einen Titel anzugeben...",
"Please fill in an URL first!": "Du musst eine URL/einen Link angeben!",
// Post item
"Share": "Teilen",
"Discuss": "Kommentare",
"Upvote": "Abstimmen",
"Sticky": "Angeheftet",
"status": "status",
"votes": "Stimmen",
"baseScore": "Punktebasis",
"score": "Punkte",
"clicks": "klicks",
"inactive": "inaktiv",
"comment": "Kommentar",
"comments": "Kommentare",
"point": "Punkt",
"points": "Punkte",
//User
"Please complete your profile below before continuing.": "Bitte füllen Dein Profil vollständig aus bevor du fortfährst.",
"Account": "Konto",
"Username": "Benutzername",
"Display Name": "Angezeigter Name",
"Email": "Email",
"Bio": "Bio",
"Password": "Passwort",
"Change Password?": "Passwort ändern?",
"Old Password": "Altes Passwort",
"New Password": "Neues Passwort",
"Email Notifications": "Email-Benachrichtigung",
"New Posts": "Neue Links",
"Comments on my posts": "Kommentare zu meinen Links",
"Replies to my comments": "Antworten auf meine Kommentare",
"Forgot password?": "Passwort vergessen?",
"Profile updated": "Profil aktualisiert",
"Please fill in your email below to finish signing up.": "Bitte trage Deine Email-Adresse ein um die Registrierung abzuschließen.",
"Invite": "Einladen",
"Uninvite": "Ausladen",
"Make admin": "Zum Admin ernennen",
"Unadmin": "Als Admin entfernen",
"Delete User": "Benutzer löschen",
"Are you sure you want to delete ": "Bist du Dir sicher, dass du folgendes löschen willst: ",
"Reset Password": "Passwort zurücksetzen",
"Password reset link sent!": "Ein Link zum zurücksetzen des Passworts wurde versendet!",
"Name": "Name",
"Posts": "Links",
"Comments": "Kommentare",
"Karma": "Karma",
"Is Invited?": "Wurde eingeladen?",
"Is Admin?": "Ist Admin?",
"Delete": "Löschen",
"Member since": "Mitglied seit",
"Edit profile": "Profil bearbeiten",
"Sign In": "Einloggen",
"Sign in!": "Einloggen!",
"Sign up!": "Registrieren!",
"Don't have an account?": "Du hast noch kein Konto?",
"Already have an account?": "Du hast bereits ein Konto?",
"Sign Up": "Registrieren",
"Please fill in all fields": "Bitte fülle alle Felder aus",
"Invite ": "Einladung(en) ",
"left": " übrig",
"Invite (none left)": "Einladungen (keine übrig)",
"All": "Alle",
"Invited": "Eingeladen",
"Uninvited": "Nicht eingeladen",
"Filter by": "Filtern nach",
"Sort by": "Sortieren nach",
//helpers
"Sorry, you do not have access to this page": "Sorry, Du hast keinen Zugang zu dieser Seite",
"Please Sign In First.": "Bitte melde Dich zuerst an.",
"Sorry, you have to be an admin to view this page.": "Sorry, Du musst Admin sein um diese Seite anzeigen zu können.",
"Sorry, you don't have permissions to add new items.": "Sorry, Du hast keine Berechtigung neue Einträge zu erstellen.",
"Sorry, you cannot edit this post.": "Sorry, Du kannst diesen Beitrag nicht bearbeiten.",
"Sorry, you cannot edit this comment.": "Sorry, Du kannst diesen Kommentar nicht bearbeiten.",
//Collections
"You need to login and be an admin to add a new category.": "Du musst Dich anmelden und ein Admin sein um eine neue Kategorien hinzuzufügen.",
"You need to login or be invited to post new comments.": "Du musst dich einloggen oder eingeladen sein um neue Kommentare schreiben zu können.",
"Please wait ": "Bitte warte ",
" seconds before commenting again": " Sekunden, bevor du wieder kommentierst.",
"Your comment is empty.": "Dein Kommentar ist leer.",
"You don't have permission to delete this comment.": "Du hast keine Berechtigung diesen Kommentar zu löschen.",
"You need to login or be invited to post new stories.": "Du musst eingeloggt oder eingeladen sein um einen neuen Link zu posten.",
"Please fill in a headline": "Bitte fülle den Titel aus",
"This link has already been posted": "Dieser Link wurde bereits gepostet",
"Sorry, you cannot submit more than ": "Es tut uns leid, Du kannst nicht mehr als ",
" posts per day": " Links pro Tag eintragen",
"Someone replied to your comment on": "Jemand hat auf Deinen Kommentar geantwortet bei",
" has replied to your comment on": " hat auf Deinen Kommentar geantwortet bei",
"Read more": "weiterlesen",
"A new comment on your post": "Ein neuer Kommentar zu Deinem Link",
"You have a new comment by ": "Du hast einen neuen Kommentar von ",
" on your post": " bei Deinem Link",
" has created a new post": " hat einen neuen Link erstellt",
"Your account has been approved.": "Dein Konto wurde freigeschaltet.",
"Welcome to ": "Willkommen bei ",
"Start posting.": "Fang an Links einzutragen.",
//Common
"Pending": "Wartet",
"Loading...": "lädt...",
"Submit": "Abschicken",
"You must be logged in.": "Du musst angemeldet sein.",
"Are you sure?": "Bist Du sicher?",
"Please log in first": "Bitte melde Dich zuerst an",
"Sign In/Sign Up with Twitter": "Anmelden/Registrieren mit Twitter",
"Load more": "Mehr Laden"
};

View file

@ -1,192 +0,0 @@
i18n.translations.en = {
//Navigation
"Menu": "Menu",
"Top": "Top",
"New": "New",
"Digest": "Digest",
"Categories": "Categories",
"Users": "Users",
"Settings": "Settings",
"Admin": "Admin",
"Post": "Post",
"Toolbox": "Toolbox",
"Sign Up/Sign In": "Sign Up/Sign In",
"My Account": "My Account",
"View Profile": "View Profile",
"Edit Account": "Edit Account",
//Main
"New Posts": "New Posts",
//Commments
"Your comment has been deleted.": "Your comment has been deleted.",
"Comment": "Comment",
"Delete Comment": "Delete Comment",
"Add Comment": "Add Comment",
"upvote": "upvote",
"downvote": "downvote",
"link": "link",
"Edit": "Edit",
"Reply": "Reply",
"No comments.": "No comments.",
//Errors
"You are already logged in": "You are already logged in",
"Sorry, this is a private site. Please sign up first.": "Sorry, this is a private site. Please sign up first.",
"Thanks for signing up!": "Thanks for signing up!",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "The site is currently invite-only, but we will let you know as soon as a spot opens up.",
"Sorry, you don't have the rights to view this page.": "Sorry, you don't have the rights to view this page.",
"Not Found!": "Not Found!",
"We're sorry; whatever you were looking for isn't here..": "We're sorry; whatever you were looking for isn't here..",
//Notifications
"No notifications": "No notifications",
"1 notification": "1 notification",
"notifications": "notifications",
"Mark all as read": "Mark all as read",
// Post deleted
"Your post has been deleted.": "Your post has been deleted.",
// Post digest
"The top 5 posts of each day.": "The top 5 posts of each day.",
"Previous Day": "Previous Day",
"Next Day": "Next Day",
"Sorry, no posts for today": "Sorry, no posts for today",
"Sorry, no posts for": "Sorry, no posts for",
"Today": "Today",
"Yesterday": "Yesterday",
// Post submit & edit
"Created": "Created",
"Title": "Title",
"Suggest title": "Suggest title",
"URL": "URL",
"Short URL": "Short URL",
"Body": "Body",
"Category": "Category",
"Inactive?": "Inactive?",
"Sticky?": "Sticky?",
"Submission Date": "Submission Date",
"Submission Time": "Submission Time",
"Date": "Date",
"Submission": "Submission",
"Note: this post is still pending so it has no submission timestamp yet.": "Note: this post is still pending so it has no submission timestamp yet.",
"User": "User",
"Status": "Status",
"Approved": "Approved",
"Rejected": "Rejected",
"Delete Post": "Delete Post",
"Thanks, your post is awaiting approval.": "Thanks, your post is awaiting approval.",
"Sorry, couldn't find a title...": "Sorry, couldn't find a title...",
"Please fill in an URL first!": "Please fill in an URL first!",
// Post item
"Share": "Share",
"Discuss": "Discuss",
"Upvote": "Upvote",
"Sticky": "Sticky",
"status": "status",
"votes": "votes",
"baseScore": "baseScore",
"score": "score",
"clicks": "clicks",
"inactive": "inactive",
"comment": "comment",
"comments": "comments",
"point": "point",
"points": "points",
//User
"Please complete your profile below before continuing.": "Please complete your profile below before continuing.",
"Account": "Account",
"Username": "Username",
"Display Name": "Display Name",
"Email": "Email",
"Bio": "Bio",
"Password": "Password",
"Change Password?": "Change Password?",
"Old Password": "Old Password",
"New Password": "New Password",
"Email Notifications": "Email Notifications",
"New Posts": "New Posts",
"Comments on my posts": "Comments on my posts",
"Replies to my comments": "Replies to my comments",
"Forgot password?": "Forgot password?",
"Profile updated": "Profile updated",
"Please fill in your email below to finish signing up.": "Please fill in your email below to finish signing up.",
"Invite": "Invite",
"Uninvite": "Uninvite",
"Make admin": "Make admin",
"Unadmin": "Unadmin",
"Delete User": "Delete User",
"Are you sure you want to delete ": "Are you sure you want to delete ",
"Reset Password": "Reset Password",
"Password reset link sent!": "Password reset link sent!",
"Name": "Name",
"Posts": "Posts",
"Comments": "Comments",
"Karma": "Karma",
"Is Invited?": "Is Invited?",
"Is Admin?": "Is Admin?",
"Delete": "Delete",
"Member since": "Member since",
"Edit profile": "Edit profile",
"Sign In": "Sign In",
"Sign in!": "Sign in!",
"Sign up!": "Sign up!",
"Don't have an account?": "Don't have an account?",
"Already have an account?": "Already have an account?",
"Sign Up": "Sign Up",
"Please fill in all fields": "Please fill in all fields",
"Invite ": "Invite ",
"left": " left",
"Invite (none left)": "Invite (none left)",
"All": "All",
"Invited": "Invited",
"Uninvited": "Uninvited",
"Filter by": "Filter by",
"Sort by": "Sort by",
//helpers
"Sorry, you do not have access to this page": "Sorry, you do not have access to this page",
"Please Sign In First.": "Please Sign In First.",
"Sorry, you have to be an admin to view this page.": "Sorry, you have to be an admin to view this page.",
"Sorry, you don't have permissions to add new items.": "Sorry, you don't have permissions to add new items.",
"Sorry, you cannot edit this post.": "Sorry, you cannot edit this post.",
"Sorry, you cannot edit this comment.": "Sorry, you cannot edit this comment.",
//Collections
"You need to login and be an admin to add a new category.": "You need to login and be an admin to add a new category.",
"You need to login or be invited to post new comments.": "You need to login or be invited to post new comments.",
"Please wait ": "Please wait ",
" seconds before commenting again": " seconds before commenting again",
"Your comment is empty.": "Your comment is empty.",
"You don't have permission to delete this comment.": "You don't have permission to delete this comment.",
"You need to login or be invited to post new stories.": "You need to login or be invited to post new stories.",
"Please fill in a headline": "Please fill in a headline",
"This link has already been posted": "This link has already been posted",
"Sorry, you cannot submit more than ": "Sorry, you cannot submit more than ",
" posts per day": " posts per day",
"Someone replied to your comment on": "Someone replied to your comment on",
" has replied to your comment on": " has replied to your comment on",
"Read more": "Read more",
"A new comment on your post": "A new comment on your post",
"You have a new comment by ": "You have a new comment by ",
" on your post": " on your post",
" has created a new post": " has created a new post",
"Your account has been approved.": "Your account has been approved.",
"Welcome to ": "Welcome to ",
"Start posting.": "Start posting.",
//Common
"Pending": "Pending",
"Loading...": "Loading...",
"Submit": "Submit",
"You must be logged in.": "You must be logged in.",
"Are you sure?": "Are you sure?",
"Please log in first": "Please log in first",
"Sign In/Sign Up with Twitter": "Sign In/Sign Up with Twitter",
"Load more": "Load more"
};

View file

@ -1,190 +0,0 @@
i18n.translations.es = {
//Navigation
"View": "Vista",
"Menu": "Menu",
"Top": "Todos",
"New": "Nuevos",
"Digest": "Resumen",
"Categories": "Categorías",
"Users": "Usuarios",
"Settings": "Configuración",
"Admin": "Admin",
"Post": "Post",
"Toolbox": "Herramientas",
"Sign Up/Sign In": "Connectarse/Crear una cuenta",
"My Account": "Mi Cuenta",
"View Profile": "Ver perfil",
"Edit Account": "Editar cuenta",
//Main
"New Posts": "Nuevos Posts",
//Commments
"Your comment has been deleted.": "Tu comentario ha sido borrado",
"Comment": "Comentario",
"Delete Comment": "Borrar el comentario",
"Add Comment": "Añadir comentario",
"upvote": "Voto Positivo",
"downvote": "Voto Negativo",
"link": "link",
"Edit": "Editar",
"Reply": "Contestar",
"No comments.": "No hay comentarios.",
//Errors
"You are already logged in": "Ya estás conectado",
"Sorry, this is a private site. Please sign up first.": "Lo sentimos pero esta pagina es privada. Por favor, conéctese para verla",
"Thanks for signing up!": "Gracias por registrarte",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "El sitio solo es accesible mediante invitación, pero te lo haremos saber tan pronto como abra al público.",
"Sorry, you don't have the rights to view this page.": "Lo sentimos pero no tienes los derechos suficientes para ver esta pagina",
"Not Found!": "No encontramos nada!",
"We're sorry; whatever you were looking for isn't here..": "Lo sentimos pero aqui no hay nada.. ",
//Notifications
"No notifications": "Ninguna notificación",
"1 notification": "1 notificación",
"notifications": "notificaciones",
"Mark all as read": "Marcar todas como leídas",
// Post deleted
"Your post has been deleted.": "Tu post ha sido borrado.",
// Post digest
"The top 5 posts of each day.": "Los 5 mejores posts de cada día",
"Previous Day": "Dia anterior",
"Next Day": "Dia siguiente",
"Sorry, no posts for today": "Lo sentimos, no hay post para hoy",
"Today": "Hoy",
"Yesterday": "Ayer",
// Post submit & edit
"Created": "Creado",
"Title": "Título",
"Suggest title": "Proponer un titulo",
"URL": "URL",
"Short URL": "URL Corta",
"Body": "Descripción",
"Category": "Categoría",
"Inactive?": "Inactivo?",
"Sticky?": "Pegado?",
"Submission Date": "Fecha de entrega",
"Submission Time": "Hora de entrega",
"Date": "Fecha",
"Submission": "Entrega",
"Note: this post is still pending so it has no submission timestamp yet.": "Nota : Este post esta en proceso de validación entonces no tiene fecha de entrega todavía.",
"User": "Usuario",
"Status": "Estado",
"Approved": "Aprobado",
"Rejected": "Rechezado",
"Delete Post": "Borrar este post",
"Thanks, your post is awaiting approval.": "Gracias, su post esta esperando validación.",
"Sorry, couldn't find a title...": "Lo sentimos, impossible de encontrar este título.",
"Please fill in an URL first!": "Tienes que poner una URL.",
// Post item
"Share": "Compartir",
"Discuss": "Comentar",
"Upvote": "Votar",
"Sticky": "Pegado",
"status": "Estado",
"votes": "votos",
"baseScore": "baseScore",
"score": "puntuación",
"clicks": "clicks",
"inactive": "inactivo",
"comment": "comentario",
"comments": "comentarios",
"point": "punto",
"points": "puntos",
//User
"Please complete your profile below before continuing.": "Por favor complete su perfil antes de seguir.",
"Account": "Cuenta",
"Username": "Nombre de usuario",
"Display Name": "Nombre",
"Email": "Email",
"Bio": "Bio",
"Password": "Contraseña",
"Change Password?": "Cambiar de contraseña",
"Old Password": "Antigua Contraseña",
"New Password": "Nueva Contraseña",
"Email Notifications": "Notificaciónes por Email",
"New Posts": "Nuevo Post",
"Comments on my posts": "Comentarios de mi post",
"Replies to my comments": "Respuestas a mis comentarios",
"Forgot password?": "Olvidaste tu contraseña?",
"Profile updated": "Perfil actualizado",
"Please fill in your email below to finish signing up.": "Por favor, introduzca su email para terminar de inscribirse.",
"Invite": "Invitar",
"Uninvite": "Cancelar la invitación",
"Make admin": "Hacer admin",
"Unadmin": "Borrar de admin",
"Delete User": "Borrar usuario",
"Are you sure you want to delete ": "Está seguro de que desea eliminar",
"Reset Password": "Restablecer contraseña",
"Password reset link sent!": "Enlace de restablecimiento de contraseña enviado!!",
"Name": "Nombre",
"Posts": "Posts",
"Comments": "Comentarios",
"Karma": "Karma",
"Is Invited?": "Esta invitado?",
"Is Admin?": "Es admin?",
"Delete": "Borrar",
"Member since": "Miembro desde",
"Edit profile": "Modificar el perfil",
"Sign In": "Registrarse",
"Sign in!": "Registrarse",
"Sign up!": "Inscribirse",
"Don't have an account?": "¿No tiene cuenta de usuario?",
"Already have an account?": "¿Ya tiene cuenta?",
"Sign Up": "Inscribirse",
"Please fill in all fields": "Tiene que rellenar todos los campos",
"Invite ": "Invitación ",
"left": " restante",
"Invite (none left)": "Invitación (no queda)",
"All": "Todos",
"Invited": "Invitados",
"Uninvited": "No invitado",
"Filter by": "Filtrar por",
"Sort by": "Ordenar por",
//Helpers
"Sorry, you do not have access to this page": "Lo sentimos, usted no tiene acceso a esta página",
"Please Sign In First.": "Tiene que registrarse primero.",
"Sorry, you have to be an admin to view this page.": "Lo sentimos, usted tiene que ser un administrador para ver esta página.",
"Sorry, you don't have permissions to add new items.": "Lo sentimos, usted no tiene permisos para agregar nuevos elementos.",
"Sorry, you cannot edit this post.": "Lo sentimos, no puede editar este post.",
"Sorry, you cannot edit this comment.": "Lo sentimos, no puede editar este comentario.",
//Collections
"You need to login and be an admin to add a new category.": "Usted tiene que entrar y ser un administrador para añadir una nueva categoría",
"You need to login or be invited to post new comments.": "¡Tienes que iniciar sesión o ser invitado a publicar nuevos comentarios.",
"Please wait ": "Espera por favor",
" seconds before commenting again": " segundos antes de comentar de nuevo",
"Your comment is empty.": "Tu comentario está vacío",
"You don't have permission to delete this comment.": "Usted no tiene permiso para eliminar este comentario.",
"You need to login or be invited to post new stories.": "¡Tienes que iniciar sesión o ser invitado para publicar nuevas historias.",
"Please fill in a headline": "Por favor rellene el titulo",
"This link has already been posted": "Este enlace ya ha sido publicado",
"Sorry, you cannot submit more than ": "Lo sentimos, usted no puede presentar más de ",
" posts per day": " posts por dia",
"Someone replied to your comment on": "Alguien respondió a tu comentario en",
" has replied to your comment on": " ha respondido a su comentario sobre",
"Read more": "Leer más",
"A new comment on your post": "Un nuevo comentario en su post",
"You have a new comment by ": "Usted tiene un nuevo comentario de ",
" on your post": " en su post",
" has created a new post": " ha creado un nuevo post",
"Your account has been approved.": "Su cuenta ha sido aprobada.",
"Start posting.": "Empezar a publicar",
//Common
"Pending": "Pendiente",
"Loading...": "Cargando...",
"Submit": "Enviar",
"You must be logged in.": "Debe estar conectado",
"Are you sure?": "¿Está seguro? ",
"Please log in first": "Por favor, inicia sesión",
"Sign In/Sign Up with Twitter": "Inicia sesión/Inscribete con Twitter",
"Load more": "Cargar más"
};

View file

@ -1,191 +0,0 @@
i18n.translations.fr = {
//Navigation
"View": "Vue",
"Menu": "Menu",
"Top": "Top",
"New": "Nouveau",
"Digest": "Résumé",
"Categories": "Catégories",
"Users": "Utilisateurs",
"Settings": "Paramètres",
"Admin": "Admin",
"Post": "Poster",
"Toolbox": "Outils",
"Sign Up/Sign In": "Connexion/Créer un compte",
"My Account": "Mon compte",
"View Profile": "Voir le profil",
"Edit Account": "Editer le compte",
//Main
"New Posts": "Nouveaux Posts",
//Commments
"Your comment has been deleted.": "Votre commentaire a été supprimé.",
"Comment": "Commentaire",
"Delete Comment": "Supprimer le commentaire",
"Add Comment": "Ajouter un commentaire",
"upvote": "upvote",
"downvote": "downvote",
"link": "lien",
"Edit": "Editer",
"Reply": "Répondre",
"No comments.": "Aucun commentaire.",
//Errors
"You are already logged in": "Vous êtes déjà connecté",
"Sorry, this is a private site. Please sign up first.": "Désolé mais ce site est privé, vous devez d'abord vous connecter",
"Thanks for signing up!": "Merci pour votre inscription !",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "L'accès au site se fait uniquement par invitation. Nous vous informerons dès qu'une place se libère.",
"Sorry, you don't have the rights to view this page.": "Désolé, vous n'avez pas le droit de voir cette page.",
"Not Found!": "Oups",
"We're sorry; whatever you were looking for isn't here..": "Désolé, mais ce que vous cherchez ne se trouve pas ici...",
//Notifications
"No notifications": "Aucune notification",
"1 notification": "1 notification",
"notifications": "notifications",
"Mark all as read": "Effacer les notifications",
// Post deleted
"Your post has been deleted.": "Votre post a été supprimé.",
// Post digest
"The top 5 posts of each day.": "5 meilleurs post par jours",
"Previous Day": "Jour précédent",
"Next Day": "Jour suivant",
"Sorry, no posts for today": "Désolé, aucun post aujourd'hui",
"Today": "Aujourd'hui",
"Yesterday": "Hier",
// Post submit & edit
"Created": "Crée",
"Title": "Titre",
"Suggest title": "Suggérer un titre",
"URL": "URL",
"Short URL": "URL Courte",
"Body": "Description",
"Category": "Catégorie",
"Inactive?": "Inactif ?",
"Sticky?": "Mis en avant ?",
"Submission Date": "Date de soumission",
"Submission Time": "Heure de soumission",
"Date": "Date",
"Submission": "Soumission",
"Note: this post is still pending so it has no submission timestamp yet.": "Note : ce post est en cours de validation, il n'a pas encore de timestamp.",
"User": "Utilisateur",
"Status": "Status",
"Approved": "Approuvé",
"Rejected": "Rejeté",
"Delete Post": "Supprimer le post",
"Thanks, your post is awaiting approval.": "Merci, votre post est en cours de validation",
"Sorry, couldn't find a title...": "Désolé, impossible de trouver un titre...",
"Please fill in an URL first!": "Vous devez saisir une URL.",
// Post item
"Share": "Partager",
"Discuss": "Discuter",
"Upvote": "Voter",
"Sticky": "Mis en avant",
"status": "status",
"votes": "votes",
"baseScore": "baseScore",
"score": "score",
"clicks": "clics",
"inactive": "inactif",
"comment": "commentaire",
"comments": "commentaires",
"point": "point",
"points": "points",
//User
"Please complete your profile below before continuing.": "Merci de compléter votre profil avant de continuer.",
"Account": "Compte",
"Username": "Nom d'utilisateur",
"Display Name": "Nom réel",
"Email": "Email",
"Bio": "Bio",
"Password": "Mot de passe",
"Change Password?": "Changer de mot de passe",
"Old Password": "Ancien mot de passe",
"New Password": "Nouveau mot de passe",
"Email Notifications": "Notifications par email",
"New Posts": "Nouveau Post",
"Comments on my posts": "Commentaires sur mes posts",
"Replies to my comments": "Reponses à mes commentaires",
"Forgot password?": "Mot de passe oublié ?",
"Profile updated": "Profil mis à jour",
"Please fill in your email below to finish signing up.": "Merci de saisir votre email pour finir la création de votre compte",
"Invite": "Inviter",
"Uninvite": "Annuler l'invitation",
"Make admin": "Rendre admin",
"Unadmin": "Supprimer les droits d'admin",
"Delete User": "Supprimer l'utilisateur",
"Are you sure you want to delete ": "Etes-vous sur de vouloir supprimer ",
"Reset Password": "Redéfinir le mot de passe",
"Password reset link sent!": "Un lien pour redéfinir votre mot de passe a été envoyé !",
"Name": "Nom",
"Posts": "Posts",
"Comments": "Commentaires",
"Karma": "Karma",
"Is Invited?": "Est-il invité ?",
"Is Admin?": "Est-il Administrateur ?",
"Delete": "Supprimer",
"Member since": "Membre depuis",
"Edit profile": "Modifier le profil",
"Sign In": "Connexion",
"Sign in!": "Connexion",
"Sign up!": "Créer un compte !",
"Don't have an account?": "Pas encore de compte ?",
"Already have an account?": "Déjà un compte ?",
"Sign Up": "Créer un compte",
"Please fill in all fields": "Vous devez remplir tous les champs",
"Invite ": "Invitation ",
"left": " restante",
"Invite (none left)": "Invitation (aucune restante)",
"All": "All",
"Invited": "Invité",
"Uninvited": "Pas invité",
"Filter by": "Filtrer par",
"Sort by": "Trier par",
//Helpers
"Sorry, you do not have access to this page": "Désolé, vous n'avez pas accès à cette page",
"Please Sign In First.": "Vous devez d'abord vous connecter.",
"Sorry, you have to be an admin to view this page.": "Désolé, vous devez être administrateur pour voir cette page.",
"Sorry, you don't have permissions to add new items.": "Désolé, vous n'avez pas la permission d'ajouter de nouveaux posts.",
"Sorry, you cannot edit this post.": "Désolé, vous ne pouvez pas modifier ce post.",
"Sorry, you cannot edit this comment.": "Désolé, vous ne pouvez pas modifier ce commentaire.",
//Collections
"You need to login and be an admin to add a new category.": "Vous devez être administrateur et connecté pour ajouter une catégorie",
"You need to login or be invited to post new comments.": "Vous devez être connecté et invité pour poster des commentaires",
"Please wait ": "Merci de patienter ",
" seconds before commenting again": " secondes avant de poster un nouveau commentaire",
"Your comment is empty.": "Votre commentaire est vide",
"You don't have permission to delete this comment.": "Vous n'avez pas la permission de supprimer ce commentaire",
"You need to login or be invited to post new stories.": "Vous devez être connecté ou invité pour créer un nouveau post",
"Please fill in a headline": "Merci de saisir un titre",
"This link has already been posted": "Ce lien a déjà été posté",
"Sorry, you cannot submit more than ": "Désolé, vous ne pouvez pas créer plus de ",
" posts per day": " posts par jour",
"Someone replied to your comment on": "Quelqu'un à répondu à votre commentaire sur",
" has replied to your comment on": " a répondu à votre commentaire sur",
"Read more": "Lire la suite",
"A new comment on your post": "Un nouveau commentaire sur votre post",
"You have a new comment by ": "Vous avez un nouveau commentaire de ",
" on your post": " sur votre post",
" has created a new post": " a créer un nouveau post",
"Your account has been approved.": "Votre compte a été validé.",
"Welcome to ": "Bienvenu sur ",
"Start posting.": "Commencer à poster.",
//Common
"Pending": "En attente",
"Loading...": "Chargement...",
"Submit": "Envoyer",
"You must be logged in.": "Vous devez être connecté",
"Are you sure?": "Etes-vous sur ?",
"Please log in first": "Vous devez être connecté",
"Sign In/Sign Up with Twitter": "Connexion/Créer un compte avec Twitter",
"Load more": "Charger plus"
};

View file

@ -1,192 +0,0 @@
i18n.translations.it = {
//Navigation
"Menu": "Menu",
"Top": "Migliori",
"New": "Nuovi",
"Digest": "Selezione",
"Categories": "Categorie",
"Users": "Utenti",
"Settings": "Impostazioni",
"Admin": "Amministrazione",
"Post": "Posta",
"Toolbox": "Toolbox",
"Sign Up/Sign In": "Registrati/Accedi",
"My Account": "Il Mio Account",
"View Profile": "Vedi Profilo",
"Edit Account": "Modifica Account",
//Main
"New Posts": "Nuovi Post",
//Commments
"Your comment has been deleted.": "Il tuo commento è stato rimosso.",
"Comment": "Commenta",
"Delete Comment": "Elimina Commento",
"Add Comment": "Aggiungi Commento",
"upvote": "promuovi",
"downvote": "sconsiglia",
"link": "link",
"Edit": "Modifica",
"Reply": "Rispondi",
"No comments.": "Nessun commento.",
//Errors
"You are already logged in": "Hai già eseguito l'accesso",
"Sorry, this is a private site. Please sign up first.": "Ci spiace, questo è un sito privato. Per favore registrati.",
"Thanks for signing up!": "Grazie per esserti registrato!",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "Questo sito al momento è solo per chi è stato invitato, ma ti faremo sapere non appena ci sarà la possibilità di accedere.",
"Sorry, you don't have the rights to view this page.": "Ci spiace, non hai i permessi per visualizzare questa pagina.",
"Not Found!": "Non Trovato!",
"We're sorry; whatever you were looking for isn't here..": "Ci spiace; qualsiasi cosa stessi cercando non è qua..",
//Notifications
"No notifications": "Nessuna notifica",
"1 notification": "1 notifica",
"notifications": "notifiche",
"Mark all as read": "Segna tutte come lette",
// Post deleted
"Your post has been deleted.": "Il tuo post è stato rimosso.",
// Post digest
"The top 5 posts of each day.": "I 5 migliori post di ogni giorno.",
"Previous Day": "Giorno Precedente",
"Next Day": "Giorno Successivo",
"Sorry, no posts for today": "Ci spiace, non ci sono post per oggi",
"Sorry, no posts for": "Ci spiace, non ci sono post per",
"Today": "Oggi",
"Yesterday": "Ieri",
// Post submit & edit
"Created": "Creato",
"Title": "Titolo",
"Suggest title": "Titolo suggerito",
"URL": "URL",
"Short URL": "URL breve",
"Body": "Corpo",
"Category": "Categoria",
"Inactive?": "Inattivo?",
"Sticky?": "Persistente?",
"Submission Date": "Data di Invio",
"Submission Time": "Ora di Invio",
"Date": "Data",
"Submission": "Invio",
"Note: this post is still pending so it has no submission timestamp yet.": "Nota: questo post è ancora in attesa quindi non ha ancora una data di invio.",
"User": "Utente",
"Status": "Stato",
"Approved": "Approvato",
"Rejected": "Rifiutato",
"Delete Post": "Elimina Post",
"Thanks, your post is awaiting approval.": "Grazie, il tuo post è in attesa di approvazione.",
"Sorry, couldn't find a title...": "Ci spiace, non riusciamo a trovare un titolo...",
"Please fill in an URL first!": "Per favore riempi prima l'URL!",
// Post item
"Share": "Condividi",
"Discuss": "Discuti",
"Upvote": "Promuovi",
"Sticky": "Persistente",
"status": "stato",
"votes": "voti",
"baseScore": "punteggioBase",
"score": "punteggio",
"clicks": "clicks",
"inactive": "inattivo",
"comment": "commento",
"comments": "commenti",
"point": "punto",
"points": "punti",
//User
"Please complete your profile below before continuing.": "Per favore completa il tuo profilo qua sotto prima di proseguire.",
"Account": "Account",
"Username": "Nome Utente",
"Display Name": "Nome Visualizzato",
"Email": "Email",
"Bio": "Biografia",
"Password": "Password",
"Change Password?": "Cambio Password?",
"Old Password": "Vecchia Password",
"New Password": "Nuova Password",
"Email Notifications": "Notifiche via Email",
"New Posts": "Nuovi Posts",
"Comments on my posts": "Commenti ai miei post",
"Replies to my comments": "Risposte ai miei commenti",
"Forgot password?": "Password dimenticata?",
"Profile updated": "Profilo aggiornato",
"Please fill in your email below to finish signing up.": "Per favore inserisci qua sotto la tua email per completare la registrazione.",
"Invite": "Invita",
"Uninvite": "Annulla l'invito",
"Make admin": "Rendi amministratore",
"Unadmin": "Annulla amministratore",
"Delete User": "Elimina Utente",
"Are you sure you want to delete ": "Sei sicuro di voler eliminare ",
"Reset Password": "Reimposta Password",
"Password reset link sent!": "Link per reimpostare la password inviato!",
"Name": "Nome",
"Posts": "Post",
"Comments": "Commenti",
"Karma": "Karma",
"Is Invited?": "È Invitato?",
"Is Admin?": "È Amministratore?",
"Delete": "Elimina",
"Member since": "Membro dal",
"Edit profile": "Modifica profilo",
"Sign In": "Accedi",
"Sign in!": "Accedi!",
"Sign up!": "Registrati!",
"Don't have an account?": "Non hai un account?",
"Already have an account?": "Hai già un account?",
"Sign Up": "Registrati",
"Please fill in all fields": "Per favore compila tutti i campi",
"Invite ": "Invita ",
"left": " sinistra",
"Invite (none left)": "Invita (nessuno rimasto)",
"All": "Tutti",
"Invited": "Invitati",
"Uninvited": "Non invitati",
"Filter by": "Filtra per",
"Sort by": "Ordina per",
//helpers
"Sorry, you do not have access to this page": "Ci spiace, non hai accesso a questa pagina",
"Please Sign In First.": "Per favore prima accedi.",
"Sorry, you have to be an admin to view this page.": "Ci spiace, devi essere un amministratore per vedere questa pagina.",
"Sorry, you don't have permissions to add new items.": "Ci spiace, non hai i permessi per aggiungere nuovi elementi.",
"Sorry, you cannot edit this post.": "Ci spiace, non puoi modificare questo post.",
"Sorry, you cannot edit this comment.": "Ci spiace, non puoi modificare questo commento.",
//Collections
"You need to login and be an admin to add a new category.": "Devi accedere ed essere un amministratore per aggiungere una nuova categoria.",
"You need to login or be invited to post new comments.": "Devi accedere od essere invitato per postare nuovi commenti.",
"Please wait ": "Per favore attendi ",
" seconds before commenting again": " secondi prima di fare un altro commento",
"Your comment is empty.": "Il tuo commento è vuoto.",
"You don't have permission to delete this comment.": "Non hai i permessi per eliminare questo commento.",
"You need to login or be invited to post new stories.": "Devi accedere o essere invitato per postare nuove storie.",
"Please fill in a headline": "Per favore inserisci un titolo",
"This link has already been posted": "Questo link è già stato postato",
"Sorry, you cannot submit more than ": "Ci spiace, non puoi inviare più di ",
" posts per day": " post al giorno",
"Someone replied to your comment on": "Qualcuno ha risposto al tuo commento su",
" has replied to your comment on": " ha risposto al tuo commento su",
"Read more": "Leggi di più",
"A new comment on your post": "Un nuovo commento sul tuo post",
"You have a new comment by ": "Hai un nuovo commento di ",
" on your post": " sul tuo post",
" has created a new post": " ha creato un nuovo post",
"Your account has been approved.": "Il tuo account è stato approvato.",
"Welcome to ": "Benvenuto a ",
"Start posting.": "Inizia a postare.",
//Common
"Pending": "In attesa",
"Loading...": "Caricamento...",
"Submit": "Invia",
"You must be logged in.": "Devi effettuare l'accesso.",
"Are you sure?": "Sei sicuro?",
"Please log in first": "Per favore esegui prima l'accesso",
"Sign In/Sign Up with Twitter": "Accedi/Registrati con Twitter",
"Load more": "Carica altro"
};

View file

@ -1,194 +0,0 @@
i18n.translations.zh = {
//Navigation
"View": "视图",
"Menu": "菜单",
"Top": "置顶",
"New": "最新",
"Digest": "摘要",
"Categories": "分类",
"Users": "用户",
"Settings": "设置",
"Admin": "管理",
"Post": "提交",
"Toolbox": "工具箱",
"Sign Up/Sign In": "注册/登录",
"My Account": "帐号",
"View Profile": "个人资料",
"Edit Account": "编辑帐号",
//Main
"New Posts": "最新提交",
//Commments
"Your comment has been deleted.": "你的评论已经被删除",
"Comment": "评论",
"Delete Comment": "删除评论",
"Add Comment": "评论",
"upvote": "顶",
"downvote": "踩",
"link": "链接",
"Edit": "编辑",
"Reply": "回复",
"No comments.": "暂时没有评论",
//Errors
"You are already logged in": "你已经登录",
"Sorry, this is a private site. Please sign up first.": "对不起, 请先注册再进行后续操作",
"Thanks for signing up!": "感谢您的注册!",
"The site is currently invite-only, but we will let you know as soon as a spot opens up.": "该站点暂时只允许邀请访问, 如果开放了我们会让你知道",
"Sorry, you don't have the rights to view this page.": "抱歉你没有权利查看此页面",
"Not Found!": "页面不存在",
"We're sorry; whatever you were looking for isn't here..": "抱歉没有你要查看的内容!",
//Notifications
"No notifications": "无消息",
"1 notification": "1 个消息",
"notifications": "消息",
"Mark all as read": "标记所有",
// Post deleted
"Your post has been deleted.": "你的帖子已经被删除",
// Post digest
"The top 5 posts of each day.": "每天前5名的帖子",
"Previous Day": "前一天",
"Next Day": "后一天",
"Sorry, no posts for today": "抱歉今天没有新的帖子",
"Today": "今天",
"Yesterday": "昨天",
// Post submit & edit
"Created": "创建",
"Title": "标题",
"Suggest title": "显示标题",
"URL": "链接地址",
"Short URL": "短网址",
"Body": "内容",
"Category": "分类",
"Inactive?": "Inactive?",
"Sticky?": "置顶?",
"Submission Date": "提交日期",
"Submission Time": "提交时间",
"Date": "日期",
"Submission": "提交",
"Note: this post is still pending so it has no submission timestamp yet.": "这篇文章没有进行审核.",
"User": "用户",
"Status": "专题",
"Approved": "审核",
"Rejected": "拒接",
"Delete Post": "删除帖子",
"Thanks, your post is awaiting approval.": "感谢, 你的帖子正在等待批准.",
"Sorry, couldn't find a title...": "抱歉找不相关话题",
"Please fill in an URL first!": "请在第一栏填写链接",
// Post item
"Share": "分享",
"Discuss": "讨论",
"Upvote": "顶",
"Sticky": "置顶",
"status": "状态",
"votes": "得票",
"baseScore": "基础得分",
"score": "得分",
"clicks": "点击",
"inactive": "不活跃",
"comment": "评论",
"comments": "评论数",
"point": "点击",
"points": "点击数",
//User
"Please complete your profile below before continuing.": "在继续之前请填写相关资料.",
"Account": "帐号",
"Username": "用户名",
"Display Name": "昵称",
"Email": "Email",
"Bio": "小传",
"Password": "密码",
"Change Password?": "修改密码?",
"Old Password": "旧密码",
"New Password": "新密码",
"Email Notifications": "邮箱提醒",
"New Posts": "最新主题",
"Comments on my posts": "评论我的主题时",
"Replies to my comments": "回复我的回复时",
"Forgot password?": "忘记密码?",
"Profile updated": "更新资料",
"Please fill in your email below to finish signing up.": "请填写你的电子邮件完成注册.",
"Invite": "邀请",
"Uninvite": "未激活",
"Make admin": "设置为管理员",
"Unadmin": "取消管理资格",
"Delete User": "删除用户",
"Are you sure you want to delete ": "你确定要删除用户吗 ",
"Reset Password": "重置密码",
"Password reset link sent!": "密码重置链接已发送",
"Name": "名字",
"Posts": "帖子数",
"Comments": "评论数",
"Karma": "Karma",
"Is Invited?": "邀请用户?",
"Is Admin?": "管理员?",
"Delete": "删除",
"Member since": "加入至今",
"Edit profile": "修改个人资料",
"Sign In": "登录",
"Sign in!": "登录!",
"Sign up!": "注册!",
"Don't have an account?": "还没有帐号?",
"Already have an account?": "已有帐号?",
"Sign Up": "注册",
"Please fill in all fields": "请填写完整",
"Invite ": "邀请 ",
"left": " restante",
"Invite (none left)": "Invite (none left)",
"All": "全部",
"Invited": "邀请",
"Uninvited": "未被邀请",
"Filter by": "过滤",
"Sort by": "排序",
//helpers
"Sorry, you do not have access to this page": "抱歉你没有权限访问此页面",
"Please Sign In First.": "请先登录.",
"Sorry, you have to be an admin to view this page.": "抱歉你必须是管理员才能查看此页面",
"Sorry, you don't have permissions to add new items.": "抱歉你没有权限添加新项.",
"Sorry, you cannot edit this post.": "对不起你不能编辑这个帖子",
"Sorry, you cannot edit this comment.": "对不起你不能编辑这个评论",
//Collections
"You need to login and be an admin to add a new category.": "你必须登录并且是管理员才能添加新类别.",
"You need to login or be invited to post new comments.": "你需要登录或被邀请才能发表新的评论.",
"Please wait ": "请稍等 ",
" seconds before commenting again": " 秒后在评论",
"Your comment is empty.": "你的评论是空的.",
"You don't have permission to delete this comment.": "你没有删除此评论的权限.",
"You need to login or be invited to post new stories.": "你需要登录或被邀请才能发布新的内容.",
"Please fill in a headline": "请填写一个标题",
"This link has already been posted": "这个链接已发布",
"Sorry, you cannot submit more than ": "对不起, 内容不能超过",
" posts per day": " 评价每日发帖",
"Someone replied to your comment on": "有人回复了你的评论",
" has replied to your comment on": " 已经有人回复了你的评论",
"Read more": "查看更多",
"A new comment on your post": "你发表的主题有新的评论",
"You have a new comment by ": "你有一个新的评论在 ",
" on your post": " 在你的帖子",
" has created a new post": " 发一个新帖",
"Your account has been approved.": "你的帐号已被批准",
"Welcome to ": "欢迎来到 ",
"Start posting.": "开始发布.",
//Common
"Pending": "悬而未决...",
"Loading...": "加载中...",
"Submit": "提交",
"You must be logged in.": "你必须登录.",
"Are you sure?": "是否确定?",
"Please log in first": "请先登录",
"Sign In/Sign Up with Twitter": "使用微博等/注册",
"Load more": "加载更多",
"Administration": "管理",
"Best": "精华"
};

View file

@ -1,823 +0,0 @@
/*
//--------------------------------------------------------------------------------------------------//
//---------------------------------------- Table Of Contents ---------------------------------------//
//--------------------------------------------------------------------------------------------------//
---------------------------------------------------------------
# Config #
---------------------------------------------------------------
//
---------------------------------------------------------------
# Filters #
---------------------------------------------------------------
isLoggedIn
isLoggedOut
isAdmin
canView
canPost
canEditPost
canEditComment
hasCompletedProfile
---------------------------------------------------------------
# Controllers #
---------------------------------------------------------------
PostsListController
PostPageController
---------------------------------------------------------------
# Routes #
---------------------------------------------------------------
1) Paginated Lists
----------------------
Top
New
Best
Pending
Categories
2) Digest
--------------------
Digest
3) Posts
--------------------
Post Page
Post Page (scroll to comment)
Post Edit
Post Submit
4) Comments
--------------------
Comment Page
Comment Edit
Comment Submit
5) Users
--------------------
User Profie
User Edit
Account
All Users
Unsubscribe (from notifications)
6) Misc Routes
--------------------
Settings
Categories
Toolbox
7) Server-side
--------------------
API
RSS
*/
// uncomment to disable FastRender
var FastRender = {RouteController: RouteController, onAllRoutes: function() {}};
//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Config ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//
preloadSubscriptions.push('settings');
preloadSubscriptions.push('currentUser');
Router.configure({
layoutTemplate: getTemplate('layout'),
loadingTemplate: getTemplate('loading'),
notFoundTemplate: getTemplate('notFound'),
waitOn: function () {
return _.map(preloadSubscriptions, function(sub){
// can either pass strings or objects with subName and subArguments properties
if (typeof sub === 'object'){
Meteor.subscribe(sub.subName, sub.subArguments);
}else{
Meteor.subscribe(sub);
}
});
}
});
//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Filters --------------------------------------------//
//--------------------------------------------------------------------------------------------------//
Router._filters = {
isReady: function(pause) {
if (!this.ready()) {
// console.log('not ready')
this.render(getTemplate('loading'));
pause();
}else{
// console.log('ready')
}
},
resetScroll: function () {
var scrollTo = window.currentScroll || 0;
var $body = $('body');
$body.scrollTop(scrollTo);
$body.css("min-height", 0);
},
/*
isLoggedIn: function(pause) {
if (!(Meteor.loggingIn() || Meteor.user())) {
throwError(i18n.t('Please Sign In First.'));
var current = getCurrentRoute();
if (current){
Session.set('fromWhere', current);
}
this.render('entrySignIn');
pause();
}
},
*/
isLoggedIn: AccountsTemplates.ensureSignedIn,
isLoggedOut: function(pause) {
if(Meteor.user()){
this.render('already_logged_in');
pause();
}
},
isAdmin: function(pause) {
if(!this.ready()) return;
if(!isAdmin()){
this.render(getTemplate('no_rights'));
pause();
}
},
canView: function(pause) {
if(!this.ready() || Meteor.loggingIn()){
this.render(getTemplate('loading'));
pause();
}else if (!canView()) {
this.render(getTemplate('no_rights'));
pause();
}
},
canPost: function (pause) {
if(!this.ready() || Meteor.loggingIn()){
this.render(getTemplate('loading'));
pause();
}else if(!canPost()){
throwError(i18n.t("Sorry, you don't have permissions to add new items."));
this.render(getTemplate('no_rights'));
pause();
}
},
canEditPost: function(pause) {
if(!this.ready()) return;
// Already subscribed to this post by route({waitOn: ...})
var post = Posts.findOne(this.params._id);
if(!currentUserCanEdit(post)){
throwError(i18n.t("Sorry, you cannot edit this post."));
this.render(getTemplate('no_rights'));
pause();
}
},
canEditComment: function(pause) {
if(!this.ready()) return;
// Already subscribed to this comment by CommentPageController
var comment = Comments.findOne(this.params._id);
if(!currentUserCanEdit(comment)){
throwError(i18n.t("Sorry, you cannot edit this comment."));
this.render(getTemplate('no_rights'));
pause();
}
},
hasCompletedProfile: function(pause) {
if(!this.ready()) return;
var user = Meteor.user();
if (user && ! userProfileComplete(user)){
this.render(getTemplate('user_email'));
pause();
}
},
setTitle: function() {
// set title
var title = getSetting("title");
var tagline = getSetting("tagline");
document.title = (tagline ? title+': '+tagline : title) || "";
}
};
var filters = Router._filters;
var coreSubscriptions = new SubsManager({
// cache recent 50 subscriptions
cacheLimit: 50,
// expire any subscription after 30 minutes
expireIn: 30
});
if(Meteor.isClient){
// Load Hooks
Router.onRun( function () {
Session.set('categorySlug', null);
// if we're not on the search page itself, clear search query and field
if(getCurrentRoute().indexOf('search') == -1){
Session.set('searchQuery', '');
$('.search-field').val('').blur();
}
});
// Before Hooks
// Router.onBeforeAction(filters.isReady);
Router.onBeforeAction(clearSeenErrors);
Router.onBeforeAction(filters.canView, {except: ['atSignIn', 'atSignUp', 'atForgotPwd', 'atResetPwd', 'signOut']});
Router.onBeforeAction(filters.hasCompletedProfile);
Router.onBeforeAction(filters.isLoggedIn, {only: ['post_submit']});
Router.onBeforeAction(filters.isLoggedOut, {only: []});
Router.onBeforeAction(filters.canPost, {only: ['posts_pending', 'post_submit']});
Router.onBeforeAction(filters.canEditPost, {only: ['post_edit']});
Router.onBeforeAction(filters.canEditComment, {only: ['comment_edit']});
Router.onBeforeAction(filters.isAdmin, {only: ['posts_pending', 'all-users', 'settings', 'toolbox', 'logs']});
// After Hooks
// Router.onAfterAction(filters.resetScroll, {except:['posts_top', 'posts_new', 'posts_best', 'posts_pending', 'posts_category', 'all-users']});
Router.onAfterAction(analyticsInit); // will only run once thanks to _.once()
Router.onAfterAction(analyticsRequest); // log this request with mixpanel, etc
Router.onAfterAction(filters.setTitle);
// Unload Hooks
//
}
//--------------------------------------------------------------------------------------------------//
//------------------------------------------- Controllers ------------------------------------------//
//--------------------------------------------------------------------------------------------------//
// Controller for all posts lists
PostsListController = FastRender.RouteController.extend({
template: getTemplate('posts_list'),
onBeforeAction: function () {
// take the first segment of the path to get the view, unless it's '/' in which case the view default to 'top'
// note: most of the time this.params.slug will be empty
this._terms = {
view: this.view,
limit: this.params.limit || getSetting('postsPerPage', 10),
category: this.params.slug
};
if(Meteor.isClient) {
this._terms.query = Session.get("searchQuery");
}
this.postsListSub = coreSubscriptions.subscribe('postsList', this._terms);
return [
this.postsListSub,
coreSubscriptions.subscribe('postsListUsers', this._terms)
];
},
data: function () {
this._terms = {
view: this.view,
limit: this.params.limit || getSetting('postsPerPage', 10),
category: this.params.slug
};
if(Meteor.isClient) {
this._terms.query = Session.get("searchQuery");
}
var parameters = getPostsParameters(this._terms),
postsCount = Posts.find(parameters.find, parameters.options).count();
parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') };
var posts = Posts.find(parameters.find, parameters.options);
// Incoming posts
parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') };
var postsIncoming = Posts.find(parameters.find, parameters.options);
Session.set('postsLimit', this._terms.limit);
return {
incoming: postsIncoming,
postsList: posts,
postsCount: postsCount,
ready: this.postsListSub.ready
};
},
onAfterAction: function() {
Session.set('view', this.view);
}
});
PostsTopController = PostsListController.extend({
view: 'top'
});
PostsNewController = PostsListController.extend({
view: 'new'
});
PostsBestController = PostsListController.extend({
view: 'best'
});
PostsPendingController = PostsListController.extend({
view: 'pending'
});
// Controller for post digest
PostsDigestController = FastRender.RouteController.extend({
template: getTemplate('posts_digest'),
waitOn: function() {
// if day is set, use that. If not default to today
var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : new Date(),
terms = {
view: 'digest',
after: moment(currentDate).startOf('day').toDate(),
before: moment(currentDate).endOf('day').toDate()
};
return [
coreSubscriptions.subscribe('postsList', terms),
coreSubscriptions.subscribe('postsListUsers', terms)
];
},
data: function() {
var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
terms = {
view: 'digest',
after: moment(currentDate).startOf('day').toDate(),
before: moment(currentDate).endOf('day').toDate()
},
parameters = getPostsParameters(terms);
Session.set('currentDate', currentDate);
parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') };
var posts = Posts.find(parameters.find, parameters.options);
// Incoming posts
parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') };
var postsIncoming = Posts.find(parameters.find, parameters.options);
return {
incoming: postsIncoming,
posts: posts
};
}
});
// Controller for post pages
PostPageController = FastRender.RouteController.extend({
waitOn: function() {
this.postSubscription = coreSubscriptions.subscribe('singlePost', this.params._id);
this.postUsersSubscription = coreSubscriptions.subscribe('postUsers', this.params._id);
this.commentSubscription = coreSubscriptions.subscribe('postComments', this.params._id);
},
post: function() {
return Posts.findOne(this.params._id);
},
onBeforeAction: function(pause) {
if (! this.post()) {
if (this.postSubscription.ready()) {
this.render(getTemplate('not_found'));
return pause();
}
this.render(getTemplate('loading'));
pause();
}
},
data: function() {
return this.post();
}
});
// Controller for comment pages
CommentPageController = FastRender.RouteController.extend({
waitOn: function() {
return [
coreSubscriptions.subscribe('singleComment', this.params._id),
coreSubscriptions.subscribe('commentUser', this.params._id),
coreSubscriptions.subscribe('commentPost', this.params._id)
];
},
data: function() {
return {
comment: Comments.findOne(this.params._id)
};
},
onAfterAction: function () {
window.queueComments = false;
}
});
// Controller for user pages
UserPageController = FastRender.RouteController.extend({
waitOn: function() {
return [
coreSubscriptions.subscribe('userProfile', this.params._idOrSlug)
]
},
data: function() {
var findById = Meteor.users.findOne(this.params._idOrSlug);
var findBySlug = Meteor.users.findOne({slug: this.params._idOrSlug});
if(typeof findById !== "undefined"){
// redirect to slug-based URL
Router.go(getProfileUrl(findById), {replaceState: true});
}else{
return {
user: (typeof findById == "undefined") ? findBySlug : findById
};
}
}
});
// Controller for user account editing
AccountController = FastRender.RouteController.extend({
waitOn: function() {
return coreSubscriptions.subscribe('invites');
},
data: function() {
return {
user : Meteor.user(),
invites: Invites.find({invitingUserId:Meteor.userId()})
};
}
});
var getDefaultViewController = function () {
var defaultView = getSetting('defaultView', 'top');
defaultView = defaultView.charAt(0).toUpperCase() + defaultView.slice(1);
return eval("Posts"+defaultView+"Controller");
};
//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Routes ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//
Meteor.startup(function () {
Router.map(function() {
// -------------------------------------------- Post Lists -------------------------------------------- //
this.route('posts_default', {
path: '/',
controller: getDefaultViewController()
});
this.route('posts_top', {
path: '/top/:limit?',
controller: PostsTopController
});
// New
this.route('posts_new', {
path: '/new/:limit?',
controller: PostsNewController
});
// Best
this.route('posts_best', {
path: '/best/:limit?',
controller: PostsBestController
});
// Pending
this.route('posts_pending', {
path: '/pending/:limit?',
controller: PostsPendingController
});
// TODO: enable /category/new, /category/best, etc. views
// Digest
this.route('posts_digest', {
path: '/digest/:year/:month/:day',
controller: PostsDigestController
});
this.route('posts_digest', {
path: '/digest',
controller: PostsDigestController
});
// -------------------------------------------- Post -------------------------------------------- //
// Post Page
this.route('post_page', {
template: getTemplate('post_page'),
path: '/posts/:_id',
controller: PostPageController
});
this.route('post_page', {
template: getTemplate('post_page'),
path: '/posts/:_id/comment/:commentId',
controller: PostPageController,
onAfterAction: function () {
// TODO: scroll to comment position
}
});
// Post Edit
this.route('post_edit', {
template: getTemplate('post_edit'),
path: '/posts/:_id/edit',
waitOn: function () {
return [
coreSubscriptions.subscribe('singlePost', this.params._id),
coreSubscriptions.subscribe('allUsersAdmin')
];
},
data: function() {
return {
postId: this.params._id,
post: Posts.findOne(this.params._id)
};
},
fastRender: true
});
// Post Submit
this.route('post_submit', {
template: getTemplate('post_submit'),
waitOn: function () {
return [
coreSubscriptions.subscribe('allUsersAdmin')
]
},
path: '/submit'
});
// -------------------------------------------- Comment -------------------------------------------- //
// Comment Reply
this.route('comment_reply', {
template: getTemplate('comment_reply'),
path: '/comments/:_id',
controller: CommentPageController,
onAfterAction: function() {
window.queueComments = false;
}
});
// Comment Edit
this.route('comment_edit', {
template: getTemplate('comment_edit'),
path: '/comments/:_id/edit',
controller: CommentPageController,
onAfterAction: function() {
window.queueComments = false;
}
});
// -------------------------------------------- Users -------------------------------------------- //
// User Logout
this.route('signOut', {
path: '/sign-out',
onBeforeAction: function(pause) {
Meteor.logout(function() {
return Router.go('/');
});
return pause();
}
});
// User Profile
this.route('user_profile', {
template: getTemplate('user_profile'),
path: '/users/:_idOrSlug',
controller: UserPageController
});
// User Edit
this.route('user_edit', {
template: getTemplate('user_edit'),
path: '/users/:_idOrSlug/edit',
controller: UserPageController
});
// Account
this.route('account', {
template: getTemplate('user_edit'),
path: '/account',
controller: AccountController
});
// All Users
this.route('all-users', {
template: getTemplate('users'),
path: '/all-users/:limit?',
waitOn: function() {
var limit = parseInt(this.params.limit) || 20;
return coreSubscriptions.subscribe('allUsers', this.params.filterBy, this.params.sortBy, limit);
},
data: function() {
var limit = parseInt(this.params.limit) || 20,
parameters = getUsersParameters(this.params.filterBy, this.params.sortBy, limit),
filterBy = (typeof this.params.filterBy === 'string') ? this.params.filterBy : 'all',
sortBy = (typeof this.params.sortBy === 'string') ? this.params.sortBy : 'createdAt';
Session.set('usersLimit', limit);
return {
users: Meteor.users.find(parameters.find, parameters.options),
filterBy: filterBy,
sortBy: sortBy
};
},
fastRender: true
});
// Unsubscribe (from notifications)
this.route('unsubscribe', {
template: getTemplate('unsubscribe'),
path: '/unsubscribe/:hash',
data: function() {
return {
hash: this.params.hash
};
}
});
// -------------------------------------------- Other -------------------------------------------- //
// Settings
this.route('settings', {
template: getTemplate('settings'),
data: function () {
// we only have one set of settings for now
return {
hasSettings: !!Settings.find().count(),
settings: Settings.findOne()
}
}
});
// Loading (for testing purposes)
this.route('loading', {
template: getTemplate('loading')
});
// Toolbox
this.route('toolbox',{
template: getTemplate('toolbox')
});
// -------------------------------------------- Server-Side -------------------------------------------- //
// Link Out
this.route('out', {
where: 'server',
path: '/out',
action: function(){
var query = this.request.query;
if(query.url){
var decodedUrl = decodeURIComponent(query.url);
var post = Posts.findOne({url: decodedUrl});
if(post){
Posts.update(post._id, {$inc: {clicks: 1}});
}
this.response.writeHead(302, {'Location': query.url});
this.response.end();
}
}
});
// Notification email
this.route('notification', {
where: 'server',
path: '/email/notification/:id?',
action: function() {
var notification = Notifications.findOne(this.params.id);
var notificationContents = buildEmailNotification(notification);
this.response.write(notificationContents.html);
this.response.end();
}
});
// New user email
this.route('newUser', {
where: 'server',
path: '/email/new-user/:id?',
action: function() {
var user = Meteor.users.findOne(this.params.id);
var emailProperties = {
profileUrl: getProfileUrl(user),
username: getUserName(user)
};
console.log(Handlebars);
console.log(Handlebars.templates);
html = getEmailTemplate('emailNewUser')(emailProperties);
this.response.write(buildEmailTemplate(html));
this.response.end();
}
});
// New post email
this.route('newPost', {
where: 'server',
path: '/email/new-post/:id?',
action: function() {
var post = Posts.findOne(this.params.id);
html = Handlebars.templates[getTemplate('emailNewPost')](getPostProperties(post));
this.response.write(buildEmailTemplate(html));
this.response.end();
}
});
// Account approved email
this.route('accountApproved', {
where: 'server',
path: '/email/account-approved/:id?',
action: function() {
var user = Meteor.users.findOne(this.params.id);
var emailProperties = {
profileUrl: getProfileUrl(user),
username: getUserName(user),
siteTitle: getSetting('title'),
siteUrl: getSiteUrl()
};
html = Handlebars.templates[getTemplate('emailAccountApproved')](emailProperties);
this.response.write(buildEmailTemplate(html));
this.response.end();
}
});
});
});
// adding common subscriptions that's need to be loaded on all the routes
// notification does not included here since it is not much critical and
// it might have considerable amount of docs
if(Meteor.isServer) {
FastRender.onAllRoutes(function() {
var router = this;
_.each(preloadSubscriptions, function(sub){
router.subscribe(sub);
});
});
}

45
lib/router/comments.js Normal file
View file

@ -0,0 +1,45 @@
// Controller for comment pages
CommentPageController = FastRender.RouteController.extend({
waitOn: function() {
return [
coreSubscriptions.subscribe('singleComment', this.params._id),
coreSubscriptions.subscribe('commentUser', this.params._id),
coreSubscriptions.subscribe('commentPost', this.params._id)
];
},
data: function() {
return {
comment: Comments.findOne(this.params._id)
};
},
onAfterAction: function () {
window.queueComments = false;
}
});
Meteor.startup( function () {
// Comment Reply
Router.route('/comments/:_id', {
name: 'comment_reply',
template: getTemplate('comment_reply'),
controller: CommentPageController,
onAfterAction: function() {
window.queueComments = false;
}
});
// Comment Edit
Router.route('/comments/:_id/edit', {
name: 'comment_edit',
template: getTemplate('comment_edit'),
controller: CommentPageController,
onAfterAction: function() {
window.queueComments = false;
}
});
});

35
lib/router/config.js Normal file
View file

@ -0,0 +1,35 @@
// uncomment to disable FastRender
var FastRender = {RouteController: RouteController, onAllRoutes: function() {}};
Router.setTemplateNameConverter(function (str) { return str; });
preloadSubscriptions.push('settings');
preloadSubscriptions.push('currentUser');
Router.configure({
layoutTemplate: getTemplate('layout'),
loadingTemplate: getTemplate('loading'),
notFoundTemplate: getTemplate('notFound'),
waitOn: function () {
return _.map(preloadSubscriptions, function(sub){
// can either pass strings or objects with subName and subArguments properties
if (typeof sub === 'object'){
Meteor.subscribe(sub.subName, sub.subArguments);
}else{
Meteor.subscribe(sub);
}
});
}
});
// adding common subscriptions that's need to be loaded on all the routes
// notification does not included here since it is not much critical and
// it might have considerable amount of docs
if(Meteor.isServer) {
FastRender.onAllRoutes(function() {
var router = this;
_.each(preloadSubscriptions, function(sub){
router.subscribe(sub);
});
});
}

179
lib/router/filters.js Normal file
View file

@ -0,0 +1,179 @@
//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Filters --------------------------------------------//
//--------------------------------------------------------------------------------------------------//
Router._filters = {
isReady: function() {
if (!this.ready()) {
// console.log('not ready')
this.render(getTemplate('loading'));
}else{
this.next();
// console.log('ready')
}
},
clearSeenErrors: function () {
clearSeenErrors();
this.next();
},
resetScroll: function () {
var scrollTo = window.currentScroll || 0;
var $body = $('body');
$body.scrollTop(scrollTo);
$body.css("min-height", 0);
},
/*
isLoggedIn: function() {
if (!(Meteor.loggingIn() || Meteor.user())) {
throwError(i18n.t('please_sign_in_first'));
var current = getCurrentRoute();
if (current){
Session.set('fromWhere', current);
}
this.render('entrySignIn');
} else {
this.next();
}
},
*/
isLoggedIn: AccountsTemplates.ensureSignedIn,
isLoggedOut: function() {
if(Meteor.user()){
this.render('already_logged_in');
} else {
this.next();
}
},
isAdmin: function() {
if(!this.ready()) return;
if(!isAdmin()){
this.render(getTemplate('no_rights'));
} else {
this.next();
}
},
canView: function() {
if(!this.ready() || Meteor.loggingIn()){
this.render(getTemplate('loading'));
} else if (!canView()) {
this.render(getTemplate('no_rights'));
} else {
this.next();
}
},
canPost: function () {
if(!this.ready() || Meteor.loggingIn()){
this.render(getTemplate('loading'));
} else if(!canPost()) {
throwError(i18n.t("sorry_you_dont_have_permissions_to_add_new_items"));
this.render(getTemplate('no_rights'));
} else {
this.next();
}
},
canEditPost: function() {
if(!this.ready()) return;
// Already subscribed to this post by route({waitOn: ...})
var post = Posts.findOne(this.params._id);
if(!currentUserCanEdit(post)){
throwError(i18n.t("sorry_you_cannot_edit_this_post"));
this.render(getTemplate('no_rights'));
} else {
this.next();
}
},
canEditComment: function() {
if(!this.ready()) return;
// Already subscribed to this comment by CommentPageController
var comment = Comments.findOne(this.params._id);
if(!currentUserCanEdit(comment)){
throwError(i18n.t("sorry_you_cannot_edit_this_comment"));
this.render(getTemplate('no_rights'));
} else {
this.next();
}
},
hasCompletedProfile: function() {
if(!this.ready()) return;
var user = Meteor.user();
if (user && ! userProfileComplete(user)){
this.render(getTemplate('user_email'));
} else {
this.next();
}
},
setTitle: function() {
// set title
var title = getSetting("title");
var tagline = getSetting("tagline");
document.title = (tagline ? title+': '+tagline : title) || "";
}
};
filters = Router._filters;
coreSubscriptions = new SubsManager({
// cache recent 50 subscriptions
cacheLimit: 50,
// expire any subscription after 30 minutes
expireIn: 30
});
Meteor.startup( function (){
if(Meteor.isClient){
// Load Hooks
Router.onRun( function () {
Session.set('categorySlug', null);
// if we're not on the search page itself, clear search query and field
if(getCurrentRoute().indexOf('search') == -1){
Session.set('searchQuery', '');
$('.search-field').val('').blur();
}
this.next();
});
// Before Hooks
Router.onBeforeAction(filters.isReady);
Router.onBeforeAction(filters.clearSeenErrors);
Router.onBeforeAction(filters.canView, {except: ['atSignIn', 'atSignUp', 'atForgotPwd', 'atResetPwd', 'signOut']});
Router.onBeforeAction(filters.hasCompletedProfile);
Router.onBeforeAction(filters.isLoggedIn, {only: ['post_submit']});
Router.onBeforeAction(filters.isLoggedOut, {only: []});
Router.onBeforeAction(filters.canPost, {only: ['posts_pending', 'post_submit']});
Router.onBeforeAction(filters.canEditPost, {only: ['post_edit']});
Router.onBeforeAction(filters.canEditComment, {only: ['comment_edit']});
Router.onBeforeAction(filters.isAdmin, {only: ['posts_pending', 'all-users', 'settings', 'toolbox', 'logs']});
// After Hooks
// Router.onAfterAction(filters.resetScroll, {except:['posts_top', 'posts_new', 'posts_best', 'posts_pending', 'posts_category', 'all-users']});
Router.onAfterAction(analyticsInit); // will only run once thanks to _.once()
Router.onAfterAction(analyticsRequest); // log this request with mixpanel, etc
Router.onAfterAction(filters.setTitle);
// Unload Hooks
//
}
});

31
lib/router/other.js Normal file
View file

@ -0,0 +1,31 @@
Meteor.startup(function (){
// Settings
Router.route('/settings', {
name: 'settings',
template: getTemplate('settings'),
data: function () {
// we only have one set of settings for now
return {
hasSettings: !!Settings.find().count(),
settings: Settings.findOne()
}
}
});
// Loading (for testing purposes)
Router.route('/loading', {
name: 'loading',
template: getTemplate('loading')
});
// Toolbox
Router.route('/toolbox', {
name: 'toolbox',
template: getTemplate('toolbox')
});
});

249
lib/router/posts.js Normal file
View file

@ -0,0 +1,249 @@
var getDefaultViewController = function () {
var defaultView = getSetting('defaultView', 'top');
defaultView = defaultView.charAt(0).toUpperCase() + defaultView.slice(1);
return eval("Posts"+defaultView+"Controller");
};
// Controller for all posts lists
PostsListController = FastRender.RouteController.extend({
template: getTemplate('posts_list'),
subscriptions: function () {
// take the first segment of the path to get the view, unless it's '/' in which case the view default to 'top'
// note: most of the time this.params.slug will be empty
this._terms = {
view: this.view,
limit: this.params.limit || getSetting('postsPerPage', 10),
category: this.params.slug
};
if(Meteor.isClient) {
this._terms.query = Session.get("searchQuery");
}
this.postsListSub = coreSubscriptions.subscribe('postsList', this._terms);
this.postsListUsersSub = coreSubscriptions.subscribe('postsListUsers', this._terms);
},
data: function () {
this._terms = {
view: this.view,
limit: this.params.limit || getSetting('postsPerPage', 10),
category: this.params.slug
};
if(Meteor.isClient) {
this._terms.query = Session.get("searchQuery");
}
var parameters = getPostsParameters(this._terms),
postCount = Posts.find(parameters.find, parameters.options).count();
parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') };
var posts = Posts.find(parameters.find, parameters.options);
// Incoming posts
parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') };
var postsIncoming = Posts.find(parameters.find, parameters.options);
Session.set('postsLimit', this._terms.limit);
return {
incoming: postsIncoming,
postsList: posts,
postCount: postCount,
ready: this.postsListSub.ready
};
},
onAfterAction: function() {
Session.set('view', this.view);
}
});
PostsTopController = PostsListController.extend({
view: 'top'
});
PostsNewController = PostsListController.extend({
view: 'new'
});
PostsBestController = PostsListController.extend({
view: 'best'
});
PostsPendingController = PostsListController.extend({
view: 'pending'
});
// Controller for post digest
PostsDigestController = FastRender.RouteController.extend({
template: getTemplate('posts_digest'),
waitOn: function() {
// if day is set, use that. If not default to today
var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : new Date(),
terms = {
view: 'digest',
after: moment(currentDate).startOf('day').toDate(),
before: moment(currentDate).endOf('day').toDate()
};
return [
coreSubscriptions.subscribe('postsList', terms),
coreSubscriptions.subscribe('postsListUsers', terms)
];
},
data: function() {
var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
terms = {
view: 'digest',
after: moment(currentDate).startOf('day').toDate(),
before: moment(currentDate).endOf('day').toDate()
},
parameters = getPostsParameters(terms);
Session.set('currentDate', currentDate);
parameters.find.createdAt = { $lte: Session.get('listPopulatedAt') };
var posts = Posts.find(parameters.find, parameters.options);
// Incoming posts
parameters.find.createdAt = { $gt: Session.get('listPopulatedAt') };
var postsIncoming = Posts.find(parameters.find, parameters.options);
return {
incoming: postsIncoming,
posts: posts
};
}
});
// Controller for post pages
PostPageController = FastRender.RouteController.extend({
template: getTemplate('post_page'),
waitOn: function() {
this.postSubscription = coreSubscriptions.subscribe('singlePost', this.params._id);
this.postUsersSubscription = coreSubscriptions.subscribe('postUsers', this.params._id);
this.commentSubscription = coreSubscriptions.subscribe('postComments', this.params._id);
},
post: function() {
return Posts.findOne(this.params._id);
},
onBeforeAction: function() {
if (! this.post()) {
if (this.postSubscription.ready()) {
this.render(getTemplate('not_found'));
} else {
this.render(getTemplate('loading'));
}
} else {
this.next();
}
},
onRun: function() {
var sessionId = Meteor.default_connection && Meteor.default_connection._lastSessionId ? Meteor.default_connection._lastSessionId : null;
Meteor.call('increasePostViews', this.params._id, sessionId);
},
data: function() {
return this.post();
}
});
Meteor.startup(function () {
Router.route('/', {
name: 'posts_default',
controller: getDefaultViewController()
});
Router.route('/top/:limit?', {
name: 'posts_top',
controller: PostsTopController
});
// New
Router.route('/new/:limit?', {
name: 'posts_new',
controller: PostsNewController
});
// Best
Router.route('/best/:limit?', {
name: 'posts_best',
controller: PostsBestController
});
// Pending
Router.route('/pending/:limit?', {
name: 'posts_pending',
controller: PostsPendingController
});
// TODO: enable /category/new, /category/best, etc. views
// Digest
Router.route('/digest/:year/:month/:day', {
name: 'posts_digest',
controller: PostsDigestController
});
Router.route('/digest', {
name: 'posts_digest_default',
controller: PostsDigestController
});
// Post Page
Router.route('/posts/:_id', {
name: 'post_page',
controller: PostPageController
});
Router.route('/posts/:_id/comment/:commentId', {
name: 'post_page_comment',
controller: PostPageController,
onAfterAction: function () {
// TODO: scroll to comment position
}
});
// Post Edit
Router.route('/posts/:_id/edit', {
name: 'post_edit',
template: getTemplate('post_edit'),
waitOn: function () {
return [
coreSubscriptions.subscribe('singlePost', this.params._id),
coreSubscriptions.subscribe('allUsersAdmin')
];
},
data: function() {
return {
postId: this.params._id,
post: Posts.findOne(this.params._id)
};
},
fastRender: true
});
// Post Submit
Router.route('/submit', {
name: 'post_submit',
template: getTemplate('post_submit'),
waitOn: function () {
return coreSubscriptions.subscribe('allUsersAdmin');
}
});
});

42
lib/router/server.js Normal file
View file

@ -0,0 +1,42 @@
Meteor.startup(function (){
// Link Out
Router.route('/out', {
name: 'out',
where: 'server',
action: function(){
var query = this.request.query;
if(query.url){
var decodedUrl = decodeURIComponent(query.url);
var post = Posts.findOne({url: decodedUrl});
if(post){
var sessionId = Meteor.default_connection && Meteor.default_connection._lastSessionId ? Meteor.default_connection._lastSessionId : null;
Meteor.call('increasePostClicks', post._id, sessionId);
}
this.response.writeHead(302, {'Location': query.url});
this.response.end();
}
}
});
// Account approved email
Router.route('/email/account-approved/:id?', {
name: 'accountApproved',
where: 'server',
action: function() {
var user = Meteor.users.findOne(this.params.id);
var emailProperties = {
profileUrl: getProfileUrl(user),
username: getUserName(user),
siteTitle: getSetting('title'),
siteUrl: getSiteUrl()
};
html = Handlebars.templates[getTemplate('emailAccountApproved')](emailProperties);
this.response.write(buildEmailTemplate(html));
this.response.end();
}
});
});

110
lib/router/users.js Normal file
View file

@ -0,0 +1,110 @@
// Controller for user pages
UserPageController = FastRender.RouteController.extend({
waitOn: function() {
return [
coreSubscriptions.subscribe('userProfile', this.params._idOrSlug)
]
},
data: function() {
var findById = Meteor.users.findOne(this.params._idOrSlug);
var findBySlug = Meteor.users.findOne({slug: this.params._idOrSlug});
if(typeof findById !== "undefined"){
// redirect to slug-based URL
Router.go(getProfileUrl(findById), {replaceState: true});
}else{
return {
user: (typeof findById == "undefined") ? findBySlug : findById
};
}
}
});
// Controller for user account editing
AccountController = FastRender.RouteController.extend({
waitOn: function() {
return coreSubscriptions.subscribe('invites');
},
data: function() {
return {
user : Meteor.user(),
invites: Invites.find({invitingUserId:Meteor.userId()})
};
}
});
Meteor.startup(function () {
// User Logout
Router.route('/sign-out', {
name: 'signOut',
onBeforeAction: function() {
Meteor.logout(function() {
return Router.go('/');
});
}
});
// User Profile
Router.route('/users/:_idOrSlug', {
name: 'user_profile',
template: getTemplate('user_profile'),
controller: UserPageController
});
// User Edit
Router.route('/users/:_idOrSlug/edit', {
name: 'user_edit',
template: getTemplate('user_edit'),
controller: UserPageController
});
// Account
Router.route('/account', {
name: 'account',
template: getTemplate('user_edit'),
controller: AccountController
});
// All Users
Router.route('/all-users/:limit?', {
name: 'all-users',
template: getTemplate('users'),
waitOn: function() {
var limit = parseInt(this.params.limit) || 20;
return coreSubscriptions.subscribe('allUsers', this.params.filterBy, this.params.sortBy, limit);
},
data: function() {
var limit = parseInt(this.params.limit) || 20,
parameters = getUsersParameters(this.params.query.filterBy, this.params.query.sortBy, limit),
filterBy = (typeof this.params.query.filterBy === 'string') ? this.params.query.filterBy : 'all',
sortBy = (typeof this.params.query.sortBy === 'string') ? this.params.query.sortBy : 'createdAt';
Session.set('usersLimit', limit);
return {
users: Meteor.users.find(parameters.find, parameters.options),
filterBy: filterBy,
sortBy: sortBy
};
},
fastRender: true
});
// Unsubscribe (from notifications)
Router.route('/unsubscribe/:hash', {
name: 'unsubscribe',
template: getTemplate('unsubscribe'),
data: function() {
return {
hash: this.params.hash
};
}
});
});

View file

@ -83,10 +83,10 @@ getEmail = function(user){
};
getEmailHash = function(user){
// has to be this way to work with Gravatar
return CryptoJS.MD5(getEmail(user).trim().toLowerCase()).toString()
return Gravatar.hash(getEmail(user));
};
getAvatarUrl = function(user) {
console.log('FUNCTION getAvatarUrl() IS DEPRECATED -- package bengott:avatar is used instead.')
console.warn('FUNCTION getAvatarUrl() IS DEPRECATED -- package bengott:avatar is used instead.')
return Avatar.getUrl(user);
};
getCurrentUserEmail = function(){
@ -141,8 +141,8 @@ setUserSetting = function (setting, value, userArgument) {
var field = {};
field['profile.'+setting] = value;
var options = {$set: field};
console.log(find);
console.log(options);
// console.log(find);
// console.log(options);
var result = Meteor.users.update(find, options, {validate: false});
};

View file

@ -1 +1 @@
telescopeVersion = "0.9.7";
telescopeVersion = "0.9.10";

View file

@ -2,14 +2,14 @@
"dependencies": [
[
"meteor",
"1.1.1"
"1.1.3"
],
[
"underscore",
"1.0.0"
"1.0.1"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.33",
"toolVersion": "meteor-tool@1.0.35",
"format": "1.0"
}

View file

@ -1,17 +1,13 @@
Meteor.startup(function () {
Router.map(function() {
this.route('api', {
where: 'server',
path: '/api/:limit?',
action: function() {
var limit = parseInt(this.params.limit);
this.response.write(serveAPI(limit));
this.response.end();
}
});
Router.route('api', {
where: 'server',
path: '/api/:limit?',
action: function() {
var limit = parseInt(this.params.limit);
this.response.write(serveAPI(limit));
this.response.end();
}
});
});

View file

@ -2,72 +2,152 @@
"dependencies": [
[
"aldeed:simple-schema",
"1.1.0"
],
[
"application-configuration",
"1.0.3"
],
[
"base64",
"1.0.0"
"1.0.1"
],
[
"binary-heap",
"1.0.1"
],
[
"blaze",
"2.0.1"
"2.0.3"
],
[
"blaze-tools",
"1.0.1"
],
[
"boilerplate-generator",
"1.0.1"
],
[
"callback-hook",
"1.0.1"
],
[
"check",
"1.0.1"
"1.0.2"
],
[
"deps",
"coffeescript",
"1.0.4"
],
[
"ddp",
"1.0.11"
],
[
"deps",
"1.0.5"
],
[
"ejson",
"1.0.3"
"1.0.4"
],
[
"follower-livedata",
"1.0.2"
],
[
"geojson-utils",
"1.0.0"
],
[
"htmljs",
"1.0.1"
],
[
"html-tools",
"1.0.2"
],
[
"htmljs",
"1.0.2"
],
[
"id-map",
"1.0.0"
"1.0.1"
],
[
"jquery",
"1.0.0"
"1.0.1"
],
[
"json",
"1.0.0"
"1.0.1"
],
[
"logging",
"1.0.5"
],
[
"meteor",
"1.1.1"
"1.1.3"
],
[
"minifiers",
"1.1.2"
],
[
"minimongo",
"1.0.3"
"1.0.5"
],
[
"mongo",
"1.0.8"
],
[
"observe-sequence",
"1.0.2"
"1.0.3"
],
[
"ordered-dict",
"1.0.0"
"1.0.1"
],
[
"random",
"1.0.0"
"1.0.1"
],
[
"reactive-dict",
"1.0.4"
],
[
"reactive-var",
"1.0.3"
],
[
"retry",
"1.0.1"
],
[
"routepolicy",
"1.0.2"
],
[
"session",
"1.0.4"
],
[
"spacebars",
"1.0.3"
],
[
"spacebars-compiler",
"1.0.3"
],
[
"tap:http-methods",
"0.0.23"
],
[
"tap:i18n",
"1.2.1"
],
[
"telescope-base",
"0.0.0"
@ -81,19 +161,31 @@
"0.2.9"
],
[
"tracker",
"1.0.2"
"templating",
"1.0.9"
],
[
"ui",
"tracker",
"1.0.3"
],
[
"ui",
"1.0.4"
],
[
"underscore",
"1.0.0"
"1.0.1"
],
[
"webapp",
"1.1.4"
],
[
"webapp-hashing",
"1.0.1"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.33",
"toolVersion": "meteor-tool@1.0.35",
"format": "1.0"
}

View file

@ -45,19 +45,19 @@ adminNav = [];
viewNav = [
{
route: 'posts_top',
label: 'Top'
label: 'top'
},
{
route: 'posts_new',
label: 'New'
label: 'new'
},
{
route: 'posts_best',
label: 'Best'
label: 'best'
},
{
route: 'posts_digest',
label: 'Digest'
route: 'posts_digest_default',
label: 'digest'
}
];

View file

@ -2,72 +2,152 @@
"dependencies": [
[
"aldeed:simple-schema",
"1.1.0"
],
[
"application-configuration",
"1.0.3"
],
[
"base64",
"1.0.0"
"1.0.1"
],
[
"binary-heap",
"1.0.1"
],
[
"blaze",
"2.0.1"
"2.0.3"
],
[
"blaze-tools",
"1.0.1"
],
[
"boilerplate-generator",
"1.0.1"
],
[
"callback-hook",
"1.0.1"
],
[
"check",
"1.0.1"
"1.0.2"
],
[
"deps",
"coffeescript",
"1.0.4"
],
[
"ddp",
"1.0.11"
],
[
"deps",
"1.0.5"
],
[
"ejson",
"1.0.3"
"1.0.4"
],
[
"follower-livedata",
"1.0.2"
],
[
"geojson-utils",
"1.0.0"
],
[
"htmljs",
"1.0.1"
],
[
"html-tools",
"1.0.2"
],
[
"htmljs",
"1.0.2"
],
[
"id-map",
"1.0.0"
"1.0.1"
],
[
"jquery",
"1.0.0"
"1.0.1"
],
[
"json",
"1.0.0"
"1.0.1"
],
[
"logging",
"1.0.5"
],
[
"meteor",
"1.1.1"
"1.1.3"
],
[
"minifiers",
"1.1.2"
],
[
"minimongo",
"1.0.3"
"1.0.5"
],
[
"mongo",
"1.0.8"
],
[
"observe-sequence",
"1.0.2"
"1.0.3"
],
[
"ordered-dict",
"1.0.0"
"1.0.1"
],
[
"random",
"1.0.0"
"1.0.1"
],
[
"reactive-dict",
"1.0.4"
],
[
"reactive-var",
"1.0.3"
],
[
"retry",
"1.0.1"
],
[
"routepolicy",
"1.0.2"
],
[
"session",
"1.0.4"
],
[
"spacebars",
"1.0.3"
],
[
"spacebars-compiler",
"1.0.3"
],
[
"tap:http-methods",
"0.0.23"
],
[
"tap:i18n",
"1.2.1"
],
[
"telescope-i18n",
"0.0.0"
@ -77,19 +157,31 @@
"0.2.9"
],
[
"tracker",
"1.0.2"
"templating",
"1.0.9"
],
[
"ui",
"tracker",
"1.0.3"
],
[
"ui",
"1.0.4"
],
[
"underscore",
"1.0.0"
"1.0.1"
],
[
"webapp",
"1.1.4"
],
[
"webapp-hashing",
"1.0.1"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.33",
"toolVersion": "meteor-tool@1.0.35",
"format": "1.0"
}

1
packages/telescope-blank/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.build*

View file

@ -0,0 +1 @@
node_modules

View file

@ -0,0 +1,7 @@
This directory and the files immediately inside it are automatically generated
when you change this package's NPM dependencies. Commit the files in this
directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
so that others run the same versions of sub-dependencies.
You should NOT check in the node_modules directory that Meteor automatically
creates; if you are using git, the .gitignore file tells git to ignore it.

View file

@ -0,0 +1,29 @@
{
"dependencies": {
"html-to-text": {
"version": "0.1.0",
"dependencies": {
"htmlparser": {
"version": "1.7.7"
},
"underscore": {
"version": "1.7.0"
},
"underscore.string": {
"version": "2.4.0"
},
"optimist": {
"version": "0.6.1",
"dependencies": {
"wordwrap": {
"version": "0.0.2"
},
"minimist": {
"version": "0.0.10"
}
}
}
}
}
}
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1,3 @@
{
"translation_key": "translation string"
}

View file

@ -0,0 +1 @@
both.js

Some files were not shown because too many files have changed in this diff Show more