Compare commits
1 Commits
main
...
i18n/count
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7974fcba46 |
@ -544,7 +544,9 @@ en:
|
||||
|
||||
dominating_topic: You’ve posted a lot in this topic! Consider giving others an opportunity to reply here and discuss things with each other as well.
|
||||
|
||||
get_a_room: You’ve replied to @%{reply_username} %{count} times, did you know you could send them a personal message instead?
|
||||
get_a_room:
|
||||
one: "You’ve replied to @%{reply_username} once, did you know you could send them a personal message instead?"
|
||||
other: "You’ve replied to @%{reply_username} %{count} times, did you know you could send them a personal message instead?"
|
||||
|
||||
too_many_replies: |
|
||||
### You have reached the reply limit for this topic
|
||||
@ -707,7 +709,9 @@ en:
|
||||
topic_exists:
|
||||
one: "Can't delete this category because it has %{count} topic. Oldest topic is %{topic_link}."
|
||||
other: "Can't delete this category because it has %{count} topics. Oldest topic is %{topic_link}."
|
||||
topic_exists_no_oldest: "Can't delete this category because topic count is %{count}."
|
||||
topic_exists_no_oldest:
|
||||
one: "Can't delete this category because it has %{count} topic."
|
||||
other: "Can't delete this category because it has %{count} topics."
|
||||
uncategorized_description: "Topics that don't need a category, or don't fit into any other existing category."
|
||||
trust_levels:
|
||||
admin: "Admin"
|
||||
@ -2444,7 +2448,9 @@ en:
|
||||
regex_invalid: "The regular expression is invalid: %{error}"
|
||||
leading_trailing_slash: "The regular expression must not start and end with a slash."
|
||||
unicode_usernames_avatars: "The internal system avatars do not support Unicode usernames."
|
||||
list_value_count: "The list must contain exactly %{count} values."
|
||||
list_value_count:
|
||||
one: "The list must contain exactly %{count} value."
|
||||
other: "The list must contain exactly %{count} values."
|
||||
markdown_linkify_tlds: "You cannot include a value of '*'."
|
||||
google_oauth2_hd_groups: "You must configure all 'google oauth2 hd' settings before enabling this setting."
|
||||
search_tokenize_chinese_enabled: "You must disable 'search_tokenize_chinese' before enabling this setting."
|
||||
@ -3275,10 +3281,16 @@ en:
|
||||
email_reject_post_too_short:
|
||||
title: "Email Reject Post Too Short"
|
||||
subject_template: "[%{email_prefix}] Email issue -- Post too short"
|
||||
text_body_template: |
|
||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||
text_body_template:
|
||||
one: |
|
||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||
|
||||
To promote more in depth conversations, very short replies are not allowed. Can you please reply with at least %{count} characters? Alternatively, you can like a post via email by replying with "+1".
|
||||
To promote more in depth conversations, very short replies are not allowed. Can you please reply with at least %{count} character? Alternatively, you can like a post via email by replying with "+1".
|
||||
|
||||
other: |
|
||||
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
|
||||
|
||||
To promote more in depth conversations, very short replies are not allowed. Can you please reply with at least %{count} characters? Alternatively, you can like a post via email by replying with "+1".
|
||||
|
||||
email_reject_invalid_post_action:
|
||||
title: "Email Reject Invalid Post Action"
|
||||
@ -4613,7 +4625,9 @@ en:
|
||||
mass_award:
|
||||
errors:
|
||||
invalid_csv: We encountered an error on line %{line_number}. Please confirm the CSV has one email per line.
|
||||
too_many_csv_entries: Too many entries in the CSV file. Please provide a CSV file with no more than %{count} entries.
|
||||
too_many_csv_entries:
|
||||
one: Too many entries in the CSV file. Please provide a CSV file with no more than %{count} entry.
|
||||
other: Too many entries in the CSV file. Please provide a CSV file with no more than %{count} entries.
|
||||
badge_disabled: Please enable the %{badge_name} badge first.
|
||||
cant_grant_multiple_times: Can't grant the %{badge_name} badge multiple times to a single user.
|
||||
editor:
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
{{d-icon "info-circle"}}
|
||||
{{i18n
|
||||
"chat.settings.retention_info"
|
||||
days=this.siteSettings.chat_channel_retention_days
|
||||
count=this.siteSettings.chat_channel_retention_days
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -32,7 +32,7 @@ export default Component.extend({
|
||||
days = this.siteSettings.chat_dm_retention_days;
|
||||
translationKey = "chat.retention_reminders.dm";
|
||||
}
|
||||
return I18n.t(translationKey, { days });
|
||||
return I18n.t(translationKey, { count: days });
|
||||
},
|
||||
|
||||
@discourseComputed("chatChannel.chatable_type")
|
||||
|
||||
@ -91,16 +91,29 @@ export default class CreateChannelController extends Controller.extend(
|
||||
const allowedGroups = catPermissions.allowed_groups;
|
||||
|
||||
if (catPermissions.private) {
|
||||
const warningTranslationKey =
|
||||
allowedGroups.length < 3 ? "warning_groups" : "warning_multiple_groups";
|
||||
let warningTranslationKey;
|
||||
|
||||
switch (allowedGroups.length) {
|
||||
case 1:
|
||||
warningTranslationKey =
|
||||
"chat.create_channel.auto_join_users.warning_one_group";
|
||||
break;
|
||||
case 2:
|
||||
warningTranslationKey =
|
||||
"chat.create_channel.auto_join_users.warning_two_groups";
|
||||
break;
|
||||
default:
|
||||
warningTranslationKey =
|
||||
"chat.create_channel.auto_join_users.warning_multiple_groups";
|
||||
break;
|
||||
}
|
||||
|
||||
this.set(
|
||||
"autoJoinWarning",
|
||||
I18n.t(`chat.create_channel.auto_join_users.${warningTranslationKey}`, {
|
||||
members_count: catPermissions.members_count,
|
||||
I18n.t(warningTranslationKey, {
|
||||
count: catPermissions.members_count,
|
||||
group: escapeExpression(allowedGroups[0]),
|
||||
group_2: escapeExpression(allowedGroups[1]),
|
||||
count: allowedGroups.length,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
|
||||
@ -116,10 +116,10 @@ en:
|
||||
without_membership:
|
||||
one: "%{username} has not joined this channel."
|
||||
other: "%{username} and %{others} have not joined this channel."
|
||||
group_mentions_disabled:
|
||||
group_mentions_disabled:
|
||||
one: "%{group_name} doesn't allow mentions"
|
||||
other: "%{group_name} and %{others} doesn't allow mentions"
|
||||
too_many_members:
|
||||
too_many_members:
|
||||
one: "%{group_name} has too many members. No one was notified"
|
||||
other: "%{group_name} and %{others} have too many members. No one was notified"
|
||||
warning_multiple:
|
||||
@ -132,12 +132,16 @@ en:
|
||||
all: "Nobody will be notified"
|
||||
unreachable:
|
||||
one: "@%{group} doesn't allow mentions"
|
||||
other: "@%{group} and @%{group_2} doesn't allow mentions"
|
||||
unreachable_multiple: "@%{group} and %{count} others doesn't allow mentions"
|
||||
other: "@%{group} and @%{group_2} don't allow mentions"
|
||||
unreachable_multiple:
|
||||
one: "@%{group} and %{count} other group don't allow mentions"
|
||||
other: "@%{group} and %{count} others don't allow mentions"
|
||||
too_many_members:
|
||||
one: "Mentioning @%{group} exceeds the %{notification_limit} of %{limit}"
|
||||
other: "Mentioning both @%{group} or @%{group_2} exceeds the %{notification_limit} of %{limit}"
|
||||
too_many_members_multiple: "These %{count} groups exceed the %{notification_limit} of %{limit}"
|
||||
too_many_members_multiple:
|
||||
one: "This %{count} group exceeds the %{notification_limit} of %{limit}"
|
||||
other: "These %{count} groups exceed the %{notification_limit} of %{limit}"
|
||||
users_limit:
|
||||
one: "%{count} user"
|
||||
other: "%{count} users"
|
||||
@ -272,10 +276,15 @@ en:
|
||||
create_channel:
|
||||
auto_join_users:
|
||||
public_category_warning: "%{category} is a public category. Automatically add all recently active users to this channel?"
|
||||
warning_groups:
|
||||
one: Automatically add %{members_count} users from %{group}?
|
||||
other: Automatically add %{members_count} users from %{group} and %{group_2}?
|
||||
warning_multiple_groups: Automatically add %{members_count} users from %{group_1} and %{count} others?
|
||||
warning_one_group:
|
||||
one: Automatically add %{count} user from %{group}?
|
||||
other: Automatically add %{count} users from %{group}?
|
||||
warning_two_groups:
|
||||
one: Automatically add %{count} user from %{group} and %{group_2}?
|
||||
other: Automatically add %{count} users from %{group} and %{group_2}?
|
||||
warning_multiple_groups:
|
||||
one: Automatically add %{count} user from %{group_1} and multiple other groups?
|
||||
other: Automatically add %{count} users from %{group_1} and multiple other groups?
|
||||
choose_category:
|
||||
label: "Choose a category"
|
||||
none: "select one..."
|
||||
@ -283,7 +292,9 @@ en:
|
||||
hint_groups:
|
||||
one: Users in %{hint} will have access to this channel per the <a href=%{link} target="_blank">security settings</a>
|
||||
other: Users in %{hint} and %{hint_2} will have access to this channel per the <a href=%{link} target="_blank">security settings</a>
|
||||
hint_multiple_groups: Users in %{hint_1} and %{count} other groups will have access to this channel per the <a href=%{link} target="_blank">security settings</a>
|
||||
hint_multiple_groups:
|
||||
one: Users in %{hint_1} and %{count} other group will have access to this channel per the <a href=%{link} target="_blank">security settings</a>
|
||||
other: Users in %{hint_1} and %{count} other groups will have access to this channel per the <a href=%{link} target="_blank">security settings</a>
|
||||
create: "Create channel"
|
||||
description: "Description (optional)"
|
||||
name: "Channel name"
|
||||
@ -338,7 +349,9 @@ en:
|
||||
saved: "Saved"
|
||||
unfollow: "Leave"
|
||||
admin_title: "Admin"
|
||||
retention_info: "Chat history will be saved for %{days} days."
|
||||
retention_info:
|
||||
one: "Chat history will be saved for %{count} day."
|
||||
other: "Chat history will be saved for %{count} days."
|
||||
|
||||
admin:
|
||||
title: "Chat"
|
||||
@ -410,8 +423,12 @@ en:
|
||||
other: "%{commaSeparatedUsernames} and %{count} others are typing"
|
||||
|
||||
retention_reminders:
|
||||
public: "Channel history is retained for %{days} days."
|
||||
dm: "Personal chat history is retained for %{days} days."
|
||||
public:
|
||||
one: "Channel history is retained for %{count} day."
|
||||
other: "Channel history is retained for %{count} days."
|
||||
dm:
|
||||
one: "Personal chat history is retained for %{count} day."
|
||||
other: "Personal chat history is retained for %{count} days."
|
||||
|
||||
flags:
|
||||
off_topic: "This message is not relevant to the current discussion as defined by the channel title, and should probably be moved elsewhere."
|
||||
|
||||
@ -28,7 +28,7 @@ module(
|
||||
async test(assert) {
|
||||
assert.equal(
|
||||
query(".chat-retention-reminder-text").innerText.trim(),
|
||||
I18n.t("chat.retention_reminders.public", { days: 100 })
|
||||
I18n.t("chat.retention_reminders.public", { count: 100 })
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@ -76,7 +76,9 @@ en:
|
||||
|
||||
breakdown:
|
||||
title: "Poll results"
|
||||
votes: "%{count} votes"
|
||||
votes:
|
||||
one: "%{count} vote"
|
||||
other: "%{count} votes"
|
||||
breakdown: "Breakdown"
|
||||
percentage: "Percentage"
|
||||
count: "Count"
|
||||
@ -91,7 +93,9 @@ en:
|
||||
insert: Insert Poll
|
||||
help:
|
||||
options_min_count: Enter at least 1 option.
|
||||
options_max_count: Enter at most %{count} options.
|
||||
options_max_count:
|
||||
one: Enter at most %{count} option.
|
||||
other: Enter at most %{count} options.
|
||||
invalid_min_value: Minimum value must be at least 1.
|
||||
invalid_max_value: Maximum value must be at least 1, but less than or equal with the number of options.
|
||||
invalid_values: Minimum value must be smaller than the maximum value.
|
||||
|
||||
@ -33,11 +33,18 @@ class LocaleFileValidator
|
||||
wrong_pluralization_keys: "Pluralized strings must have only the sub-keys 'one' and 'other'.\nThe following keys have missing or additional keys:",
|
||||
invalid_one_keys: "The following keys contain the number 1 instead of the interpolation key %{count}:",
|
||||
invalid_message_format_one_key: "The following keys use 'one {1 foo}' instead of the generic 'one {# foo}':",
|
||||
missing_pluralization: "The following keys use %{count} without pluralization.\nSplit the key into `one` and `other` or add it to the allow list in `script/i18n_lint.rb`:",
|
||||
}
|
||||
|
||||
PLURALIZATION_KEYS = ['zero', 'one', 'two', 'few', 'many', 'other']
|
||||
ENGLISH_KEYS = ['one', 'other']
|
||||
|
||||
COUNT_WITHOUT_PLURALIZATION_ALLOW_LIST = [
|
||||
"errors.messages.",
|
||||
"activemodel.errors.messages.",
|
||||
"activerecord.errors.messages.",
|
||||
]
|
||||
|
||||
def initialize(filename)
|
||||
@filename = filename
|
||||
@errors = {}
|
||||
@ -73,7 +80,7 @@ class LocaleFileValidator
|
||||
if Hash === value
|
||||
each_translation(value, current_key, &block)
|
||||
else
|
||||
yield(current_key, value.to_s)
|
||||
yield(current_key, value.to_s, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -83,22 +90,29 @@ class LocaleFileValidator
|
||||
@errors[:invalid_relative_image_sources] = []
|
||||
@errors[:invalid_interpolation_key_format] = []
|
||||
@errors[:invalid_message_format_one_key] = []
|
||||
@errors[:missing_pluralization] = []
|
||||
|
||||
each_translation(yaml) do |key, value|
|
||||
each_translation(yaml) do |full_key, value, last_key_part|
|
||||
if value.match?(/href\s*=\s*["']\/[^\/]|\]\(\/[^\/]/i)
|
||||
@errors[:invalid_relative_links] << key
|
||||
@errors[:invalid_relative_links] << full_key
|
||||
end
|
||||
|
||||
if value.match?(/src\s*=\s*["']\/[^\/]/i)
|
||||
@errors[:invalid_relative_image_sources] << key
|
||||
@errors[:invalid_relative_image_sources] << full_key
|
||||
end
|
||||
|
||||
if value.match?(/{{.+?}}/) && !key.end_with?("_MF")
|
||||
@errors[:invalid_interpolation_key_format] << key
|
||||
if value.match?(/{{.+?}}/) && !full_key.end_with?("_MF")
|
||||
@errors[:invalid_interpolation_key_format] << full_key
|
||||
end
|
||||
|
||||
if key.end_with?("_MF") && value.match?(/one {.*?1.*?}/)
|
||||
@errors[:invalid_message_format_one_key] << key
|
||||
if full_key.end_with?("_MF") && value.match?(/one {.*?1.*?}/)
|
||||
@errors[:invalid_message_format_one_key] << full_key
|
||||
end
|
||||
|
||||
if value.include?("%{count}") && !ENGLISH_KEYS.include?(last_key_part) &&
|
||||
COUNT_WITHOUT_PLURALIZATION_ALLOW_LIST.none? { |k| full_key.start_with?(k) }
|
||||
|
||||
@errors[:missing_pluralization] << full_key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user