diff --git a/app/assets/javascripts/discourse/components/post-menu.js.es6 b/app/assets/javascripts/discourse/components/post-menu.js.es6
index 765539245a7..2b3e28e72a0 100644
--- a/app/assets/javascripts/discourse/components/post-menu.js.es6
+++ b/app/assets/javascripts/discourse/components/post-menu.js.es6
@@ -248,7 +248,9 @@ const PostMenuComponent = Ember.Component.extend(StringBuffer, {
if (likeCount > 0) {
const likedPost = !!this.get('post.likeAction.acted');
- const label = likedPost ? 'post.has_likes_title_you' : 'post.has_likes_title';
+ const label = likedPost
+ ? likeCount === 1 ? 'post.has_likes_title_only_you' : 'post.has_likes_title_you'
+ : 'post.has_likes_title';
return new Button('like-count', label, undefined, {
className: 'like-count highlight-action',
diff --git a/app/assets/javascripts/discourse/controllers/feature-topic.js.es6 b/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
index 4b189d168d3..34c1c9516f1 100644
--- a/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/feature-topic.js.es6
@@ -41,7 +41,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
@computed("categoryLink", "pinnedInCategoryCount")
alreadyPinnedMessage(categoryLink, count) {
- return I18n.t("topic.feature_topic.already_pinned", { categoryLink, count });
+ const key = count === 0 ? "topic.feature_topic.not_pinned" : "topic.feature_topic.already_pinned";
+ return I18n.t(key, { categoryLink, count });
},
@computed("parsedPinnedInCategoryUntil")
diff --git a/app/assets/javascripts/discourse/models/nav-item.js.es6 b/app/assets/javascripts/discourse/models/nav-item.js.es6
index 64cb9fea433..1d614c0d1d0 100644
--- a/app/assets/javascripts/discourse/models/nav-item.js.es6
+++ b/app/assets/javascripts/discourse/models/nav-item.js.es6
@@ -12,12 +12,13 @@ const NavItem = Discourse.Model.extend({
}
var extra = { count: count };
+ var titleKey = count === 0 ? '.title' : '.title_with_count';
if (categoryName) {
name = 'category';
extra.categoryName = toTitleCase(categoryName);
}
- return I18n.t("filters." + name.replace("/", ".") + ".title", extra);
+ return I18n.t("filters." + name.replace("/", ".") + titleKey, extra);
}.property('categoryName', 'name', 'count'),
categoryName: function() {
diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
index 8456eaf4faa..219ae7d3276 100644
--- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6
@@ -57,7 +57,7 @@ export default (filter, params) => {
},
titleToken() {
- const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', { count: 0 }),
+ const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title'),
category = this.currentModel.category;
return I18n.t('filters.with_category', { filter: filterText, category: category.get('name') });
diff --git a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
index 0da680a200f..890f0729f85 100644
--- a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
+++ b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6
@@ -80,7 +80,7 @@ export default function(filter, extras) {
titleToken() {
if (filter === Discourse.Utilities.defaultHomepage()) { return; }
- const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title', {count: 0});
+ const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title');
return I18n.t('filters.with_topics', {filter: filterText});
},
diff --git a/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs
index 3d875eb6062..6c3640a6c79 100644
--- a/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs
+++ b/app/assets/javascripts/discourse/templates/components/hamburger-menu.hbs
@@ -41,14 +41,22 @@
{{/if}}
{{#menu-links}}
-
diff --git a/app/assets/javascripts/discourse/templates/modal/feature-topic.hbs b/app/assets/javascripts/discourse/templates/modal/feature-topic.hbs
index 7aee95425e3..942fa261165 100644
--- a/app/assets/javascripts/discourse/templates/modal/feature-topic.hbs
+++ b/app/assets/javascripts/discourse/templates/modal/feature-topic.hbs
@@ -5,7 +5,11 @@
{{#if model.pinned_globally}}
{{#conditional-loading-spinner size="small" condition=loading}}
- {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}}
+ {{#if pinnedGloballyCount}}
+ {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}}
+ {{else}}
+ {{{i18n "topic.feature_topic.not_pinned_globally"}}}
+ {{/if}}
{{/conditional-loading-spinner}}
{{#conditional-loading-spinner size="small" condition=loading}}
- {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}}
+ {{#if pinnedGloballyCount}}
+ {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}}
+ {{else}}
+ {{{i18n "topic.feature_topic.not_pinned_globally"}}}
+ {{/if}}
{{/conditional-loading-spinner}}
@@ -71,7 +79,11 @@
{{#conditional-loading-spinner size="small" condition=loading}}
- {{{i18n "topic.feature_topic.already_banner" count=bannerCount}}}
+ {{#if bannerCount}}
+ {{{i18n "topic.feature_topic.banner_exists"}}}
+ {{else}}
+ {{{i18n "topic.feature_topic.no_banner_exists"}}}
+ {{/if}}
{{/conditional-loading-spinner}}
diff --git a/app/assets/javascripts/discourse/templates/user/preferences.hbs b/app/assets/javascripts/discourse/templates/user/preferences.hbs
index 3ebc10e5a5d..efe26f09d91 100644
--- a/app/assets/javascripts/discourse/templates/user/preferences.hbs
+++ b/app/assets/javascripts/discourse/templates/user/preferences.hbs
@@ -182,7 +182,11 @@
{{preference-checkbox labelKey="user.email_always" checked=model.email_always}}
- {{i18n 'user.email.frequency' count=siteSettings.email_time_window_mins}}
+ {{#if siteSettings.email_time_window_mins}}
+ {{i18n 'user.email.frequency' count=siteSettings.email_time_window_mins}}
+ {{else}}
+ {{i18n 'user.email.frequency_immediately'}}
+ {{/if}}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 162a03aaff0..552d104ed6d 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -537,8 +537,8 @@ en:
ok: "We will email you to confirm"
invalid: "Please enter a valid email address"
authenticated: "Your email has been authenticated by {{provider}}"
+ frequency_immediately: "We'll email you immediately if you haven't read the thing we're emailing you about."
frequency:
- zero: "We'll email you immediately if you haven't read the thing we're emailing you about."
one: "We'll only email you if we haven't seen you in the last minute."
other: "We'll only email you if we haven't seen you in the last {{count}} minutes."
@@ -1225,25 +1225,24 @@ en:
unpin_until: "Remove this topic from the top of the {{categoryLink}} category or wait until
%{until}."
pin_note: "Users can unpin the topic individually for themselves."
pin_validation: "A date is required to pin this topic."
+ not_pinned: "There are no topics pinned in {{categoryLink}}."
already_pinned:
- zero: "There are no topics pinned in {{categoryLink}}."
- one: "Topics currently pinned in {{categoryLink}}:
1."
- other: "Topics currently pinned in {{categoryLink}}:
{{count}}."
+ one: "Topics currently pinned in {{categoryLink}}:
1"
+ other: "Topics currently pinned in {{categoryLink}}:
{{count}}"
pin_globally: "Make this topic appear at the top of all topic lists until"
confirm_pin_globally: "You already have {{count}} globally pinned topics. Too many pinned topics may be a burden for new and anonymous users. Are you sure you want to pin another topic globally?"
unpin_globally: "Remove this topic from the top of all topic lists."
unpin_globally_until: "Remove this topic from the top of all topic lists or wait until
%{until}."
global_pin_note: "Users can unpin the topic individually for themselves."
+ not_pinned_globally: "There are no topics pinned globally."
already_pinned_globally:
- zero: "There are no topics pinned globally."
- one: "Topics currently pinned globally:
1."
- other: "Topics currently pinned globally:
{{count}}."
+ one: "Topics currently pinned globally:
1"
+ other: "Topics currently pinned globally:
{{count}}"
make_banner: "Make this topic into a banner that appears at the top of all pages."
remove_banner: "Remove the banner that appears at the top of all pages."
banner_note: "Users can dismiss the banner by closing it. Only one topic can be bannered at any given time."
- already_banner:
- zero: "There is no banner topic."
- one: "There
is currently a banner topic."
+ no_banner_exists: "There is no banner topic."
+ banner_exists: "There
is currently a banner topic."
inviting: "Inviting..."
automatically_add_to_groups_optional: "This invite also includes access to these groups: (optional, admin only)"
@@ -1364,8 +1363,8 @@ en:
one: "1 person liked this post"
other: "{{count}} people liked this post"
+ has_likes_title_only_you: "you liked this post"
has_likes_title_you:
- zero: "you liked this post"
one: "you and 1 other person liked this post"
other: "you and {{count}} other people liked this post"
@@ -1515,11 +1514,6 @@ en:
one: "1 person voted for this post"
other: "{{count}} people voted for this post"
- edits:
- one: 1 edit
- other: "{{count}} edits"
- zero: no edits
-
delete:
confirm:
one: "Are you sure you want to delete that post?"
@@ -1600,8 +1594,6 @@ en:
position_disabled_click: 'enable the "fixed category positions" setting.'
parent: "Parent Category"
notifications:
- title: ''
- reasons:
watching:
title: "Watching"
description: "You will automatically watch all new topics in these categories. You will be notified of every new post in every topic, and a count of new replies will be shown."
@@ -1717,8 +1709,8 @@ en:
with_topics: "%{filter} topics"
with_category: "%{filter} %{category} topics"
latest:
- title:
- zero: "Latest"
+ title: "Latest"
+ title_with_count:
one: "Latest (1)"
other: "Latest ({{count}})"
help: "topics with recent posts"
@@ -1736,23 +1728,21 @@ en:
title_in: "Category - {{categoryName}}"
help: "all topics grouped by category"
unread:
- title:
- zero: "Unread"
+ title: "Unread"
+ title_with_count:
one: "Unread (1)"
other: "Unread ({{count}})"
help: "topics you are currently watching or tracking with unread posts"
lower_title_with_count:
- zero: ""
one: "1 unread"
other: "{{count}} unread"
new:
lower_title_with_count:
- zero: ""
one: "1 new"
other: "{{count}} new"
lower_title: "new"
- title:
- zero: "New"
+ title: "New"
+ title_with_count:
one: "New (1)"
other: "New ({{count}})"
help: "topics created in the last few days"
@@ -1763,8 +1753,8 @@ en:
title: "Bookmarks"
help: "topics you have bookmarked"
category:
- title:
- zero: "{{categoryName}}"
+ title: "{{categoryName}}"
+ title_with_count:
one: "{{categoryName}} (1)"
other: "{{categoryName}} ({{count}})"
help: "latest topics in the {{categoryName}} category"
@@ -2566,8 +2556,8 @@ en:
bad_count_warning:
header: "WARNING!"
text: "There are missing grant samples. This happens when the badge query returns user IDs or post IDs that do not exist. This may cause unexpected results later on - please double-check your query."
+ no_grant_count: "No badges to be assigned."
grant_count:
- zero: "No badges to be assigned."
one: "
1 badge to be assigned."
other: "
%{count} badges to be assigned."
sample: "Sample:"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index a96f5f25e09..c143a20b347 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -140,26 +140,27 @@ en:
one: "1 reply"
other: "%{count} replies"
+ no_mentions_allowed: "Sorry, you can't mention other users."
too_many_mentions:
- zero: "Sorry, you can't mention other users."
one: "Sorry, you can only mention one other user in a post."
other: "Sorry, you can only mention %{count} users in a post."
+ no_mentions_allowed_newuser: "Sorry, new users can't mention other users."
too_many_mentions_newuser:
- zero: "Sorry, new users can't mention other users."
one: "Sorry, new users can only mention one other user in a post."
other: "Sorry, new users can only mention %{count} users in a post."
+ no_images_allowed: "Sorry, new users can't put images in posts."
too_many_images:
- zero: "Sorry, new users can't put images in posts."
one: "Sorry, new users can only put one image in a post."
other: "Sorry, new users can only put %{count} images in a post."
+ no_attachments_allowed: "Sorry, new users can't put attachments in posts."
too_many_attachments:
- zero: "Sorry, new users can't put attachments in posts."
one: "Sorry, new users can only put one attachment in a post."
other: "Sorry, new users can only put %{count} attachments in a post."
+ no_links_allowed: "Sorry, new users can't put links in posts."
too_many_links:
- zero: "Sorry, new users can't put links in posts."
one: "Sorry, new users can only put one link in a post."
other: "Sorry, new users can only put %{count} links in a post."
+
spamming_host: "Sorry you cannot post a link to that host."
user_is_suspended: "Suspended users are not allowed to post."
topic_not_found: "Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?"
diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb
index fc16571476d..29dcb9a9e8a 100644
--- a/lib/validators/post_validator.rb
+++ b/lib/validators/post_validator.rb
@@ -51,9 +51,9 @@ class Validators::PostValidator < ActiveModel::Validator
# Ensure maximum amount of mentions in a post
def max_mention_validator(post)
if acting_user_is_trusted?(post)
- add_error_if_count_exceeded(post, :too_many_mentions, post.raw_mentions.size, SiteSetting.max_mentions_per_post)
+ add_error_if_count_exceeded(post, :no_mentions_allowed, :too_many_mentions, post.raw_mentions.size, SiteSetting.max_mentions_per_post)
else
- add_error_if_count_exceeded(post, :too_many_mentions_newuser, post.raw_mentions.size, SiteSetting.newuser_max_mentions_per_post)
+ add_error_if_count_exceeded(post, :no_mentions_allowed_newuser, :too_many_mentions_newuser, post.raw_mentions.size, SiteSetting.newuser_max_mentions_per_post)
end
end
@@ -65,17 +65,17 @@ class Validators::PostValidator < ActiveModel::Validator
# Ensure new users can not put too many images in a post
def max_images_validator(post)
- add_error_if_count_exceeded(post, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post)
+ add_error_if_count_exceeded(post, :no_images_allowed, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post)
end
# Ensure new users can not put too many attachments in a post
def max_attachments_validator(post)
- add_error_if_count_exceeded(post, :too_many_attachments, post.attachment_count, SiteSetting.newuser_max_attachments) unless acting_user_is_trusted?(post)
+ add_error_if_count_exceeded(post, :no_attachments_allowed, :too_many_attachments, post.attachment_count, SiteSetting.newuser_max_attachments) unless acting_user_is_trusted?(post)
end
# Ensure new users can not put too many links in a post
def max_links_validator(post)
- add_error_if_count_exceeded(post, :too_many_links, post.link_count, SiteSetting.newuser_max_links) unless acting_user_is_trusted?(post)
+ add_error_if_count_exceeded(post, :no_links_allowed, :too_many_links, post.link_count, SiteSetting.newuser_max_links) unless acting_user_is_trusted?(post)
end
# Stop us from posting the same thing too quickly
@@ -98,7 +98,13 @@ class Validators::PostValidator < ActiveModel::Validator
post.acting_user.present? && post.acting_user.has_trust_level?(TrustLevel[1])
end
- def add_error_if_count_exceeded(post, key_for_translation, current_count, max_count)
- post.errors.add(:base, I18n.t(key_for_translation, count: max_count)) if current_count > max_count
+ def add_error_if_count_exceeded(post, not_allowed_translation_key, limit_translation_key, current_count, max_count)
+ if current_count > max_count
+ if max_count == 0
+ post.errors.add(:base, I18n.t(not_allowed_translation_key))
+ else
+ post.errors.add(:base, I18n.t(limit_translation_key, count: max_count))
+ end
+ end
end
end