diff --git a/app/assets/javascripts/admin/translations.js.erb b/app/assets/javascripts/admin/translations.js.erb index 2b6519bb79c..1bee607e2da 100644 --- a/app/assets/javascripts/admin/translations.js.erb +++ b/app/assets/javascripts/admin/translations.js.erb @@ -1,4 +1,4 @@ -//= depend_on 'en.yml' +//= depend_on 'client.en.yml' <% SimplesIdeias::I18n.assert_usable_configuration! %> <% admin = SimplesIdeias::I18n.translation_segments['app/assets/javascripts/i18n/admin.en.js'] diff --git a/app/assets/javascripts/discourse/components/div_resizer.js.coffee b/app/assets/javascripts/discourse/components/div_resizer.js.coffee index 0b4c3683343..a756b1c788b 100644 --- a/app/assets/javascripts/discourse/components/div_resizer.js.coffee +++ b/app/assets/javascripts/discourse/components/div_resizer.js.coffee @@ -31,14 +31,17 @@ lastMousePos = thisMousePos size = Math.min(size, $(window).height()) size = Math.max(min, size) - div.height size + "px" + + sizePx = size + "px" + opts.onDrag?(sizePx) + div.height(sizePx) endDrag e,opts if size < min false endDrag = (e,opts) -> $(document).unbind("mousemove", wrappedPerformDrag).unbind "mouseup", wrappedEndDrag div.removeClass('clear-transitions') div.focus() - opts.resize() if opts.resize + opts.resize?() div = null mousePosition = (e) -> x: e.clientX + document.documentElement.scrollLeft diff --git a/app/assets/javascripts/discourse/controllers/composer_controller.js.coffee b/app/assets/javascripts/discourse/controllers/composer_controller.js.coffee index 8d2d9aaf8e0..ee697f3c082 100644 --- a/app/assets/javascripts/discourse/controllers/composer_controller.js.coffee +++ b/app/assets/javascripts/discourse/controllers/composer_controller.js.coffee @@ -2,6 +2,8 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence needs: ['modal', 'topic'] + hasReply: false + togglePreview: -> @get('content').togglePreview() @@ -20,11 +22,19 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence .then (opts) => opts = opts || {} @close() + Discourse.set('currentUser.post_count', Discourse.get('currentUser.post_count') + 1) Discourse.routeTo(opts.post.get('url')) , (error) => composer.set('disableDrafts', false) bootbox.alert error + checkReplyLength: -> + if @present('content.reply') + @set('hasReply', true) + else + @set('hasReply', false) + + saveDraft: -> model = @get('content') model.saveDraft() if model @@ -40,6 +50,8 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence open: (opts={}) -> opts.promise = promise = opts.promise || new RSVP.Promise + @set('hasReply', false) + unless opts.draftKey alert("composer was opened without a draft key") throw "composer opened without a proper draft key" @@ -164,7 +176,7 @@ window.Discourse.ComposerController = Ember.Controller.extend Discourse.Presence # ESC key hit hitEsc: -> - @shrink() if @get('content.composeState') == @OPEN + @shrink() if @get('content.composeState') is Discourse.Composer.OPEN showOptions: -> diff --git a/app/assets/javascripts/discourse/templates/composer.js.handlebars b/app/assets/javascripts/discourse/templates/composer.js.handlebars index ebb64eaf74c..72e7e19239c 100644 --- a/app/assets/javascripts/discourse/templates/composer.js.handlebars +++ b/app/assets/javascripts/discourse/templates/composer.js.handlebars @@ -2,6 +2,12 @@
+
+ {{i18n ok}} + + {{{view.educationContents}}} +
+
diff --git a/app/assets/javascripts/discourse/translations.js.erb b/app/assets/javascripts/discourse/translations.js.erb index 3ace45233a8..4058b0eb838 100644 --- a/app/assets/javascripts/discourse/translations.js.erb +++ b/app/assets/javascripts/discourse/translations.js.erb @@ -1,4 +1,4 @@ -//= depend_on 'en.yml' +//= depend_on 'client.en.yml' <% SimplesIdeias::I18n.assert_usable_configuration! %> var I18n = I18n || {}; diff --git a/app/assets/javascripts/discourse/views/composer_view.js.coffee b/app/assets/javascripts/discourse/views/composer_view.js.coffee index 66638cb9444..c0897b575ce 100644 --- a/app/assets/javascripts/discourse/views/composer_view.js.coffee +++ b/app/assets/javascripts/discourse/views/composer_view.js.coffee @@ -10,6 +10,8 @@ window.Discourse.ComposerView = window.Discourse.View.extend 'content.showPreview', 'content.hidePreview'] + educationClosed: null + composeState: (-> state = @get('content.composeState') unless state @@ -49,28 +51,58 @@ window.Discourse.ComposerView = window.Discourse.View.extend if $wmdPreview.length > 0 $wmdPreview.scrollTop($wmdPreview[0].scrollHeight) - ).observes('content.reply', 'content.hidePreview') - willDestroyElement: -> - $('body').off 'keydown.composer' + closeEducation: -> + @set('educationClosed', true) + false + + fetchNewUserEducation: (-> + + if (Discourse.get('currentUser.post_count') >= Discourse.SiteSettings.educate_until_posts) + @set('educationClosed', true) + return + + return unless @get('controller.hasReply') + + @set('educationClosed', false) + + # If visible update the text + educationKey = if @get('content.creatingTopic') then 'new-topic' else 'new-reply' + $.get("/education/#{educationKey}").then (result) => @set('educationContents', result) + + ).observes('controller.hasReply', 'content.creatingTopic', 'Discourse.currentUser.post_count') + + newUserEducationVisible: (-> + return 'collapsed' unless @get('educationContents') + return 'collapsed' unless @get('content.composeState') is Discourse.Composer.OPEN + return 'collapsed' unless @present('content.reply') + return 'collapsed' if @get('educationClosed') + + return 'visible' + ).property('content.composeState', 'content.reply', 'educationClosed', 'educationContents') + + moveNewUserEducation: (sizePx) -> + $('#new-user-education').css('bottom', sizePx) resize: (-> # this still needs to wait on animations, need a clean way to do that Em.run.next null, => replyControl = $('#reply-control') h = replyControl.height() || 0 - $('.topic-area').css('padding-bottom', "#{h}px") + sizePx = "#{h}px" + $('.topic-area').css('padding-bottom', sizePx) + $('#new-user-education').css('bottom', sizePx) ).observes('content.composeState') + keyUp: (e) -> + controller = @get('controller') + controller.checkReplyLength() + controller.hitEsc() if e.which == 27 + didInsertElement: -> - - # Delegate ESC to the composer - $('body').on 'keydown.composer', (e) => - @get('controller').hitEsc() if e.which == 27 - replyControl = $('#reply-control') - replyControl.DivResizer(resize: @resize) + replyControl.DivResizer(resize: @resize, onDrag: @moveNewUserEducation) Discourse.TransitionHelper.after(replyControl, @resize) click: -> diff --git a/app/assets/stylesheets/application/compose.css.scss b/app/assets/stylesheets/application/compose.css.scss index 99c50848840..dd4a438a6db 100644 --- a/app/assets/stylesheets/application/compose.css.scss +++ b/app/assets/stylesheets/application/compose.css.scss @@ -3,6 +3,34 @@ @import "foundation/variables"; @import "foundation/mixins"; + +#new-user-education { + + &.collapsed { + max-height: 0; + visibility: hidden; + } + + &.visible { + max-height: 1000px; + visibility: visible; + } + + p { + margin: 0 0 10px 0; + } + + a.close { + float: right; + } + + background-color: lighten($yellow, 40%); + border: 1px solid $yellow; + padding: 10px; + width: 600px; + position: absolute; +} + #reply-control { .toggle-preview, .saving-draft { position: absolute; diff --git a/app/controllers/education_controller.rb b/app/controllers/education_controller.rb new file mode 100644 index 00000000000..66486c958cd --- /dev/null +++ b/app/controllers/education_controller.rb @@ -0,0 +1,17 @@ +class EducationController < ApplicationController + + before_filter :ensure_logged_in + + def show + raise Discourse::InvalidAccess.new unless params[:id] =~ /^[a-z0-9\-\_]+$/ + raise Discourse::NotFound.new unless I18n.t(:education).include?(params[:id].to_sym) + + education_posts_text = I18n.t('education.until_posts', count: SiteSetting.educate_until_posts) + + markdown_content = MultisiteI18n.t("education.#{params[:id]}", + site_name: SiteSetting.title, + education_posts_text: education_posts_text) + render text: PrettyText.cook(markdown_content) + end + +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 5f7b7a0efda..9607c2ece3c 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -116,6 +116,10 @@ class PostsController < ApplicationController render_serialized(post.replies, PostSerializer) end + # Returns the "you're creating a post education" + def education_text + + end def bookmark post = find_post_from_params diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 86ea8b2f6bf..87d2aaae759 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -138,6 +138,8 @@ class SiteSetting < ActiveRecord::Base setting(:new_user_period_days, 2) + client_setting(:educate_until_posts, 2) + def self.call_discourse_hub? self.enforce_global_nicknames? and self.discourse_org_access_key.present? end diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index c7496586567..018915d9d42 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -6,7 +6,8 @@ class CurrentUserSerializer < BasicUserSerializer :admin?, :notification_channel_position, :site_flagged_posts_count, - :moderator? + :moderator?, + :post_count # we probably want to move this into site, but that json is cached so hanging it off current user seems okish @@ -14,6 +15,10 @@ class CurrentUserSerializer < BasicUserSerializer object.admin end + def post_count + object.posts.count + end + def moderator? object.has_trust_level?(:moderator) end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml new file mode 100644 index 00000000000..07c4e2a7410 --- /dev/null +++ b/config/locales/client.en.yml @@ -0,0 +1,674 @@ +# This file contains content for the client portion of Discourse, sent out +# to the Javascript app. + +en: + js: + share: + topic: 'share a link to this topic' + post: 'share a link to this post' + + edit: 'edit the title and category of this topic' + not_implemented: "That feature hasn't been implemented yet, sorry!" + no_value: "No" + yes_value: "Yes" + of_value: "of" + generic_error: "Sorry, an error has occurred." + log_in: "Log In" + age: "Age" + last_post: "Last Post" + admin_title: "Admin" + flags_title: "Flags" + show_more: "show more" + links: Links + faq: "FAQ" + you: "You" + ok: "ok" + + suggested_topics: + title: "Suggested Topics" + + bookmarks: + not_logged_in: "Sorry you must be logged in to bookmark posts." + created: "You've bookmarked this post." + not_bookmarked: "You've read this post; click to bookmark it." + last_read: "This is the last post you've read." + + new_topics_inserted: "{{count}} new topics." + show_new_topics: "Click to show." + preview: "preview" + cancel: "cancel" + + save: "Save Changes" + saving: "Saving..." + saved: "Saved!" + + user_action_descriptions: + "6": "Responses" + + user: + information: "User Information" + profile: Profile + title: "User" + mute: Mute + edit: Edit Preferences + download_archive: "download archive of my posts" + private_message: "Private Message" + private_messages: "Messages" + activity_stream: "Activity" + preferences: "Preferences" + bio: "About me" + change_password: "change" + invited_by: "Invited By" + trust_level: "Trust Level" + + change_username: + action: "change" + title: "Change Username" + confirm: "There could be consequences to changing your username. Are you absolutely sure you want to?" + taken: "Sorry that username is taken." + error: "There was an error changing your username." + invalid: "That username is invalid. It must only include numbers and letters" + change_email: + action: 'change' + title: "Change Email" + taken: "Sorry that email is not available." + error: "There was an error changing your email. Perhaps that address is already in use?" + success: "We've sent an email to that address. Please follow the confirmation instructions." + + email: + title: "Email" + instructions: "Your email will never be shown to the public." + ok: "Looks good. We will email you to confirm." + invalid: "Please enter a valid email address." + authenticated: "Your email has been authenticated by {{provider}}." + frequency: "We'll only email you if we haven't seen you recently and you haven't already seen the thing we're emailing you about." + + name: + title: "Name" + instructions: "The longer version of your name; does not need to be unique." + too_short: "Your name is too short." + ok: "Your name looks good." + username: + title: "Username" + #instructions: "People can mention you as @{{username}}. This is an unregistered nickname. You can register it at discourse.org." + instructions: "People can mention you as @{{username}}." + available: "Your username is available." + global_match: "Email matches the registered username." + global_mismatch: "Already registered. Try {{suggestion}}?" + not_available: "Not available. Try {{suggestion}}?" + too_short: "Your username is too short." + too_long: "Your username is too long." + checking: "Checking username availability..." + enter_email: 'Username found. Enter matching email.' + + last_posted: "Last Post" + last_emailed: "Last Emailed" + last_seen: "Last Seen" + created: "Created At" + log_out: "Log Out" + website: "Web Site" + email_settings: "Email" + email_digests: + title: "When I don't visit the site, send me an email digest of what's new" + daily: "daily" + weekly: "weekly" + bi_weekly: "every two weeks" + + email_direct: "Receive an email when someone quotes you, replies to your post, or mentions your @username" + email_private_messages: "Receive an email when someone sends you a private message" + + other_settings: "Other" + + new_topic_duration: + label: "Consider topics new when" + not_viewed: "I haven't viewed them yet" + last_here: "they were posted since I was here last" + after_n_days: + one: "they were posted in the last day" + other: "they were posted in the last {{count}} days" + after_n_weeks: + one: "they were posted in the last week" + other: "they were posted in the last {{count}} week" + + auto_track_topics: "Automatically track topics I enter" + auto_track_options: + never: "never" + always: "always" + after_n_seconds: + one: "after 1 second" + other: "after {{count}} seconds" + after_n_minutes: + one: "after 1 minute" + other: "after {{count}} minutes" + + invited: + title: "Invites" + user: "Invited User" + none: "{{username}} hasn't invited any users to the site." + redeemed: "Redeemed Invites" + redeemed_at: "Redeemed At" + pending: "Pending Invites" + topics_entered: "Topics Entered" + posts_read_count: "Posts Read" + rescind: "Remove Invitation" + rescinded: "Invite removed" + time_read: "Read Time" + days_visited: "Days Visited" + account_age_days: "Account age in days" + + password: + title: "Password" + too_short: "Your password is too short." + ok: "Your password looks good." + + ip_address: + title: "Last IP Address" + avatar: + title: "Avatar" + instructions: "We use Gravatar for avatars based on your email" + + filters: + all: "All" + + loading: "Loading..." + close: "Close" + learn_more: "learn more..." + + year: 'year' + year_desc: 'topics posted in the last 365 days' + month: 'month' + month_desc: 'topics posted in the last 30 days' + week: 'week' + week_desc: 'topics posted in the last 7 days' + + first_post: First post + mute: Mute + unmute: Unmute + last_post: Last post + + best_of: + title: "Best Of" + description: "There are {{count}} posts in this topic. That's a lot! Would you like to save time by switching your view to show only the posts with the most interactions and responses?" + button: 'Switch to "Best Of" view' + + private_message_info: + title: "Private Conversation" + invite: "Invite Others..." + + email: 'Email' + username: 'Username' + last_seen: 'Last Seen' + created: 'Created' + trust_level: 'Trust Level' + + create_account: + title: "Create Account" + action: "Create one now!" + invite: "Don't have an account yet?" + failed: "Something went wrong, perhaps this email is already registered, try the forgot password link" + + forgot_password: + title: "Forgot Password" + action: "I forgot my password" + invite: "Enter your username or email address, and we'll send you a password reset email." + reset: "Reset Password" + complete: "You should receive an email with instructions on how to reset your password shortly." + + login: + title: "Log In" + username: "Login" + password: "Password" + email_placeholder: "email address or username" + error: "Unknown error" + reset_password: 'Reset Password' + logging_in: "Logging In..." + or: "Or" + authenticating: "Authenticating..." + awaiting_confirmation: "Your account is awaiting activation, use the forgot password link to issue another activation email." + awaiting_approval: "Your account has not been approved by a moderator yet. You will receive an email when it is approved." + google: + title: "Log In with Google" + message: "Authenticating with Google (make sure pop up blockers are not enabled)" + twitter: + title: "Log In with Twitter" + message: "Authenticating with Twitter (make sure pop up blockers are not enabled)" + facebook: + title: "Log In with Facebook" + message: "Authenticating with Facebook (make sure pop up blockers are not enabled)" + yahoo: + title: "Log In with Yahoo" + message: "Authenticating with Yahoo (make sure pop up blockers are not enabled)" + + composer: + saving_draft_tip: "saving" + saved_draft_tip: "saved" + saved_local_draft_tip: "saved locally" + + save_edit: "Save Edit" + reply: "Reply" + create_topic: "Create Topic" + create_pm: "Create Private Message" + + users_placeholder: "Add a user" + title_placeholder: "Type your title here. What is this discussion about in one brief sentence?" + reply_placeholder: "Type your reply here. Use Markdown or BBCode to format. Drag or paste an image here to upload it." + view_new_post: "View your new post." + saving: "Saving..." + saved: "Saved!" + saved_draft: "You have a post draft in progress. Click anywhere in this box to resume editing." + uploading: "Uploading..." + show_preview: 'show preview »' + hide_preview: '« hide preview' + + notifications: + title: "notifications of @name mentions, replies to your posts and topics, private messages, etc" + none: "You have no notifications right now." + more: "view older notifications" + mentioned: "{{username}} mentioned you in {{link}}" + quoted: "{{username}} quoted you in {{link}}" + replied: "{{username}} replied to you in {{link}}" + posted: "{{username}} replied to {{link}}" + edited: "{{username}} edited your post {{link}}" + liked: "{{username}} liked your post {{link}}" + private_message: "{{username}} sent you a private message: {{link}}" + invited_to_private_message: "{{username}} invited you to a private conversation: {{link}}" + invitee_accepted: "{{username}} accepted your invite and signed up to participate." + moved_post: "{{username}} moved your post to {{link}}" + + image_selector: + from_my_computer: "From My Device" + from_the_web: "From The Web" + add_image: "Add Image" + remote_tip: "enter address of an image in the form http://example.com/image.jpg" + local_tip: "click to select an image from your device." + upload: "Upload" + + search: + title: "search for topics, posts, users, or categories" + placeholder: "type your search terms here" + no_results: "No results found." + searching: "Searching ..." + + site_map: "go to another topic list or category" + go_back: 'go back' + current_user: 'go to your user page' + + favorite: + title: 'Favorite' + help: 'add this topic to your favorites list' + + topics: + no_favorited: "You haven't favorited any topics yet. To favorite a topic, click or tap the star next to the title." + no_unread: "You have no unread topics to read." + no_new: "You have no new topics to read." + no_read: "You haven't read any topics yet." + no_posted: "You haven't posted in any topics yet." + no_popular: "There are no popular topics. That's sad." + + topic: + create_in: 'Create {{categoryName}} Topic' + create: 'Create Topic' + create_long: 'Create a new Topic' + private_message: 'Start a private conversation' + list: 'Topics' + new: 'new topic' + title: 'Topic' + loading_more: "Loading more Topics..." + loading: 'Loading topic...' + missing: "Topic Not Found" + not_found: + title: "Topic Not Found" + description: "Sorry, we couldn't find that topic. Perhaps it has been deleted?" + unread_posts: "you have {{unread}} unread old posts in this topic" + new_posts: "there are {{new_posts}} new posts in this topic since you last read it" + likes: "there are {{likes}} likes in this topic" + back_to_list: "Back to Topic List" + options: "Topic Options" + show_links: "show links within this topic" + toggle_information: "toggle topic details" + read_more_in_category: "Want to read more? Browse other topics in {{catLink}} or {{popularLink}}." + read_more: "Want to read more? {{catLink}} or {{popularLink}}." + browse_all_categories: Browse all categories + view_popular_topics: view popular topics + + progress: + title: topic progress + jump_top: jump to first post + jump_bottom: jump to last post + total: total posts + current: current post + + notifications: + title: '' + reasons: + "3_2": 'You will receive notifications because you are watching this topic.' + "3_1": 'You will receive notifications because you created this topic.' + "2_4": 'You will receive notifications because you posted a reply to this topic.' + "2_2": 'You will receive notifications because you are tracking this topic.' + "2": 'You will receive notifications because you read this topic.' + "1": 'You will be notified only if someone mentions your @name or replies to your post.' + "1_2": 'You will be notified only if someone mentions your @name or replies to your post.' + "0": 'You are ignoring all notifications on this topic.' + "0_2": 'You are ignoring all notifications on this topic.' + watching: + title: "Watching" + description: "you will see unread and new post counts on this topic, plus notifications of @name mentions and all new posts." + tracking: + title: "Tracking" + description: "you will see unread and new post counts on this topic, plus notifications of @name mentions and replies to your posts." + regular: + title: "Regular" + description: "you will be notified only if someone mentions your @name or replies to your post." + muted: + title: "Muted" + description: "you will not be notified of anything about this topic, and it will not appear on your unread tab." + + actions: + delete: "Delete Topic" + open: "Open Topic" + close: "Close Topic" + unpin: "Un-Pin Topic" + pin: "Pin Topic" + unarchive: "Unarchive Topic" + archive: "Archive Topic" + invisible: "Make Invisible" + visible: "Make Visible" + reset_read: "Reset Read Data" + multi_select: "Toggle Multi-Select" + convert_to_topic: "Convert to Regular Topic" + + reply: + title: 'Reply' + help: 'begin composing a reply to this topic' + + share: + title: 'Share' + help: 'share a link to this topic' + + inviting: "Inviting..." + + invite_private: + title: 'Invite to Private Conversation' + email_or_username: "Invitee's Email or Username" + email_or_username_placeholder: "email address or username" + action: "Invite" + success: "Thanks! We've invited that user to participate in this private conversation." + error: "Sorry there was an error inviting that user." + + invite_reply: + title: 'Invite Friends to Reply' + help: 'send invitations to friends so they can reply to this topic with a single click' + email: "We'll send your friend a brief email allowing them to reply to this topic by clicking a link." + email_placeholder: 'email address' + success: "Thanks! We mailed out an invitation to {{email}}. We'll let you know when they redeem your invitation. Check the invitations tab on your user page to keep track of who you've invited." + error: "Sorry we couldn't invite that person. Perhaps they are already a user?" + + login_reply: 'Log In to Reply' + + filters: + user: "You're viewing only posts by specific user(s)." + best_of: "You're viewing only the 'Best Of' posts." + cancel: "Show all posts in this topic again." + + move_selected: + title: "Move Selected Posts" + topic_name: "New Topic Name:" + error: "Sorry, there was an error moving those posts." + instructions: + one: "You are about to create a new topic and populate it with the post you've selected." + other: "You are about to create a new topic and populate it with the {{count}} posts you've selected." + + multi_select: + select: 'select' + selected: 'selected ({{count}})' + delete: delete selected + cancel: cancel selecting + move: move selected + description: + one: You have selected 1 post. + other: "You have selected {{count}} posts." + + post: + reply: "Replying to {{link}} by {{replyAvatar}} {{username}}" + reply_topic: "Reply to {{link}}" + edit: "Edit {{link}}" + in_reply_to: "in reply to" + reply_as_new_topic: "Reply as new Topic" + continue_discussion: "Continuing the discussion from {{postLink}}:" + follow_quote: "go to the quoted post" + deleted_by_author: "(post removed by author)" + + has_replies: + one: "Reply" + other: "Replies" + + errors: + create: "Sorry, there was an error creating your post. Please try again." + edit: "Sorry, there was an error editing your post. Please try again." + upload: "Sorry, there was an error uploading that file. Please try again." + + abandon: "Are you sure you want to abandon your post?" + + archetypes: + save: 'Save Options' + + controls: + reply: "begin composing a reply to this post" + like: "like this post" + edit: "edit this post" + flag: "flag this post for moderator attention" + delete: "delete this post" + undelete: "undelete this post" + share: "share a link to this post" + bookmark: "bookmark this post to your user page" + more: "More" + + actions: + flag: 'Flag' + clear_flags: + one: "Clear flag" + other: "Clear flags" + it_too: "{{alsoName}} it too" + undo: "Undo {{alsoName}}" + by_you_and_others: + zero: "You {{long_form}}" + one: "You and 1 other person {{long_form}}" + other: "You and {{count}} other people {{long_form}}" + by_others: + one: "1 person {{long_form}}" + other: "{{count}} people {{long_form}}" + + edits: + one: 1 edit + other: "{{count}} edits" + zero: no edits + + delete: + confirm: + one: "Are you sure you want to delete that post?" + other: "Are you sure you want to delete all those posts?" + + category: + none: '(no category)' + edit: 'edit' + view: 'View Topics in Category' + delete: 'Delete Category' + create: 'Create Category' + more_posts: "view all {{posts}}..." + name: "Category Name" + description: "Description" + topic: "category topic" + color: "Color" + name_placeholder: "Should be short and succinct." + color_placeholder: "Any web color" + delete_confirm: "Are you sure you want to delete that category?" + list: "List Categories" + + flagging: + title: 'Why are you flagging this post?' + action: 'Flag Post' + cant: "Sorry, you can't flag this post at this time." + custom_placeholder: "Why does this post require moderator attention? Let us know specifically what you are concerned about, and provide relevant links where possible." + custom_message: + at_least: "enter at least {{n}} characters" + more: "{{n}} to go..." + left: "{{n}} remaining" + + topic_summary: + title: "Topic Summary" + links_shown: "show all {{totalLinks}} links..." + + topic_statuses: + locked: + help: "this topic is closed; it no longer accepts new replies" + pinned: + help: "this topic is pinned; it will display at the top of its category" + archived: + help: "this topic is archived; it is frozen and cannot be changed" + invisible: + help: "this topic is invisible; it will not be displayed in topic lists, and can only be accessed via a direct link" + + posts: "Posts" + posts_long: "{{number}} posts in this topic" + original_post: "Original Post" + views: "Views" + replies: "Replies" + views_long: "this topic has been viewed {{number}} times" + activity: "Activity" + likes: "Likes" + top_contributors: "Participants" + category_title: "Category" + + categories_list: "Categories List" + + filters: + popular: + title: "Popular" + help: "the most popular recent topics" + favorited: + title: "Favorited" + help: "topics you marked as favorites" + read: + title: "Read" + help: "topics you've read" + categories: + title: "Categories" + title_in: "Category - {{categoryName}}" + help: "all topics grouped by category" + unread: + title: + zero: "Unread" + one: "Unread (1)" + other: "Unread ({{count}})" + help: "tracked topics with unread posts" + new: + title: + zero: "New" + one: "New (1)" + other: "New ({{count}})" + help: "new topics since your last visit, and tracked topics with new posts" + posted: + title: "My Posts" + help: "topics you have posted in" + category: + title: + zero: "{{categoryName}}" + one: "{{categoryName}} (1)" + other: "{{categoryName}} ({{count}})" + help: "popular topics in the {{categoryName}} category" + + # This section is exported to the javascript for i18n in the admin section + admin_js: + type_to_filter: "type to filter..." + + admin: + title: 'Discourse Admin' + dashboard: 'Admin Dashboard' + + flags: + title: "Flags" + old: "Old" + active: "Active" + clear: "Clear Flags" + clear_title: "dismiss all flags on this post (will unhide hidden posts)" + delete: "Delete Post" + delete_title: "delete post (if its the first post delete topic)" + + customize: + title: "Customize" + header: "Header" + css: "Stylesheet" + override_default: "Override default?" + enabled: "Enabled?" + preview: "preview" + undo_preview: "undo preview" + save: "Save" + delete: "Delete" + delete_confirm: "Delete this customization?" + + email_logs: + title: "Email Logs" + sent_at: "Sent At" + email_type: "Email Type" + to_address: "To Address" + test_email_address: "email address to test" + send_test: "send test email" + sent_test: "sent!" + + impersonate: + title: "Impersonate User" + username_or_email: "Username or Email of User" + help: "Use this tool to impersonate a user account for debugging purposes." + not_found: "That user can't be found." + invalid: "Sorry, you may not impersonate that user." + + users: + title: 'Users' + create: 'Add Admin User' + last_emailed: "Last Emailed" + not_found: "Sorry that username doesn't exist in our system." + new: "New" + active: "Active" + pending: "Pending" + approved: "Approved?" + approved_selected: + one: "approve user" + other: "approve users ({{count}})" + + user: + ban_failed: "Something went wrong banning this user {{error}}" + unban_failed: "Something went wrong unbanning this user {{error}}" + ban_duration: "How long would you like to ban the user for? (days)" + delete_all_posts: "Delete all posts" + ban: "Ban" + unban: "Unban" + banned: "Banned?" + moderator: "Moderator?" + admin: "Admin?" + show_admin_profile: "Admin" + refresh_browsers: "Force browser refresh" + show_public_profile: "Show Public Profile" + impersonate: 'Impersonate' + revoke_admin: 'Revoke Admin' + grant_admin: 'Grant Admin' + revoke_moderation: 'Revoke Moderation' + grant_moderation: 'Grant Moderation' + basics: Basics + reputation: Reputation + permissions: Permissions + activity: Activity + like_count: Likes Received + private_topics_count: Private Topics Count + posts_read_count: Posts Read + post_count: Posts Created + topics_entered: Topics Entered + flags_given_count: Flags Given + flags_received_count: Flags Received + approve: 'Approve' + approved_by: "approved by" + time_read: "Read Time" + + site_settings: + show_overriden: 'Only show overridden' + title: 'Site Settings' + reset: 'reset to default' \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/server.en.yml similarity index 54% rename from config/locales/en.yml rename to config/locales/server.en.yml index 0204b103102..f3d9b496d69 100644 --- a/config/locales/en.yml +++ b/config/locales/server.en.yml @@ -11,6 +11,38 @@ en: invalid_characters: "contains invalid characters" is_invalid: "is invalid; try to be a little more descriptive" + education: + until_posts: + one: "post" + other: "%{count} posts" + + 'new-topic': | + Welcome to %{site_name} and thanks for contributing to the conversation! + + Here are a few things to keep in mind as you compose your topic: + + - Does the title adequately describe what someone could reasonably expect to find if they opened your topic? + + - The first post defines your topic: What is this about? Who would be interested in it? Why does it matter? What kind of responses are you hoping for? + + - Try to use the right words so people can *find* your topic. If it needs to be in a category, pick an appropriate category. + + For more guidance, [see our FAQ](/faq). This panel will only appear for your first %{education_posts_text}. + + 'new-reply': | + Welcome to %{site_name} and thanks for contributing to the conversation! + + Here are a few things to keep in mind as you compose your reply: + + - Does your reply improve the conversation in some way, however small? + + - Treat your fellow posters with the same respect you'd wish to be treated. + + - It's fine to be critical, but remember to criticize *ideas*, not people. + + For more guidance, [see our FAQ](/faq). This panel will only appear for your first %{education_posts_text}. + + activerecord: attributes: category: @@ -150,7 +182,6 @@ en: approval_required: "A moderator must manually approve your new account before you can access this forum. You'll get an email when your account is approved!" post_action_types: - off_topic: title: 'Off-Topic' description: 'This post is radically off-topic in the current conversation, and should probably be moved to a different topic.' @@ -205,7 +236,7 @@ en: unique_posts_mins: "How many minutes before a user can make a post with the same content again" enforce_global_nicknames: "Enforce global nickname uniqueness. Note: Only change during initial setup." discourse_org_access_key: "The access key used to access the discourse.org nickname registry" - + educate_until_posts: "Show education until the user has made this many posts" title: "title of this website" secret_token: "secret token used to secure cookies" restrict_access: "restrict forum access unless this password is entered" @@ -316,102 +347,6 @@ en: new_user_period_days: "How long a user is highlighted as being new, in days." - # This section is exported to the javascript for i18n in the admin section - admin_js: - type_to_filter: "type to filter..." - - admin: - title: 'Discourse Admin' - dashboard: 'Admin Dashboard' - - flags: - title: "Flags" - old: "Old" - active: "Active" - clear: "Clear Flags" - clear_title: "dismiss all flags on this post (will unhide hidden posts)" - delete: "Delete Post" - delete_title: "delete post (if its the first post delete topic)" - - customize: - title: "Customize" - header: "Header" - css: "Stylesheet" - override_default: "Override default?" - enabled: "Enabled?" - preview: "preview" - undo_preview: "undo preview" - save: "Save" - delete: "Delete" - delete_confirm: "Delete this customization?" - - email_logs: - title: "Email Logs" - sent_at: "Sent At" - email_type: "Email Type" - to_address: "To Address" - test_email_address: "email address to test" - send_test: "send test email" - sent_test: "sent!" - - impersonate: - title: "Impersonate User" - username_or_email: "Username or Email of User" - help: "Use this tool to impersonate a user account for debugging purposes." - not_found: "That user can't be found." - invalid: "Sorry, you may not impersonate that user." - - users: - title: 'Users' - create: 'Add Admin User' - last_emailed: "Last Emailed" - not_found: "Sorry that username doesn't exist in our system." - new: "New" - active: "Active" - pending: "Pending" - approved: "Approved?" - approved_selected: - one: "approve user" - other: "approve users ({{count}})" - - user: - ban_failed: "Something went wrong banning this user {{error}}" - unban_failed: "Something went wrong unbanning this user {{error}}" - ban_duration: "How long would you like to ban the user for? (days)" - delete_all_posts: "Delete all posts" - ban: "Ban" - unban: "Unban" - banned: "Banned?" - moderator: "Moderator?" - admin: "Admin?" - show_admin_profile: "Admin" - refresh_browsers: "Force browser refresh" - show_public_profile: "Show Public Profile" - impersonate: 'Impersonate' - revoke_admin: 'Revoke Admin' - grant_admin: 'Grant Admin' - revoke_moderation: 'Revoke Moderation' - grant_moderation: 'Grant Moderation' - basics: Basics - reputation: Reputation - permissions: Permissions - activity: Activity - like_count: Likes Received - private_topics_count: Private Topics Count - posts_read_count: Posts Read - post_count: Posts Created - topics_entered: Topics Entered - flags_given_count: Flags Given - flags_received_count: Flags Received - approve: 'Approve' - approved_by: "approved by" - time_read: "Read Time" - - site_settings: - show_overriden: 'Only show overridden' - title: 'Site Settings' - reset: 'reset to default' - notification_types: mentioned: "%{display_username} mentioned you in %{link}" liked: "%{display_username} liked your post in %{link}" @@ -424,580 +359,6 @@ en: invited_to_private_message: "%{display_username} invited you to a private message: %{link}" invitee_accepted: "%{display_username} accepted your invitation" - # This section is exported to the javascript for i18n - js: - share: - topic: 'share a link to this topic' - post: 'share a link to this post' - - edit: 'edit the title and category of this topic' - not_implemented: "That feature hasn't been implemented yet, sorry!" - no_value: "No" - yes_value: "Yes" - of_value: "of" - generic_error: "Sorry, an error has occurred." - log_in: "Log In" - age: "Age" - last_post: "Last Post" - admin_title: "Admin" - flags_title: "Flags" - show_more: "show more" - links: Links - faq: "FAQ" - you: "You" - - suggested_topics: - title: "Suggested Topics" - - bookmarks: - not_logged_in: "Sorry you must be logged in to bookmark posts." - created: "You've bookmarked this post." - not_bookmarked: "You've read this post; click to bookmark it." - last_read: "This is the last post you've read." - - new_topics_inserted: "{{count}} new topics." - show_new_topics: "Click to show." - preview: "preview" - cancel: "cancel" - - save: "Save Changes" - saving: "Saving..." - saved: "Saved!" - - user_action_descriptions: - "6": "Responses" - user: - information: "User Information" - profile: Profile - title: "User" - mute: Mute - edit: Edit Preferences - download_archive: "download archive of my posts" - private_message: "Private Message" - private_messages: "Messages" - activity_stream: "Activity" - preferences: "Preferences" - bio: "About me" - change_password: "change" - invited_by: "Invited By" - trust_level: "Trust Level" - - change_username: - action: "change" - title: "Change Username" - confirm: "There could be consequences to changing your username. Are you absolutely sure you want to?" - taken: "Sorry that username is taken." - error: "There was an error changing your username." - invalid: "That username is invalid. It must only include numbers and letters" - change_email: - action: 'change' - title: "Change Email" - taken: "Sorry that email is not available." - error: "There was an error changing your email. Perhaps that address is already in use?" - success: "We've sent an email to that address. Please follow the confirmation instructions." - - email: - title: "Email" - instructions: "Your email will never be shown to the public." - ok: "Looks good. We will email you to confirm." - invalid: "Please enter a valid email address." - authenticated: "Your email has been authenticated by {{provider}}." - frequency: "We'll only email you if we haven't seen you recently and you haven't already seen the thing we're emailing you about." - - name: - title: "Name" - instructions: "The longer version of your name; does not need to be unique." - too_short: "Your name is too short." - ok: "Your name looks good." - username: - title: "Username" - #instructions: "People can mention you as @{{username}}. This is an unregistered nickname. You can register it at discourse.org." - instructions: "People can mention you as @{{username}}." - available: "Your username is available." - global_match: "Email matches the registered username." - global_mismatch: "Already registered. Try {{suggestion}}?" - not_available: "Not available. Try {{suggestion}}?" - too_short: "Your username is too short." - too_long: "Your username is too long." - checking: "Checking username availability..." - enter_email: 'Username found. Enter matching email.' - - last_posted: "Last Post" - last_emailed: "Last Emailed" - last_seen: "Last Seen" - created: "Created At" - log_out: "Log Out" - website: "Web Site" - email_settings: "Email" - email_digests: - title: "When I don't visit the site, send me an email digest of what's new" - daily: "daily" - weekly: "weekly" - bi_weekly: "every two weeks" - - email_direct: "Receive an email when someone quotes you, replies to your post, or mentions your @username" - email_private_messages: "Receive an email when someone sends you a private message" - - other_settings: "Other" - - new_topic_duration: - label: "Consider topics new when" - not_viewed: "I haven't viewed them yet" - last_here: "they were posted since I was here last" - after_n_days: - one: "they were posted in the last day" - other: "they were posted in the last {{count}} days" - after_n_weeks: - one: "they were posted in the last week" - other: "they were posted in the last {{count}} week" - - auto_track_topics: "Automatically track topics I enter" - auto_track_options: - never: "never" - always: "always" - after_n_seconds: - one: "after 1 second" - other: "after {{count}} seconds" - after_n_minutes: - one: "after 1 minute" - other: "after {{count}} minutes" - - invited: - title: "Invites" - user: "Invited User" - none: "{{username}} hasn't invited any users to the site." - redeemed: "Redeemed Invites" - redeemed_at: "Redeemed At" - pending: "Pending Invites" - topics_entered: "Topics Entered" - posts_read_count: "Posts Read" - rescind: "Remove Invitation" - rescinded: "Invite removed" - time_read: "Read Time" - days_visited: "Days Visited" - account_age_days: "Account age in days" - - password: - title: "Password" - too_short: "Your password is too short." - ok: "Your password looks good." - - ip_address: - title: "Last IP Address" - avatar: - title: "Avatar" - instructions: "We use Gravatar for avatars based on your email" - - filters: - all: "All" - - loading: "Loading..." - close: "Close" - learn_more: "learn more..." - - year: 'year' - year_desc: 'topics posted in the last 365 days' - month: 'month' - month_desc: 'topics posted in the last 30 days' - week: 'week' - week_desc: 'topics posted in the last 7 days' - - first_post: First post - mute: Mute - unmute: Unmute - last_post: Last post - - best_of: - title: "Best Of" - description: "There are {{count}} posts in this topic. That's a lot! Would you like to save time by switching your view to show only the posts with the most interactions and responses?" - button: 'Switch to "Best Of" view' - - private_message_info: - title: "Private Conversation" - invite: "Invite Others..." - - email: 'Email' - username: 'Username' - last_seen: 'Last Seen' - created: 'Created' - trust_level: 'Trust Level' - - create_account: - title: "Create Account" - action: "Create one now!" - invite: "Don't have an account yet?" - failed: "Something went wrong, perhaps this email is already registered, try the forgot password link" - - forgot_password: - title: "Forgot Password" - action: "I forgot my password" - invite: "Enter your username or email address, and we'll send you a password reset email." - reset: "Reset Password" - complete: "You should receive an email with instructions on how to reset your password shortly." - - login: - title: "Log In" - username: "Login" - password: "Password" - email_placeholder: "email address or username" - error: "Unknown error" - reset_password: 'Reset Password' - logging_in: "Logging In..." - or: "Or" - authenticating: "Authenticating..." - awaiting_confirmation: "Your account is awaiting activation, use the forgot password link to issue another activation email." - awaiting_approval: "Your account has not been approved by a moderator yet. You will receive an email when it is approved." - google: - title: "Log In with Google" - message: "Authenticating with Google (make sure pop up blockers are not enabled)" - twitter: - title: "Log In with Twitter" - message: "Authenticating with Twitter (make sure pop up blockers are not enabled)" - facebook: - title: "Log In with Facebook" - message: "Authenticating with Facebook (make sure pop up blockers are not enabled)" - yahoo: - title: "Log In with Yahoo" - message: "Authenticating with Yahoo (make sure pop up blockers are not enabled)" - - composer: - saving_draft_tip: "saving" - saved_draft_tip: "saved" - saved_local_draft_tip: "saved locally" - - save_edit: "Save Edit" - reply: "Reply" - create_topic: "Create Topic" - create_pm: "Create Private Message" - - users_placeholder: "Add a user" - title_placeholder: "Type your title here. What is this discussion about in one brief sentence?" - reply_placeholder: "Type your reply here. Use Markdown or BBCode to format. Drag or paste an image here to upload it." - view_new_post: "View your new post." - saving: "Saving..." - saved: "Saved!" - saved_draft: "You have a post draft in progress. Click anywhere in this box to resume editing." - uploading: "Uploading..." - show_preview: 'show preview »' - hide_preview: '« hide preview' - - notifications: - title: "notifications of @name mentions, replies to your posts and topics, private messages, etc" - none: "You have no notifications right now." - more: "view older notifications" - mentioned: "{{username}} mentioned you in {{link}}" - quoted: "{{username}} quoted you in {{link}}" - replied: "{{username}} replied to you in {{link}}" - posted: "{{username}} replied to {{link}}" - edited: "{{username}} edited your post {{link}}" - liked: "{{username}} liked your post {{link}}" - private_message: "{{username}} sent you a private message: {{link}}" - invited_to_private_message: "{{username}} invited you to a private conversation: {{link}}" - invitee_accepted: "{{username}} accepted your invite and signed up to participate." - moved_post: "{{username}} moved your post to {{link}}" - - image_selector: - from_my_computer: "From My Device" - from_the_web: "From The Web" - add_image: "Add Image" - remote_tip: "enter address of an image in the form http://example.com/image.jpg" - local_tip: "click to select an image from your device." - upload: "Upload" - - search: - title: "search for topics, posts, users, or categories" - placeholder: "type your search terms here" - no_results: "No results found." - searching: "Searching ..." - - site_map: "go to another topic list or category" - go_back: 'go back' - current_user: 'go to your user page' - - favorite: - title: 'Favorite' - help: 'add this topic to your favorites list' - - topics: - no_favorited: "You haven't favorited any topics yet. To favorite a topic, click or tap the star next to the title." - no_unread: "You have no unread topics to read." - no_new: "You have no new topics to read." - no_read: "You haven't read any topics yet." - no_posted: "You haven't posted in any topics yet." - no_popular: "There are no popular topics. That's sad." - - topic: - create_in: 'Create {{categoryName}} Topic' - create: 'Create Topic' - create_long: 'Create a new Topic' - private_message: 'Start a private conversation' - list: 'Topics' - new: 'new topic' - title: 'Topic' - loading_more: "Loading more Topics..." - loading: 'Loading topic...' - missing: "Topic Not Found" - not_found: - title: "Topic Not Found" - description: "Sorry, we couldn't find that topic. Perhaps it has been deleted?" - unread_posts: "you have {{unread}} old unread posts in this topic" - new_posts: "there are {{new_posts}} new posts in this topic since you last read it" - likes: "there are {{likes}} likes in this topic" - back_to_list: "Back to Topic List" - options: "Topic Options" - show_links: "show links within this topic" - toggle_information: "toggle topic details" - read_more_in_category: "Want to read more? Browse other topics in {{catLink}} or {{popularLink}}." - read_more: "Want to read more? {{catLink}} or {{popularLink}}." - browse_all_categories: Browse all categories - view_popular_topics: view popular topics - - progress: - title: topic progress - jump_top: jump to first post - jump_bottom: jump to last post - total: total posts - current: current post - - notifications: - title: '' - reasons: - "3_2": 'You will receive notifications because you are watching this topic.' - "3_1": 'You will receive notifications because you created this topic.' - "2_4": 'You will receive notifications because you posted a reply to this topic.' - "2_2": 'You will receive notifications because you are tracking this topic.' - "2": 'You will receive notifications because you read this topic.' - "1": 'You will be notified only if someone mentions your @name or replies to your post.' - "1_2": 'You will be notified only if someone mentions your @name or replies to your post.' - "0": 'You are ignoring all notifications on this topic.' - "0_2": 'You are ignoring all notifications on this topic.' - watching: - title: "Watching" - description: "you will see unread and new post counts on this topic, plus notifications of @name mentions and all new posts." - tracking: - title: "Tracking" - description: "you will see unread and new post counts on this topic, plus notifications of @name mentions and replies to your posts." - regular: - title: "Regular" - description: "you will be notified only if someone mentions your @name or replies to your post." - muted: - title: "Muted" - description: "you will not be notified of anything about this topic, and it will not appear on your unread tab." - - actions: - delete: "Delete Topic" - open: "Open Topic" - close: "Close Topic" - unpin: "Un-Pin Topic" - pin: "Pin Topic" - unarchive: "Unarchive Topic" - archive: "Archive Topic" - invisible: "Make Invisible" - visible: "Make Visible" - reset_read: "Reset Read Data" - multi_select: "Toggle Multi-Select" - convert_to_topic: "Convert to Regular Topic" - - reply: - title: 'Reply' - help: 'begin composing a reply to this topic' - - share: - title: 'Share' - help: 'share a link to this topic' - - inviting: "Inviting..." - - invite_private: - title: 'Invite to Private Conversation' - email_or_username: "Invitee's Email or Username" - email_or_username_placeholder: "email address or username" - action: "Invite" - success: "Thanks! We've invited that user to participate in this private conversation." - error: "Sorry there was an error inviting that user." - - invite_reply: - title: 'Invite Friends to Reply' - help: 'send invitations to friends so they can reply to this topic with a single click' - email: "We'll send your friend a brief email allowing them to reply to this topic by clicking a link." - email_placeholder: 'email address' - success: "Thanks! We mailed out an invitation to {{email}}. We'll let you know when they redeem your invitation. Check the invitations tab on your user page to keep track of who you've invited." - error: "Sorry we couldn't invite that person. Perhaps they are already a user?" - - login_reply: 'Log In to Reply' - - filters: - user: "You're viewing only posts by specific user(s)." - best_of: "You're viewing only the 'Best Of' posts." - cancel: "Show all posts in this topic again." - - move_selected: - title: "Move Selected Posts" - topic_name: "New Topic Name:" - error: "Sorry, there was an error moving those posts." - instructions: - one: "You are about to create a new topic and populate it with the post you've selected." - other: "You are about to create a new topic and populate it with the {{count}} posts you've selected." - - multi_select: - select: 'select' - selected: 'selected ({{count}})' - delete: delete selected - cancel: cancel selecting - move: move selected - description: - one: You have selected 1 post. - other: "You have selected {{count}} posts." - - post: - reply: "Replying to {{link}} by {{replyAvatar}} {{username}}" - reply_topic: "Reply to {{link}}" - edit: "Edit {{link}}" - in_reply_to: "in reply to" - reply_as_new_topic: "Reply as new Topic" - continue_discussion: "Continuing the discussion from {{postLink}}:" - follow_quote: "go to the quoted post" - deleted_by_author: "(post removed by author)" - - has_replies: - one: "Reply" - other: "Replies" - - errors: - create: "Sorry, there was an error creating your post. Please try again." - edit: "Sorry, there was an error editing your post. Please try again." - upload: "Sorry, there was an error uploading that file. Please try again." - - abandon: "Are you sure you want to abandon your post?" - - archetypes: - save: 'Save Options' - - controls: - reply: "begin composing a reply to this post" - like: "like this post" - edit: "edit this post" - flag: "flag this post for moderator attention" - delete: "delete this post" - undelete: "undelete this post" - share: "share a link to this post" - bookmark: "bookmark this post to your user page" - more: "More" - - actions: - flag: 'Flag' - clear_flags: - one: "Clear flag" - other: "Clear flags" - it_too: "{{alsoName}} it too" - undo: "Undo {{alsoName}}" - by_you_and_others: - zero: "You {{long_form}}" - one: "You and 1 other person {{long_form}}" - other: "You and {{count}} other people {{long_form}}" - by_others: - one: "1 person {{long_form}}" - other: "{{count}} people {{long_form}}" - - edits: - one: 1 edit - other: "{{count}} edits" - zero: no edits - - delete: - confirm: - one: "Are you sure you want to delete that post?" - other: "Are you sure you want to delete all those posts?" - - category: - none: '(no category)' - edit: 'edit' - view: 'View Topics in Category' - delete: 'Delete Category' - create: 'Create Category' - more_posts: "view all {{posts}}..." - name: "Category Name" - description: "Description" - topic: "category topic" - color: "Color" - name_placeholder: "Should be short and succinct." - color_placeholder: "Any web color" - delete_confirm: "Are you sure you want to delete that category?" - list: "List Categories" - - flagging: - title: 'Why are you flagging this post?' - action: 'Flag Post' - cant: "Sorry, you can't flag this post at this time." - custom_placeholder: "Why does this post require moderator attention? Let us know specifically what you are concerned about, and provide relevant links where possible." - custom_message: - at_least: "enter at least {{n}} characters" - more: "{{n}} to go..." - left: "{{n}} remaining" - - topic_summary: - title: "Topic Summary" - links_shown: "show all {{totalLinks}} links..." - - topic_statuses: - locked: - help: "this topic is closed; it no longer accepts new replies" - pinned: - help: "this topic is pinned; it will display at the top of its category" - archived: - help: "this topic is archived; it is frozen and cannot be changed" - invisible: - help: "this topic is invisible; it will not be displayed in topic lists, and can only be accessed via a direct link" - - posts: "Posts" - posts_long: "{{number}} posts in this topic" - original_post: "Original Post" - views: "Views" - replies: "Replies" - views_long: "this topic has been viewed {{number}} times" - activity: "Activity" - likes: "Likes" - top_contributors: "Participants" - category_title: "Category" - - categories_list: "Categories List" - - filters: - popular: - title: "Popular" - help: "the most popular recent topics" - favorited: - title: "Favorited" - help: "topics you marked as favorites" - read: - title: "Read" - help: "topics you've read" - categories: - title: "Categories" - title_in: "Category - {{categoryName}}" - help: "all topics grouped by category" - unread: - title: - zero: "Unread" - one: "Unread (1)" - other: "Unread ({{count}})" - help: "tracked topics with unread posts" - new: - title: - zero: "New" - one: "New (1)" - other: "New ({{count}})" - help: "new topics since your last visit, and tracked topics with new posts" - posted: - title: "My Posts" - help: "topics you have posted in" - category: - title: - zero: "{{categoryName}}" - one: "{{categoryName}} (1)" - other: "{{categoryName}} ({{count}})" - help: "popular topics in the {{categoryName}} category" - search: types: category: 'Categories' diff --git a/config/routes.rb b/config/routes.rb index 855654b7279..fc9c63cdf93 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -137,6 +137,7 @@ Discourse::Application.routes.draw do end end resources :user_actions + resources :education get 'category/:category' => 'list#category' get 'popular' => 'list#index' diff --git a/spec/controllers/education_controller_spec.rb b/spec/controllers/education_controller_spec.rb new file mode 100644 index 00000000000..4593979a0e5 --- /dev/null +++ b/spec/controllers/education_controller_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe EducationController do + + it "requires you to be logged in" do + lambda { xhr :get, :show, id: 'topic' }.should raise_error(Discourse::NotLoggedIn) + end + + context 'when logged in' do + + let!(:user) { log_in(:user) } + + it "returns 404 from a missing id" do + xhr :get, :show, id: 'made-up' + response.response_code.should == 404 + end + + it 'raises an error with a weird id' do + xhr :get, :show, id: '../some-path' + response.should_not be_success + end + + context 'with a valid id' do + + let(:markdown_content) { "Education *markdown* content" } + let(:html_content) {"HTML Content"} + + before do + MultisiteI18n.expects(:t).with("education.new-topic", anything).returns(markdown_content) + PrettyText.expects(:cook).with(markdown_content).returns(html_content) + xhr :get, :show, id: 'new-topic' + end + + it "succeeds" do + response.should be_success + end + + it "converts markdown into HTML" do + response.body.should == html_content + end + + end + + end + +end