tamed_beast 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/README +12 -0
- data/Rakefile +2 -0
- data/app/controllers/forums_controller.rb +60 -0
- data/app/controllers/posts_controller.rb +98 -0
- data/app/controllers/topics_controller.rb +94 -0
- data/app/models/forum.rb +23 -0
- data/app/models/post.rb +26 -0
- data/app/models/topic.rb +97 -0
- data/app/views/forums/_form.html.erb +21 -0
- data/app/views/forums/edit.html.erb +12 -0
- data/app/views/forums/index.html.erb +63 -0
- data/app/views/forums/new.html.erb +10 -0
- data/app/views/forums/show.html.erb +81 -0
- data/app/views/posts/_edit.html.erb +38 -0
- data/app/views/posts/edit.html.erb +14 -0
- data/app/views/posts/index.html.erb +1 -0
- data/app/views/topics/_form.html.erb +17 -0
- data/app/views/topics/edit.html.erb +10 -0
- data/app/views/topics/index.html.erb +2 -0
- data/app/views/topics/new.html.erb +18 -0
- data/app/views/topics/show.html.erb +175 -0
- data/config/conf.rb +0 -0
- data/lib/generators/tamed_beast/install_generator.rb +56 -0
- data/lib/generators/tamed_beast/migration_generator.rb +26 -0
- data/lib/generators/tamed_beast/templates/migration.rb +57 -0
- data/lib/generators/tamed_beast/templates/routes.rb +9 -0
- data/lib/tamed_beast.rb +7 -0
- data/lib/tamed_beast/application_helper.rb +18 -0
- data/lib/tamed_beast/auth.rb +24 -0
- data/lib/tamed_beast/engine.rb +7 -0
- data/lib/tamed_beast/version.rb +3 -0
- data/tamed_beast.gemspec +23 -0
- data/test/fixtures/forums.yml +19 -0
- data/test/fixtures/posts.yml +34 -0
- data/test/fixtures/topics.yml +29 -0
- data/test/fixtures/users.yml +9 -0
- data/test/functional/forums_controller_test.rb +51 -0
- data/test/functional/posts_controller_test.rb +54 -0
- data/test/functional/topics_controller_test.rb +55 -0
- data/test/unit/forum_test.rb +10 -0
- data/test/unit/post_test.rb +32 -0
- data/test/unit/topic_test.rb +33 -0
- data/vendor/plugins/white_list/README +29 -0
- data/vendor/plugins/white_list/Rakefile +22 -0
- data/vendor/plugins/white_list/init.rb +2 -0
- data/vendor/plugins/white_list/lib/white_list_helper.rb +97 -0
- data/vendor/plugins/white_list/test/white_list_test.rb +132 -0
- data/vendor/plugins/white_list_formatted_content/init.rb +27 -0
- metadata +161 -0
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Welcome to Tamed Beast!
|
2
|
+
|
3
|
+
Tamed beast is an attempt to tame savage_beast under Rails3. We worked with savage_beast under rails 2.x, but we find ourselves less than comfortable using it...
|
4
|
+
And it came the day to migrate to Rails3 and - hey - how do we migrate savage_beast to Rails3? What about all our posts and forums?
|
5
|
+
Damn.
|
6
|
+
So we started writing our own bulletin board solution, trying to be compatible with the savage_beast data model.
|
7
|
+
|
8
|
+
TODO:
|
9
|
+
* Add moderators / manage moderatorship roles
|
10
|
+
* Add views
|
11
|
+
* Add search feature
|
12
|
+
* Improve tests
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
class ForumsController < ApplicationController
|
2
|
+
before_filter :login_required, :except => [:index, :show]
|
3
|
+
before_filter :find_or_initialize_forum, :except => :index
|
4
|
+
|
5
|
+
#before_filter :admin?, :except => [:show, :index]
|
6
|
+
|
7
|
+
def index
|
8
|
+
@forums = Forum.order('position')
|
9
|
+
# reset the page of each forum we have visited when we go back to index
|
10
|
+
session[:forum_page] = nil
|
11
|
+
respond_to do |format|
|
12
|
+
format.html
|
13
|
+
format.xml { render :xml => @forums }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
respond_to do |format|
|
19
|
+
format.html do
|
20
|
+
# keep track of when we last viewed this forum for activity indicators
|
21
|
+
(session[:forums] ||= {})[@forum.id] = Time.now.utc if !current_user.nil?
|
22
|
+
(session[:forum_page] ||= Hash.new(1))[@forum.id] = params[:page].to_i if params[:page]
|
23
|
+
|
24
|
+
@topics = @forum.topics.paginate :page => params[:page]
|
25
|
+
User.find(:all, :conditions => ['id IN (?)', @topics.collect { |t| t.replied_by }.uniq]) unless @topics.blank?
|
26
|
+
end
|
27
|
+
format.xml { render :xml => @forum }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
@forum.attributes = params[:forum]
|
33
|
+
@forum.save!
|
34
|
+
respond_to do |format|
|
35
|
+
format.html { redirect_to @forum }
|
36
|
+
format.xml { head :created, :location => forum_url(@forum, :format => :xml) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
@forum.update_attributes!(params[:forum])
|
42
|
+
respond_to do |format|
|
43
|
+
format.html { redirect_to @forum }
|
44
|
+
format.xml { head 200 }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def destroy
|
49
|
+
@forum.destroy
|
50
|
+
respond_to do |format|
|
51
|
+
format.html { redirect_to forums_path }
|
52
|
+
format.xml { head 200 }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def find_or_initialize_forum
|
58
|
+
@forum = params[:id] ? Forum.find(params[:id]) : Forum.new
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
before_filter :find_post, :except => [:index, :create]
|
3
|
+
before_filter :login_required, :except => [:index, :show]
|
4
|
+
#@@query_options = { :select => "#{Post.table_name}.*, #{Topic.table_name}.title as topic_title, #{Forum.table_name}.name as forum_name", :joins => "inner join #{Topic.table_name} on #{Post.table_name}.topic_id = #{Topic.table_name}.id inner join #{Forum.table_name} on #{Topic.table_name}.forum_id = #{Forum.table_name}.id" }
|
5
|
+
|
6
|
+
def index
|
7
|
+
#conditions = []
|
8
|
+
#[:user_id, :forum_id, :topic_id].each { |attr| conditions << Post.send(:sanitize_sql, ["#{Post.table_name}.#{attr} = ?", params[attr]]) if params[attr] }
|
9
|
+
#conditions = conditions.empty? ? nil : conditions.collect { |c| "(#{c})" }.join(' AND ')
|
10
|
+
#@posts = Post.paginate @@query_options.merge(:conditions => conditions, :page => params[:page], :count => {:select => "#{Post.table_name}.id"}, :order => post_order)
|
11
|
+
#@users = User.find(:all, :select => 'distinct *', :conditions => ['id in (?)', @posts.collect(&:user_id).uniq]).index_by(&:id)
|
12
|
+
#render_posts_or_xml
|
13
|
+
|
14
|
+
#@posts = Post.where(:forum_id => params[:forum_id]).where(:topic_id => params[:topic_id]).order('created_at desc').paginate(:page => params[:page])
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
respond_to do |format|
|
19
|
+
format.html { redirect_to forum_topic_path(@post.forum_id, @post.topic_id) }
|
20
|
+
format.xml { render :xml => @post.to_xml }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
@topic = Topic.find_by_id_and_forum_id(params[:topic_id],params[:forum_id])
|
26
|
+
@forum = @topic.forum
|
27
|
+
@post = @topic.posts.build(params[:post])
|
28
|
+
@post.user = current_user
|
29
|
+
@post.save!
|
30
|
+
email_users_in_topic(@topic)
|
31
|
+
respond_to do |format|
|
32
|
+
format.html do
|
33
|
+
redirect_to forum_topic_path(:forum_id => params[:forum_id], :id => params[:topic_id], :anchor => @post.dom_id, :page => params[:page] || '1')
|
34
|
+
end
|
35
|
+
format.xml { head :created, :location => post_url(:forum_id => params[:forum_id], :topic_id => params[:topic_id], :id => @post, :format => :xml) }
|
36
|
+
end
|
37
|
+
rescue ActiveRecord::RecordInvalid
|
38
|
+
flash[:bad_reply] = 'Please post something at least...'[:post_something_message]
|
39
|
+
respond_to do |format|
|
40
|
+
format.html do
|
41
|
+
redirect_to forum_topic_path(:forum_id => params[:forum_id], :id => params[:topic_id], :anchor => 'reply-form', :page => params[:page] || '1')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def edit
|
47
|
+
respond_to do |format|
|
48
|
+
format.html
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def update
|
53
|
+
@post.attributes = params[:post]
|
54
|
+
@post.save!
|
55
|
+
rescue ActiveRecord::RecordInvalid
|
56
|
+
flash[:bad_reply] = 'An error occurred'[:error_occured_message]
|
57
|
+
ensure
|
58
|
+
respond_to do |format|
|
59
|
+
format.html do
|
60
|
+
redirect_to forum_topic_path(:forum_id => params[:forum_id], :id => params[:topic_id], :anchor => @post.dom_id, :page => params[:page] || '1')
|
61
|
+
end
|
62
|
+
format.xml { head 200 }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def destroy
|
67
|
+
@post.destroy
|
68
|
+
#flash[:notice] = "Post of '{title}' was deleted."[:post_deleted_message, @post.topic.title]
|
69
|
+
respond_to do |format|
|
70
|
+
format.html do
|
71
|
+
redirect_to(@post.topic.frozen? ?
|
72
|
+
forum_path(params[:forum_id]) :
|
73
|
+
forum_topic_path(:forum_id => params[:forum_id], :id => params[:topic_id], :page => params[:page]))
|
74
|
+
end
|
75
|
+
format.xml { head 200 }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
def post_order
|
81
|
+
"#{Post.table_name}.created_at#{params[:forum_id] && params[:topic_id] ? nil : " desc"}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_post
|
85
|
+
@post = Post.find_by_id_and_topic_id_and_forum_id(params[:id], params[:topic_id], params[:forum_id]) || raise(ActiveRecord::RecordNotFound)
|
86
|
+
end
|
87
|
+
|
88
|
+
def email_users_in_topic(topic)
|
89
|
+
sent = []
|
90
|
+
topic.posts.find(:all, :conditions => ["user_id <> ?", current_user.id]).each do |post|
|
91
|
+
unless sent.include?(post.user.id)
|
92
|
+
UserMailer.send_later(:deliver_forum_notification, post.user, topic) if post.user.notify_forum?
|
93
|
+
sent << post.user_id
|
94
|
+
end
|
95
|
+
end
|
96
|
+
UserMailer.send_later(:deliver_forum_notification_admin, topic)
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class TopicsController < ApplicationController
|
2
|
+
before_filter :find_forum_and_topic, :except => :index
|
3
|
+
before_filter :login_required , :only => [:new, :create, :edit, :update, :destroy]
|
4
|
+
|
5
|
+
def index
|
6
|
+
respond_to do |format|
|
7
|
+
format.html { redirect_to forum_path(params[:forum_id]) }
|
8
|
+
format.xml do
|
9
|
+
@topics = Topic.paginate_by_forum_id(params[:forum_id], :order => 'sticky desc, replied_at desc', :page => params[:page])
|
10
|
+
render :xml => @topics.to_xml
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def new
|
16
|
+
@topic = Topic.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def show
|
20
|
+
respond_to do |format|
|
21
|
+
format.html do
|
22
|
+
# keep track of when we last viewed this topic for activity indicators
|
23
|
+
(session[:topics] ||= {})[@topic.id] = Time.now.utc if !current_user.nil?
|
24
|
+
# authors of topics don't get counted towards total hits
|
25
|
+
@topic.hit! unless current_user.nil? and @topic.user == current_user
|
26
|
+
@posts = @topic.posts.paginate :page => params[:page]
|
27
|
+
User.find(:all, :conditions => ['id IN (?)', @posts.collect { |p| p.user_id }.uniq]) unless @posts.nil?
|
28
|
+
@post = Post.new
|
29
|
+
end
|
30
|
+
format.xml do
|
31
|
+
render :xml => @topic.to_xml
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create
|
37
|
+
topic_save, post_save = false, false
|
38
|
+
|
39
|
+
Topic.transaction do
|
40
|
+
@topic = Topic.new(:title => params[:topic][:title])
|
41
|
+
@topic.forum_id = @forum.id
|
42
|
+
assign_protected
|
43
|
+
if @topic.save
|
44
|
+
topic_save = true
|
45
|
+
@post = Post.new(:body => params[:topic][:body])
|
46
|
+
@post.topic_id = @topic.id
|
47
|
+
@post.forum_id = @topic.forum_id
|
48
|
+
@post.user = current_user
|
49
|
+
@topic.body = @post.body
|
50
|
+
post_save = true if @post.save
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if topic_save && post_save
|
55
|
+
respond_to do |format|
|
56
|
+
format.html { redirect_to forum_topic_path(@forum, @topic) }
|
57
|
+
format.xml { head :created, :location => topic_url(:forum_id => @forum, :id => @topic, :format => :xml) }
|
58
|
+
end
|
59
|
+
else
|
60
|
+
render :action => "new"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def update
|
65
|
+
@topic.attributes = params[:topic]
|
66
|
+
assign_protected
|
67
|
+
@topic.save!
|
68
|
+
respond_to do |format|
|
69
|
+
format.html { redirect_to forum_topic_path(@forum, @topic) }
|
70
|
+
format.xml { head 200 }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def destroy
|
75
|
+
@topic.destroy
|
76
|
+
respond_to do |format|
|
77
|
+
format.html { redirect_to forum_path(@forum) }
|
78
|
+
format.xml { head 200 }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
def assign_protected
|
84
|
+
@topic.user = current_user if @topic.new_record?
|
85
|
+
#return unless admin?
|
86
|
+
#@topic.sticky, @topic.locked = params[:topic][:sticky], params[:topic][:locked]
|
87
|
+
@topic.forum_id = params[:forum_id] if params[:forum_id]
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_forum_and_topic
|
91
|
+
@forum = Forum.find(params[:forum_id])
|
92
|
+
@topic = @forum.topics.find(params[:id]) if params[:id]
|
93
|
+
end
|
94
|
+
end
|
data/app/models/forum.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Forum < ActiveRecord::Base
|
2
|
+
acts_as_list
|
3
|
+
|
4
|
+
validates_presence_of :name
|
5
|
+
|
6
|
+
has_many :topics, :order => 'sticky desc, replied_at desc', :dependent => :delete_all
|
7
|
+
has_one :recent_topic, :class_name => 'Topic', :order => 'sticky desc, replied_at desc'
|
8
|
+
|
9
|
+
# this is used to see if a forum is "fresh"... we can't use topics because it puts
|
10
|
+
# stickies first even if they are not the most recently modified
|
11
|
+
has_many :recent_topics, :class_name => 'Topic', :order => 'replied_at DESC'
|
12
|
+
has_one :recent_topic, :class_name => 'Topic', :order => 'replied_at DESC'
|
13
|
+
|
14
|
+
has_many :posts, :order => "#{Post.table_name}.created_at DESC", :dependent => :delete_all
|
15
|
+
has_one :recent_post, :order => "#{Post.table_name}.created_at DESC", :class_name => 'Post'
|
16
|
+
|
17
|
+
format_attribute :description
|
18
|
+
|
19
|
+
# retrieves forums ordered by position
|
20
|
+
def self.find_ordered(options = {})
|
21
|
+
self.order('position')
|
22
|
+
end
|
23
|
+
end
|
data/app/models/post.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
def self.per_page() 25 end
|
3
|
+
|
4
|
+
belongs_to :forum
|
5
|
+
belongs_to :user
|
6
|
+
belongs_to :topic
|
7
|
+
|
8
|
+
format_attribute :body
|
9
|
+
before_create { |r| r.forum_id = r.topic.forum_id }
|
10
|
+
after_create :update_cached_fields
|
11
|
+
after_destroy :update_cached_fields
|
12
|
+
|
13
|
+
validates_presence_of :user_id, :body, :topic_id
|
14
|
+
attr_accessible :body
|
15
|
+
|
16
|
+
def editable_by?(user)
|
17
|
+
user && (user.id == user_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
# using count isn't ideal but it gives us correct caches each time
|
22
|
+
def update_cached_fields
|
23
|
+
Forum.update_all ['posts_count = ?', Post.count(:id, :conditions => {:forum_id => forum_id})], ['id = ?', forum_id]
|
24
|
+
topic.update_cached_post_fields(self)
|
25
|
+
end
|
26
|
+
end
|
data/app/models/topic.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
class Topic < ActiveRecord::Base
|
2
|
+
validates_presence_of :forum_id, :user_id, :title
|
3
|
+
before_create :set_default_replied_at_and_sticky
|
4
|
+
before_update :check_for_changing_forums
|
5
|
+
after_save :update_forum_counter_cache
|
6
|
+
before_destroy :update_post_user_counts
|
7
|
+
after_destroy :update_forum_counter_cache
|
8
|
+
|
9
|
+
belongs_to :forum
|
10
|
+
belongs_to :user
|
11
|
+
belongs_to :last_post, :class_name => "Post", :foreign_key => 'last_post_id'
|
12
|
+
|
13
|
+
has_many :posts, :order => "#{Post.table_name}.created_at", :dependent => :delete_all
|
14
|
+
has_one :recent_post, :order => "#{Post.table_name}.created_at DESC", :class_name => 'Post'
|
15
|
+
|
16
|
+
has_many :voices, :through => :posts, :source => :user, :uniq => true
|
17
|
+
belongs_to :replied_by_user, :foreign_key => "replied_by", :class_name => "User"
|
18
|
+
|
19
|
+
attr_accessible :title
|
20
|
+
attr_accessor :body
|
21
|
+
|
22
|
+
def hit!
|
23
|
+
self.class.increment_counter :hits, id
|
24
|
+
end
|
25
|
+
|
26
|
+
def sticky?
|
27
|
+
sticky == 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def views
|
31
|
+
hits
|
32
|
+
end
|
33
|
+
|
34
|
+
def paged?
|
35
|
+
posts_count > Post.per_page
|
36
|
+
end
|
37
|
+
|
38
|
+
def last_page
|
39
|
+
[(posts_count.to_f / Post.per_page).ceil.to_i, 1].max
|
40
|
+
end
|
41
|
+
|
42
|
+
def editable_by?(user)
|
43
|
+
user && (user.id == user_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_cached_post_fields(post)
|
47
|
+
# these fields are not accessible to mass assignment
|
48
|
+
remaining_post = post.frozen? ? recent_post : post
|
49
|
+
if remaining_post
|
50
|
+
self.class.update_all(['replied_at = ?, replied_by = ?, last_post_id = ?, posts_count = ?',
|
51
|
+
remaining_post.created_at, remaining_post.user_id, remaining_post.id, posts.count], ['id = ?', id])
|
52
|
+
else
|
53
|
+
self.destroy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
def set_default_replied_at_and_sticky
|
59
|
+
self.replied_at = Time.now.utc
|
60
|
+
self.sticky ||= 0
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_post_forum_id
|
64
|
+
Post.update_all ['forum_id = ?', forum_id], ['topic_id = ?', id]
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_for_changing_forums
|
68
|
+
old = Topic.find(id)
|
69
|
+
@old_forum_id = old.forum_id if old.forum_id != forum_id
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
# using count isn't ideal but it gives us correct caches each time
|
74
|
+
def update_forum_counter_cache
|
75
|
+
forum_conditions = ['topics_count = ?', Topic.count(:id, :conditions => {:forum_id => forum_id})]
|
76
|
+
# if the topic moved forums
|
77
|
+
if !frozen? && @old_forum_id && @old_forum_id != forum_id
|
78
|
+
set_post_forum_id
|
79
|
+
Forum.update_all ['topics_count = ?, posts_count = ?',
|
80
|
+
Topic.count(:id, :conditions => {:forum_id => @old_forum_id}),
|
81
|
+
Post.count(:id, :conditions => {:forum_id => @old_forum_id})], ['id = ?', @old_forum_id]
|
82
|
+
end
|
83
|
+
# if the topic moved forums or was deleted
|
84
|
+
if frozen? || (@old_forum_id && @old_forum_id != forum_id)
|
85
|
+
forum_conditions.first << ", posts_count = ?"
|
86
|
+
forum_conditions << Post.count(:id, :conditions => {:forum_id => forum_id})
|
87
|
+
end
|
88
|
+
# User doesn't have update_posts_count method in SB2, as reported by Ryan
|
89
|
+
#@voices.each &:update_posts_count if @voices
|
90
|
+
Forum.update_all forum_conditions, ['id = ?', forum_id]
|
91
|
+
@old_forum_id = @voices = nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def update_post_user_counts
|
95
|
+
@voices = voices.to_a
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<p style="float:right; margin-top:0">
|
2
|
+
</p>
|
3
|
+
|
4
|
+
<p id="forum_name">
|
5
|
+
|
6
|
+
<table border="0" cellspacing="0" cellpadding="0" class="noborder nopad wide">
|
7
|
+
<td>
|
8
|
+
<label><%= 'Title'[:title_title] %></label><br />
|
9
|
+
<%= form.text_field :name, :class => "primary" %>
|
10
|
+
</td>
|
11
|
+
<td style="text-align:right">
|
12
|
+
<label><%= 'Position'[:position_title] %></label><br />
|
13
|
+
<%= form.text_field :position, :size => 5 %>
|
14
|
+
|
15
|
+
</td>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
</p>
|
19
|
+
<p id="forum_descripion">
|
20
|
+
<label><%= 'Description'[:description_title] %></label><br />
|
21
|
+
<%= form.text_area :description, :rows => 7 %></p>
|