diff --git a/app/assets/javascripts/admin/controllers/admin_user_controller.js b/app/assets/javascripts/admin/controllers/admin_user_controller.js
index 2565b8c8f59..cefbe0a3c61 100644
--- a/app/assets/javascripts/admin/controllers/admin_user_controller.js
+++ b/app/assets/javascripts/admin/controllers/admin_user_controller.js
@@ -6,4 +6,21 @@
@namespace Discourse
@module Discourse
**/
-Discourse.AdminUserController = Discourse.ObjectController.extend({});
\ No newline at end of file
+Discourse.AdminUserController = Discourse.ObjectController.extend({
+ editingTitle: false,
+
+ toggleTitleEdit: function() {
+ this.set('editingTitle', !this.editingTitle);
+ },
+
+ saveTitle: function() {
+ Discourse.ajax("/users/" + this.get('username').toLowerCase(), {
+ data: {title: this.get('title')},
+ type: 'PUT'
+ }).then(null, function(e){
+ bootbox.alert(Em.String.i18n("generic_error_with_reason", {error: "http: " + e.status + " - " + e.body}));
+ });
+
+ this.toggleTitleEdit();
+ }
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/user.js.handlebars b/app/assets/javascripts/admin/templates/user.js.handlebars
index 06e6591db06..fbad6ba1996 100644
--- a/app/assets/javascripts/admin/templates/user.js.handlebars
+++ b/app/assets/javascripts/admin/templates/user.js.handlebars
@@ -27,6 +27,25 @@
{{avatar content imageSize="large"}}
+
+
{{i18n user.title.title}}
+
+ {{#if editingTitle}}
+ {{textField value=title autofocus="autofocus"}}
+ {{else}}
+ {{title}}
+ {{/if}}
+
+
+ {{#if editingTitle}}
+
+
Cancel
+ {{else}}
+
+ {{/if}}
+
+
+
{{i18n user.ip_address.title}}
{{ip_address}}
diff --git a/app/assets/javascripts/discourse/templates/post.js.handlebars b/app/assets/javascripts/discourse/templates/post.js.handlebars
index 61e668397d0..b83ec83d531 100644
--- a/app/assets/javascripts/discourse/templates/post.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/post.js.handlebars
@@ -28,6 +28,7 @@
{{avatar this imageSize="large"}}
+ {{#if user_title}}
{{user_title}}
{{/if}}
diff --git a/app/assets/stylesheets/application/topic-post.css.scss b/app/assets/stylesheets/application/topic-post.css.scss
index dac676909fb..7484291812a 100644
--- a/app/assets/stylesheets/application/topic-post.css.scss
+++ b/app/assets/stylesheets/application/topic-post.css.scss
@@ -370,6 +370,16 @@
.score {
font-size: 12px;
}
+ .user-title {
+ font-size: 12px;
+ padding: 0 3px;
+ background-color: #ddd;
+ border-radius: 5px;
+ margin-top: 2px;
+ border: solid 1px #ccc;
+ font-weight: bold;
+ color: #555;
+ }
}
}
.reply-to-tab {
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 540ff2b1724..6c11b3faea3 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -48,6 +48,7 @@ class UsersController < ApplicationController
u.digest_after_days = params[:digest_after_days] || u.digest_after_days
u.auto_track_topics_after_msecs = params[:auto_track_topics_after_msecs].to_i if params[:auto_track_topics_after_msecs]
u.new_topic_duration_minutes = params[:new_topic_duration_minutes].to_i if params[:new_topic_duration_minutes]
+ u.title = params[:title] || u.title if guardian.can_grant_title?(u)
[:email_digests, :email_direct, :email_private_messages,
:external_links_in_new_tab, :enable_quoting, :dynamic_favicon].each do |i|
diff --git a/app/serializers/admin_user_serializer.rb b/app/serializers/admin_user_serializer.rb
index 8858f2bbde8..cb5860dfa7d 100644
--- a/app/serializers/admin_user_serializer.rb
+++ b/app/serializers/admin_user_serializer.rb
@@ -12,6 +12,7 @@ class AdminUserSerializer < BasicUserSerializer
:trust_level,
:flag_level,
:username,
+ :title,
:avatar_template,
:topics_entered,
:posts_read_count,
diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb
index c0c00479bcf..2270642c82d 100644
--- a/app/serializers/post_serializer.rb
+++ b/app/serializers/post_serializer.rb
@@ -33,6 +33,7 @@ class PostSerializer < ApplicationSerializer
:read,
:username,
:name,
+ :user_title,
:reply_to_user,
:bookmarked,
:raw,
@@ -128,6 +129,10 @@ class PostSerializer < ApplicationSerializer
object.user.name
end
+ def user_title
+ object.user.title
+ end
+
def trust_level
object.user.trust_level
end
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index e1224bcf2d0..598b67a03aa 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -14,7 +14,8 @@ class UserSerializer < BasicUserSerializer
:bio_excerpt,
:trust_level,
:moderator,
- :admin
+ :admin,
+ :title
has_one :invited_by, embed: :object, serializer: BasicUserSerializer
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 790c7b41b30..27217d6dbd0 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -78,6 +78,7 @@ en:
yes_value: "Yes"
of_value: "of"
generic_error: "Sorry, an error has occurred."
+ generic_error_with_reason: "An error occured: %{error}"
log_in: "Log In"
age: "Age"
last_post: "Last Post"
@@ -294,6 +295,8 @@ en:
avatar:
title: "Avatar"
instructions: "We use Gravatar for avatars based on your email"
+ title:
+ title: "Title"
filters:
all: "All"
@@ -1166,6 +1169,8 @@ en:
admin: "Admin?"
blocked: "Blocked?"
show_admin_profile: "Admin"
+ edit_title: "Edit Title"
+ save_title: "Save Title"
refresh_browsers: "Force browser refresh"
show_public_profile: "Show Public Profile"
impersonate: 'Impersonate'
diff --git a/db/migrate/20130625201113_add_title_to_users.rb b/db/migrate/20130625201113_add_title_to_users.rb
new file mode 100644
index 00000000000..8b921702a64
--- /dev/null
+++ b/db/migrate/20130625201113_add_title_to_users.rb
@@ -0,0 +1,5 @@
+class AddTitleToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :title, :string
+ end
+end
diff --git a/lib/guardian.rb b/lib/guardian.rb
index e5046d5fd60..ed49762376b 100644
--- a/lib/guardian.rb
+++ b/lib/guardian.rb
@@ -133,6 +133,10 @@ class Guardian
can_administer?(user) && not(user.moderator?)
end
+ def can_grant_title?(user)
+ user && is_staff?
+ end
+
def can_block_user?(user)
user && is_staff? && not(user.staff?)
end
diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb
index 05bc8b8b584..049a5966ea9 100644
--- a/spec/components/guardian_spec.rb
+++ b/spec/components/guardian_spec.rb
@@ -937,5 +937,27 @@ describe Guardian do
end
end
+ describe 'can_grant_title?' do
+ it 'is false without a logged in user' do
+ Guardian.new(nil).can_grant_title?(user).should be_false
+ end
+
+ it 'is false for regular users' do
+ Guardian.new(user).can_grant_title?(user).should be_false
+ end
+
+ it 'is true for moderators' do
+ Guardian.new(moderator).can_grant_title?(user).should be_true
+ end
+
+ it 'is true for admins' do
+ Guardian.new(admin).can_grant_title?(user).should be_true
+ end
+
+ it 'is false without a user to look at' do
+ Guardian.new(admin).can_grant_title?(nil).should be_false
+ end
+ end
+
end