forum_monster 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +24 -0
- data/LICENSE +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/forum_monster.rb +3 -0
- data/lib/generators/forum_monster/install_generator.rb +79 -0
- data/lib/generators/forum_monster/templates/controllers/categories_controller.rb +42 -0
- data/lib/generators/forum_monster/templates/controllers/forums_controller.rb +42 -0
- data/lib/generators/forum_monster/templates/controllers/posts_controller.rb +56 -0
- data/lib/generators/forum_monster/templates/controllers/topics_controller.rb +46 -0
- data/lib/generators/forum_monster/templates/migrations/categories.rb +15 -0
- data/lib/generators/forum_monster/templates/migrations/forums.rb +19 -0
- data/lib/generators/forum_monster/templates/migrations/posts.rb +16 -0
- data/lib/generators/forum_monster/templates/migrations/topics.rb +19 -0
- data/lib/generators/forum_monster/templates/migrations/user.rb +11 -0
- data/lib/generators/forum_monster/templates/models/category.rb +14 -0
- data/lib/generators/forum_monster/templates/models/forum.rb +19 -0
- data/lib/generators/forum_monster/templates/models/post.rb +34 -0
- data/lib/generators/forum_monster/templates/models/topic.rb +37 -0
- data/lib/generators/forum_monster/templates/public/images/ruby.png +0 -0
- data/lib/generators/forum_monster/templates/public/stylesheets/forum-monster.css +56 -0
- data/lib/generators/forum_monster/templates/views/categories/_form.html.erb +41 -0
- data/lib/generators/forum_monster/templates/views/categories/edit.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/categories/index.html.erb +46 -0
- data/lib/generators/forum_monster/templates/views/categories/new.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/forums/_form.html.erb +61 -0
- data/lib/generators/forum_monster/templates/views/forums/edit.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/forums/index.html.erb +46 -0
- data/lib/generators/forum_monster/templates/views/forums/new.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/forums/show.html.erb +36 -0
- data/lib/generators/forum_monster/templates/views/posts/_form.html.erb +26 -0
- data/lib/generators/forum_monster/templates/views/posts/edit.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/posts/new.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/topics/_form.html.erb +36 -0
- data/lib/generators/forum_monster/templates/views/topics/edit.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/topics/new.html.erb +1 -0
- data/lib/generators/forum_monster/templates/views/topics/show.html.erb +42 -0
- metadata +84 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 mkelley
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
=Forum Monster
|
2
|
+
|
3
|
+
I've re-activated the issue tracker on the Github repository page.
|
4
|
+
I will be working on a refactoring of this code, please report any bugs you may find. I will greatly appreciate it.
|
5
|
+
*Pull requests welcome!*
|
6
|
+
|
7
|
+
Forum Monster is a simple forum generator written in rails 3. The goal of Forum Monster, is to provide a simple, and easy to setup forum application without having to dictate how your site it setup.
|
8
|
+
|
9
|
+
* Live Demo: http://forum_monster.dev.codezombie.org
|
10
|
+
* Github Repo for Demo: https://github.com/gitt/forum_monster_demo
|
11
|
+
|
12
|
+
====A few things about what Forum Monster is, and is not:
|
13
|
+
|
14
|
+
* Forum Monster does not do any sort of authentication, or authorization. However, it does rely on the current_user method.
|
15
|
+
* Forum Monster while trying to assume as little as possible, currently assumes that the following columns are available from your user model: username, and created_at.
|
16
|
+
* Forum Monster does no authorization. By default all actions are available to all users. Even logged out users. ( Although, users who are not logged in cannot post, or create topics. )
|
17
|
+
|
18
|
+
====Installation
|
19
|
+
|
20
|
+
Add the following to your Gemfile
|
21
|
+
gem 'forum_monster'
|
22
|
+
|
23
|
+
Generate the installation. <b><user model> should be the actual name of the model containing your user accounts.</b> This will copy all of the required controllers, models, views, and stylesheets to your application.
|
24
|
+
rails g forum_monster:install <user model>
|
25
|
+
|
26
|
+
Add the following to your user model to setup the needed associations with user/topics/posts
|
27
|
+
has_many :topics, :dependent => :destroy
|
28
|
+
has_many :posts, :dependent => :destroy
|
29
|
+
|
30
|
+
Finally, migrate your database
|
31
|
+
rake db:migrate
|
32
|
+
|
33
|
+
====Authentication
|
34
|
+
|
35
|
+
Forum Monster, as stated before, does not come with any authentication built in. The reason for this is so you can add a forum to your existing application without having to change the way your application works. Forum Monster knows about your user model from the moment you run the installation command.
|
36
|
+
|
37
|
+
====Authorization
|
38
|
+
|
39
|
+
Forum Monster, by default, allows all access to all users. Even those that are not currently logged in. This was by design, because of the vast number of authorization methods out there. If I tried to cover all of them it would just get out of hand. Not to mention that as soon as an API changes, Forum Monster would be broken. This also provides a large amount of flexibility. For example, if you wanted to use CanCan, you can! declarative_authorization? Yep. Aegis? Indeed! Since you have Forum Monster's controllers in your main application, you can customize them for your specific solution just like the rest of your application!
|
40
|
+
|
41
|
+
====Avatars
|
42
|
+
|
43
|
+
I did not include support for avatars into Forum Monster for the same reason that authentication, and authorization were not included. Flexibility! You can use whatever you like, associate it with your user model, and put the corresponding image tag in the topic show view.
|
44
|
+
|
45
|
+
====Markdown
|
46
|
+
|
47
|
+
Forum Monster has no forced support for markdown. Again, it's for flexibility.
|
48
|
+
|
49
|
+
====Modifying the views, style, and adding your own images
|
50
|
+
|
51
|
+
Forum Monster will install the forum-monster.css stylesheet into your public/stylesheets directory. The views will be installed in your application app/views directory.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "Forum Monster"
|
8
|
+
gem.summary = %Q{A Rails 3 Forum Generator}
|
9
|
+
gem.description = %Q{A Rails 3 Forum Generator}
|
10
|
+
gem.email = "mike@codezombie.org"
|
11
|
+
gem.homepage = "http://github.com/gitt/forum_monster"
|
12
|
+
gem.authors = ["Mike Kelley"]
|
13
|
+
gem.files = Dir["{lib}/**/*", "{app}/**/*", "{config}/**/*", "{public}/**/*"]
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "Forum Monster #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class ForumMonster::InstallGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
desc "Installs the ForumMonster Controllers, Models, Views, and Migrations."
|
8
|
+
|
9
|
+
argument :user_model, :type => :string, :required => false, :default => "User", :desc => "Your user model name."
|
10
|
+
|
11
|
+
attr_reader :singular_camel_case_name, :plural_camel_case_name, :singular_lower_case_name, :plural_lower_case_name
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.next_migration_number(dirname)
|
18
|
+
if ActiveRecord::Base.timestamped_migrations
|
19
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
20
|
+
else
|
21
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_controllers
|
26
|
+
template "controllers/categories_controller.rb", "app/controllers/categories_controller.rb"
|
27
|
+
template "controllers/forums_controller.rb", "app/controllers/forums_controller.rb"
|
28
|
+
template "controllers/topics_controller.rb", "app/controllers/topics_controller.rb"
|
29
|
+
template "controllers/posts_controller.rb", "app/controllers/posts_controller.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_models
|
33
|
+
@singular_camel_case_name = user_model.singularize.camelize
|
34
|
+
@plural_camel_case_name = user_model.pluralize.camelize
|
35
|
+
@singular_lower_case_name = user_model.singularize.underscore
|
36
|
+
@plural_lower_case_name = user_model.pluralize.underscore
|
37
|
+
|
38
|
+
template "models/category.rb", "app/models/category.rb"
|
39
|
+
template "models/forum.rb", "app/models/forum.rb"
|
40
|
+
template "models/topic.rb", "app/models/topic.rb"
|
41
|
+
template "models/post.rb", "app/models/post.rb"
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_views
|
45
|
+
directory "views/categories", "app/views/categories"
|
46
|
+
directory "views/forums", "app/views/forums"
|
47
|
+
directory "views/topics", "app/views/topics"
|
48
|
+
directory "views/posts", "app/views/posts"
|
49
|
+
template "public/stylesheets/forum-monster.css", "public/stylesheets/forum-monster.css"
|
50
|
+
template "public/images/ruby.png", "public/images/ruby.png"
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_migrations
|
54
|
+
migration_template 'migrations/categories.rb', 'db/migrate/create_categories_table.rb'
|
55
|
+
migration_template 'migrations/forums.rb', 'db/migrate/create_forums_table.rb'
|
56
|
+
migration_template 'migrations/topics.rb', 'db/migrate/create_topics_table.rb'
|
57
|
+
migration_template 'migrations/posts.rb', 'db/migrate/create_posts_table.rb'
|
58
|
+
migration_template 'migrations/user.rb', 'db/migrate/update_users_table.rb'
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_routes
|
62
|
+
route "resources :categories, :except => [:index, :show]
|
63
|
+
resources :forums, :except => :index do
|
64
|
+
resources :topics, :shallow => true, :except => :index do
|
65
|
+
resources :posts, :shallow => true, :except => [:index, :show]
|
66
|
+
end
|
67
|
+
root :to => 'categories#index', :via => :get
|
68
|
+
end"
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.next_migration_number(path)
|
72
|
+
unless @prev_migration_nr
|
73
|
+
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
74
|
+
else
|
75
|
+
@prev_migration_nr += 1
|
76
|
+
end
|
77
|
+
@prev_migration_nr.to_s
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class CategoriesController < ApplicationController
|
2
|
+
def index
|
3
|
+
@categories = Category.all
|
4
|
+
end
|
5
|
+
|
6
|
+
def new
|
7
|
+
@category = Category.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@category = Category.new(params[:category])
|
12
|
+
|
13
|
+
if @category.save
|
14
|
+
flash[:notice] = "Category was successfully created."
|
15
|
+
redirect_to forums_url
|
16
|
+
else
|
17
|
+
render :action => 'new'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
@category = Category.find(params[:id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@category = Category.find(params[:id])
|
27
|
+
|
28
|
+
if @category.update_attributes(params[:category])
|
29
|
+
flash[:notice] = "Category was updated successfully."
|
30
|
+
redirect_to forums_url
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
@category = Category.find(params[:id])
|
36
|
+
|
37
|
+
if @category.destroy
|
38
|
+
flash[:notice] = "Category was deleted."
|
39
|
+
redirect_to forums_url
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class ForumsController < ApplicationController
|
2
|
+
def show
|
3
|
+
@forum = Forum.find(params[:id])
|
4
|
+
end
|
5
|
+
|
6
|
+
def new
|
7
|
+
@forum = Forum.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@forum = Forum.new(params[:forum])
|
12
|
+
|
13
|
+
if @forum.save
|
14
|
+
flash[:notice] = "Forum was successfully created."
|
15
|
+
redirect_to forums_url
|
16
|
+
else
|
17
|
+
render :action => 'new'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
@forum = Forum.find(params[:id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@forum = Forum.find(params[:id])
|
27
|
+
|
28
|
+
if @forum.update_attributes(params[:forum])
|
29
|
+
flash[:notice] = "Forum was updated successfully."
|
30
|
+
redirect_to forum_url(@forum)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
@forum = Forum.find(params[:id])
|
36
|
+
|
37
|
+
if @forum.destroy
|
38
|
+
flash[:notice] = "Category was deleted."
|
39
|
+
redirect_to forums_url
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
def new
|
3
|
+
@topic = Topic.find(params[:topic_id])
|
4
|
+
@post = Post.new
|
5
|
+
|
6
|
+
if params[:quote]
|
7
|
+
quote_post = Post.find(params[:quote])
|
8
|
+
if quote_post
|
9
|
+
@post.body = quote_post.body
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@topic = Topic.find(params[:topic_id])
|
16
|
+
@post = @topic.posts.build(params[:post])
|
17
|
+
@post.forum = @topic.forum
|
18
|
+
@post.user = current_user
|
19
|
+
|
20
|
+
if @post.save
|
21
|
+
flash[:notice] = "Post was successfully created."
|
22
|
+
redirect_to topic_path(@post.topic)
|
23
|
+
else
|
24
|
+
render :action => 'new'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def edit
|
29
|
+
@post = Post.find(params[:id])
|
30
|
+
end
|
31
|
+
|
32
|
+
def update
|
33
|
+
@post = Post.find(params[:id])
|
34
|
+
|
35
|
+
if @post.update_attributes(params[:post])
|
36
|
+
flash[:notice] = "Post was successfully updated."
|
37
|
+
redirect_to topic_path(@post.topic)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy
|
42
|
+
@post = Post.find(params[:id])
|
43
|
+
|
44
|
+
if @post.topic.posts_count > 1
|
45
|
+
if @post.destroy
|
46
|
+
flash[:notice] = "Post was successfully destroyed."
|
47
|
+
redirect_to topic_path(@post.topic)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
if @post.topic.destroy
|
51
|
+
flash[:notice] = "Topic was successfully deleted."
|
52
|
+
redirect_to forum_path(@post.forum)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class TopicsController < ApplicationController
|
2
|
+
def show
|
3
|
+
@topic = Topic.find(params[:id])
|
4
|
+
@topic.hit! if @topic
|
5
|
+
end
|
6
|
+
|
7
|
+
def new
|
8
|
+
@forum = Forum.find(params[:forum_id])
|
9
|
+
@topic = Topic.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
@forum = Forum.find(params[:forum_id])
|
14
|
+
@topic = @forum.topics.build(params[:topic])
|
15
|
+
@topic.user = current_user
|
16
|
+
|
17
|
+
if @topic.save
|
18
|
+
flash[:notice] = "Topic was successfully created."
|
19
|
+
redirect_to topic_url(@topic)
|
20
|
+
else
|
21
|
+
render :action => 'new'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def edit
|
26
|
+
@topic = Topic.find(params[:id])
|
27
|
+
end
|
28
|
+
|
29
|
+
def update
|
30
|
+
@topic = Topic.find(params[:id])
|
31
|
+
|
32
|
+
if @topic.update_attributes(params[:topic])
|
33
|
+
flash[:notice] = "Topic was updated successfully."
|
34
|
+
redirect_to topic_url(@topic)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
@topic = Topic.find(params[:id])
|
40
|
+
|
41
|
+
if @topic.destroy
|
42
|
+
flash[:notice] = "Topic was deleted successfully."
|
43
|
+
redirect_to forum_url(@topic.forum)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateCategoriesTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :categories, :force => true do |t|
|
4
|
+
t.string :title
|
5
|
+
t.boolean :state, :default => true
|
6
|
+
t.integer :position, :default => 0
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :categories
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateForumsTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :forums, :force => true do |t|
|
4
|
+
t.string :title
|
5
|
+
t.text :description
|
6
|
+
t.boolean :state, :default => true
|
7
|
+
t.integer :topics_count, :default => 0
|
8
|
+
t.integer :posts_count, :default => 0
|
9
|
+
t.integer :position, :default => 0
|
10
|
+
t.integer :category_id
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table :forums
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreatePostsTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :posts, :force => true do |t|
|
4
|
+
t.string :body
|
5
|
+
t.integer :forum_id
|
6
|
+
t.integer :topic_id
|
7
|
+
t.integer :user_id
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :posts
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateTopicsTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :topics, :force => true do |t|
|
4
|
+
t.string :title
|
5
|
+
t.integer :hits, :default => 0
|
6
|
+
t.boolean :sticky, :default => false
|
7
|
+
t.boolean :locked, :default => false
|
8
|
+
t.integer :posts_count
|
9
|
+
t.integer :forum_id
|
10
|
+
t.integer :user_id
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table :topics
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= "Update#{plural_camel_case_name}Table" %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :<%= plural_lower_case_name %>, :topics_count, :integer, :default => 0
|
4
|
+
add_column :<%= plural_lower_case_name %>, :posts_count, :integer, :default => 0
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :<%= plural_lower_case_name %>, :topics_count
|
9
|
+
remove_column :<%= plural_lower_case_name %>, :posts_count
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Category < ActiveRecord::Base
|
2
|
+
|
3
|
+
# Associations
|
4
|
+
has_many :forums, :dependent => :destroy
|
5
|
+
|
6
|
+
# Accessors
|
7
|
+
attr_accessible :title, :state, :position, :category_id
|
8
|
+
|
9
|
+
# Scopes
|
10
|
+
default_scope :order => 'position ASC'
|
11
|
+
|
12
|
+
# Validations
|
13
|
+
validates :title, :presence => true
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Forum < ActiveRecord::Base
|
2
|
+
|
3
|
+
# Associations
|
4
|
+
has_many :topics, :dependent => :destroy
|
5
|
+
has_many :posts, :through => :topics
|
6
|
+
|
7
|
+
belongs_to :category
|
8
|
+
|
9
|
+
# Accessors
|
10
|
+
attr_accessible :title, :description, :state, :position, :category_id
|
11
|
+
|
12
|
+
# Scopes
|
13
|
+
default_scope :order => 'position ASC'
|
14
|
+
|
15
|
+
# Validations
|
16
|
+
validates :title, :presence => true
|
17
|
+
validates :description, :presence => true
|
18
|
+
validates :category_id, :presence => true
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
|
3
|
+
# Associations
|
4
|
+
belongs_to :forum, :counter_cache => true
|
5
|
+
belongs_to :topic, :counter_cache => true, :touch => true
|
6
|
+
belongs_to :user, :class_name => "<%= "#{singular_camel_case_name}" %>", :counter_cache => true
|
7
|
+
|
8
|
+
# Accessors
|
9
|
+
attr_accessible :body
|
10
|
+
|
11
|
+
# Validations
|
12
|
+
validates :body, :presence => true
|
13
|
+
validates :user, :presence => true
|
14
|
+
|
15
|
+
# Default Scope
|
16
|
+
default_scope :order => 'created_at ASC'
|
17
|
+
|
18
|
+
# Scope to display only the last n posts. Used for "Recent Posts" display
|
19
|
+
scope :recent, lambda {
|
20
|
+
|c| reorder('created_at desc').limit(c)
|
21
|
+
}
|
22
|
+
|
23
|
+
# Callbacks
|
24
|
+
before_save :topic_locked?
|
25
|
+
|
26
|
+
# Methods
|
27
|
+
private
|
28
|
+
def topic_locked?
|
29
|
+
if topic.locked?
|
30
|
+
errors.add(:base, "That topic is locked")
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Topic < ActiveRecord::Base
|
2
|
+
|
3
|
+
# Associations
|
4
|
+
has_many :posts, :dependent => :destroy
|
5
|
+
belongs_to :forum, :counter_cache => true
|
6
|
+
belongs_to :user, :class_name => "<%= "#{singular_camel_case_name}" %>", :counter_cache => true
|
7
|
+
|
8
|
+
# Accessors
|
9
|
+
attr_accessor :body
|
10
|
+
attr_accessible :title, :body, :sticky, :locked
|
11
|
+
|
12
|
+
# Validations
|
13
|
+
validates :title, :presence => true
|
14
|
+
validates :body, :presence => true, :on => :create
|
15
|
+
validates :posts, :presence => true, :allow_nil => false, :on => :update
|
16
|
+
validates :user, :presence => true
|
17
|
+
|
18
|
+
# Scopes
|
19
|
+
default_scope :order => 'sticky DESC, updated_at DESC'
|
20
|
+
|
21
|
+
# Callbacks
|
22
|
+
after_create :create_initial_post
|
23
|
+
|
24
|
+
# Methods
|
25
|
+
def hit!
|
26
|
+
self.class.increment_counter :hits, id
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def create_initial_post
|
31
|
+
self.posts.build(:body => self.body).tap do |post|
|
32
|
+
post.forum = self.forum
|
33
|
+
post.user = self.user
|
34
|
+
post.save
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
Binary file
|
@@ -0,0 +1,56 @@
|
|
1
|
+
/* Modules
|
2
|
+
--------------------------------------------------------------------------------------------------*/
|
3
|
+
.module { border:1px solid #e2e2e2; margin:.8em 0; background-color:#fff; overflow:auto; }
|
4
|
+
.module_controls { padding:.8em; }
|
5
|
+
.module_header { color:#fff; padding:.7em .7em .7em 1.4em; background-color:#000; }
|
6
|
+
.module_header a { color:#fff; }
|
7
|
+
.module_subheader, .module_footer { margin:.6em .8em; padding:.6em; }
|
8
|
+
.module_subheader { border-bottom:1px solid #e2e2e2; }
|
9
|
+
.module_footer { border-top:1px solid #e2e2e2; }
|
10
|
+
.module_body { padding:1em; }
|
11
|
+
|
12
|
+
/* Form Fields & Labels
|
13
|
+
--------------------------------------------------------------------------------------------------*/
|
14
|
+
.module .fieldset { width:100%; }
|
15
|
+
.module .fieldset .indent { width:16em; }
|
16
|
+
.module .fieldset .label { font-weight:bold; text-align:right; display:block; float:left; padding:6px 0px 2px 1em; }
|
17
|
+
.module .fieldset .label small { font-weight:normal; }
|
18
|
+
.module .fieldset .input { padding:.2em 1em; display:block; float:left; }
|
19
|
+
|
20
|
+
/* Common
|
21
|
+
--------------------------------------------------------------------------------------------------*/
|
22
|
+
.module .clear { clear: both; height: 0; overflow: hidden; }
|
23
|
+
.module .smaller { font-size:.9em; }
|
24
|
+
.module .left { float:left; }
|
25
|
+
.module .right { float:right; text-align:right; }
|
26
|
+
.controls a { margin:0 5px; font-size:.8em; }
|
27
|
+
|
28
|
+
/* Tables
|
29
|
+
--------------------------------------------------------------------------------------------------*/
|
30
|
+
table { width:100%; border-collapse:collapse; }
|
31
|
+
table th { font-weight:normal; padding:.7em; font-size:.8em; }
|
32
|
+
table td { padding:.5em; border:1px solid #e2e2e2; border-bottom:0px; vertical-align:top; background:#fff; }
|
33
|
+
table td:first-child { border-left:0px; }
|
34
|
+
table td:last-child { border-right:0px; }
|
35
|
+
|
36
|
+
table .icon { width:26px; text-align:center; }
|
37
|
+
table .counts { width:8%; text-align:center; }
|
38
|
+
table .last_post { padding-left:10px; }
|
39
|
+
table .description { width:55%; text-align:left; padding-left:20px; }
|
40
|
+
|
41
|
+
/* Post View Table
|
42
|
+
--------------------------------------------------------------------------------------------------*/
|
43
|
+
table .post_author { padding-left:15px; vertical-align:top !important; }
|
44
|
+
table .post_author .name { font-size:1.5em; display:block; margin-bottom:5px; }
|
45
|
+
table .post_author .name a { margin-left:-20px; }
|
46
|
+
table .post_author .info { display:block; margin:5px 0; }
|
47
|
+
table .post_body { width:80%; padding:10px 10px 30px 10px; border-bottom:0px; }
|
48
|
+
|
49
|
+
/* BBCode
|
50
|
+
--------------------------------------------------------------------------------------------------*/
|
51
|
+
blockquote {
|
52
|
+
border: 1px solid #e2e2e2;
|
53
|
+
font-style: italic;
|
54
|
+
margin: 10px 0px 0px 25px;
|
55
|
+
padding: 10px;
|
56
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<div class="module">
|
2
|
+
<div class="module_header"><%= action_name.humanize %> Category</div>
|
3
|
+
<div class="module_subheader smaller"></div>
|
4
|
+
<div class="module_body">
|
5
|
+
<%= form_for @category do |f| %>
|
6
|
+
<% if @category.errors.any? %>
|
7
|
+
<% flash.now[:error] = @category.errors.full_messages.join(', and ') %>
|
8
|
+
<% end %>
|
9
|
+
<div class="fieldset">
|
10
|
+
<span class="label indent smaller">
|
11
|
+
<%= f.label :title %><br />
|
12
|
+
<small>(Required)</small>
|
13
|
+
</span>
|
14
|
+
<span class="input indent smaller"><%= f.text_field :title, :size => 75 %></span>
|
15
|
+
<div class="clear"></div>
|
16
|
+
</div>
|
17
|
+
<div class="fieldset">
|
18
|
+
<span class="label indent smaller">
|
19
|
+
<%= f.label :position %>
|
20
|
+
</span>
|
21
|
+
<span class="input indent smaller"><%= f.text_field :position %></span>
|
22
|
+
<div class="clear"></div>
|
23
|
+
</div>
|
24
|
+
<div class="fieldset">
|
25
|
+
<span class="label indent smaller"></span>
|
26
|
+
<span class="input indent smaller">
|
27
|
+
<%= f.check_box :state %>
|
28
|
+
<%= f.label :state %>
|
29
|
+
</span>
|
30
|
+
<div class="clear"></div>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div class="module_footer">
|
34
|
+
<div class="fieldset">
|
35
|
+
<span class="input"><%= f.submit "submit" %> or <%= link_to "cancel", forums_path %></span>
|
36
|
+
<div class="clear"></div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
</div>
|
41
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<div class="right controls"><%= link_to "New Forum Category", new_category_path %></div>
|
2
|
+
<% @categories.each do |category| %>
|
3
|
+
<div class="module">
|
4
|
+
<div class="module_header">
|
5
|
+
<%= category.title %>
|
6
|
+
<span class="controls right smaller">
|
7
|
+
<%= link_to "New Forum", new_forum_path %>
|
8
|
+
<%= link_to "Edit Category", edit_category_path(category) %>
|
9
|
+
<%= link_to "Delete Category", category_path(category), :confirm => "Are you sure you want to delete this category?", :method => :delete %>
|
10
|
+
</span>
|
11
|
+
</div>
|
12
|
+
<% if category.forums.size > 0 %>
|
13
|
+
<div>
|
14
|
+
<table>
|
15
|
+
<tr class="smaller">
|
16
|
+
<th colspan="2" align="left">Forum</th>
|
17
|
+
<th>Topics</th>
|
18
|
+
<th>Posts</th>
|
19
|
+
<th class="last_post" align="left">Last Post</th>
|
20
|
+
</tr>
|
21
|
+
<% category.forums.each do |forum| %>
|
22
|
+
<tr>
|
23
|
+
<td class="icon"><%= image_tag 'ruby.png' %></td>
|
24
|
+
<td class="description">
|
25
|
+
<%= link_to forum.title, forum_path(forum) %><br />
|
26
|
+
<span class="smaller"><%= forum.description %></span><br />
|
27
|
+
</td>
|
28
|
+
<td class="counts smaller"><%= forum.topics.size %></td>
|
29
|
+
<td class="counts smaller"><%= forum.posts.size - forum.topics.size %></td>
|
30
|
+
<td class="last_post smaller">
|
31
|
+
<% if forum.posts.size > 0 %>
|
32
|
+
<%= forum.posts.last.created_at %><br />
|
33
|
+
<%= forum.posts.last.user.username %>
|
34
|
+
<% else %>
|
35
|
+
No Topics / Posts
|
36
|
+
<% end %>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</table>
|
41
|
+
</div>
|
42
|
+
<% else %>
|
43
|
+
<div class="module_body">There are currently no forums.</div>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<div class="module">
|
2
|
+
<div class="module_header"><%= action_name.humanize %> Forum</div>
|
3
|
+
<div class="module_subheader smaller">
|
4
|
+
<em>To create a category, leave the category field unselected.</em>
|
5
|
+
</div>
|
6
|
+
<div class="module_body">
|
7
|
+
<%= form_for @forum do |f| %>
|
8
|
+
<% if @forum.errors.any? %>
|
9
|
+
<% flash.now[:error] = @forum.errors.full_messages.join(', and ') %>
|
10
|
+
<% end %>
|
11
|
+
<div class="fieldset">
|
12
|
+
<span class="label indent smaller">
|
13
|
+
<%= f.label :category_id %><br />
|
14
|
+
<small>(Required)</small>
|
15
|
+
</span>
|
16
|
+
<span class="input indent smaller">
|
17
|
+
<%= f.collection_select :category_id, Category.all, :id, :title %>
|
18
|
+
</span>
|
19
|
+
<div class="clear"></div>
|
20
|
+
</div>
|
21
|
+
<div class="fieldset">
|
22
|
+
<span class="label indent smaller">
|
23
|
+
<%= f.label :title %><br />
|
24
|
+
<small>(Required)</small>
|
25
|
+
</span>
|
26
|
+
<span class="input indent smaller"><%= f.text_field :title, :size => 75 %></span>
|
27
|
+
<div class="clear"></div>
|
28
|
+
</div>
|
29
|
+
<div class="fieldset">
|
30
|
+
<span class="label indent smaller">
|
31
|
+
<%= f.label :description %><br />
|
32
|
+
<small>(Required)</small>
|
33
|
+
</span>
|
34
|
+
<span class="input indent smaller"><%= f.text_area :description, :cols => 60, :rows => 5 %></span>
|
35
|
+
<div class="clear"></div>
|
36
|
+
</div>
|
37
|
+
<div class="fieldset">
|
38
|
+
<span class="label indent smaller">
|
39
|
+
<%= f.label :position %>
|
40
|
+
</span>
|
41
|
+
<span class="input indent smaller"><%= f.text_field :position %></span>
|
42
|
+
<div class="clear"></div>
|
43
|
+
</div>
|
44
|
+
<div class="fieldset">
|
45
|
+
<span class="label indent smaller"></span>
|
46
|
+
<span class="input indent smaller">
|
47
|
+
<%= f.check_box :state %>
|
48
|
+
<%= f.label :state %>
|
49
|
+
</span>
|
50
|
+
<div class="clear"></div>
|
51
|
+
</div>
|
52
|
+
</div>
|
53
|
+
<div class="module_footer">
|
54
|
+
<div class="fieldset">
|
55
|
+
<span class="input"><%= f.submit "submit" %> or <%= link_to "cancel", @forum.nil? ? forum_path(@forum) : forums_path %></span>
|
56
|
+
<div class="clear"></div>
|
57
|
+
</div>
|
58
|
+
</div>
|
59
|
+
<% end %>
|
60
|
+
</div>
|
61
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<div class="right controls"><%= link_to "New Forum/Category", new_forum_path %></div>
|
2
|
+
<% @categories.each do |category| %>
|
3
|
+
<div class="module">
|
4
|
+
<div class="module_header">
|
5
|
+
<%= category.title %>
|
6
|
+
<span class="controls right smaller">
|
7
|
+
<%= link_to "New Forum", new_forum_path %>
|
8
|
+
<%= link_to "Edit Category", edit_forum_path(category) %>
|
9
|
+
<%= link_to "Delete Category", forum_path(category), :confirm => "Are you sure you want to delete this category?", :method => :delete %>
|
10
|
+
</span>
|
11
|
+
</div>
|
12
|
+
<% if category.forums.size > 0 %>
|
13
|
+
<div>
|
14
|
+
<table>
|
15
|
+
<tr class="smaller">
|
16
|
+
<th colspan="2" align="left">Forum</th>
|
17
|
+
<th>Topics</th>
|
18
|
+
<th>Posts</th>
|
19
|
+
<th class="last_post" align="left">Last Post</th>
|
20
|
+
</tr>
|
21
|
+
<% category.forums.each do |forum| %>
|
22
|
+
<tr>
|
23
|
+
<td class="icon"><%= image_tag 'ruby.png' %></td>
|
24
|
+
<td class="description">
|
25
|
+
<%= link_to forum.title, forum_path(forum) %><br />
|
26
|
+
<span class="smaller"><%= forum.description %></span><br />
|
27
|
+
</td>
|
28
|
+
<td class="counts smaller"><%= forum.topics.size %></td>
|
29
|
+
<td class="counts smaller"><%= forum.posts.size - forum.topics.size %></td>
|
30
|
+
<td class="last_post smaller">
|
31
|
+
<% if forum.posts.size > 0 %>
|
32
|
+
<%= forum.posts.last.created_at %><br />
|
33
|
+
<%= forum.posts.last.user.username %>
|
34
|
+
<% else %>
|
35
|
+
No Topics / Posts
|
36
|
+
<% end %>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</table>
|
41
|
+
</div>
|
42
|
+
<% else %>
|
43
|
+
<div class="module_body">There are currently no forums.</div>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<div class="right controls"><%= link_to "Back to Forum List", forums_path %></div>
|
2
|
+
<div class="module">
|
3
|
+
<div class="module_header">
|
4
|
+
<%= @forum.title %>
|
5
|
+
<span class="controls right">
|
6
|
+
<%= link_to "New Topic", new_forum_topic_path(@forum) %>
|
7
|
+
<%= link_to "Edit Forum", edit_forum_path(@forum) %>
|
8
|
+
<%= link_to "Delete Forum", forum_path(@forum), :confirm => "Are you sure you want to delete this forum?", :method => :delete %>
|
9
|
+
</span>
|
10
|
+
</div>
|
11
|
+
<div>
|
12
|
+
<table>
|
13
|
+
<tr class="smaller">
|
14
|
+
<th colspan="2" align="left">Topic</th>
|
15
|
+
<th>Replies</th>
|
16
|
+
<th>Views</th>
|
17
|
+
<th class="last_post" align="left">Last Post</th>
|
18
|
+
</tr>
|
19
|
+
<% @forum.topics.each do |topic| %>
|
20
|
+
<tr>
|
21
|
+
<td class="icon"><%= image_tag 'ruby.png' %></td>
|
22
|
+
<td class="description">
|
23
|
+
<%= link_to topic.title, topic_path(topic) %><br />
|
24
|
+
<span class="smaller">by <%= topic.user.username %></span>
|
25
|
+
</td>
|
26
|
+
<td class="counts smaller"><%= topic.posts.size - 1 %></td>
|
27
|
+
<td class="counts smaller"><%= topic.hits %></td>
|
28
|
+
<td class="last_post smaller">
|
29
|
+
<%= topic.posts.last.created_at %><br />
|
30
|
+
by <%= topic.posts.last.user.username %>
|
31
|
+
</td>
|
32
|
+
</tr>
|
33
|
+
<% end %>
|
34
|
+
</table>
|
35
|
+
</div>
|
36
|
+
</div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<div class="module">
|
2
|
+
<div class="module_header"><%= action_name.humanize %> Post</div>
|
3
|
+
<div class="module_subheader smaller"></div>
|
4
|
+
<div class="module_body">
|
5
|
+
<%= form_for [@topic, @post] do |f| %>
|
6
|
+
<% if @post.errors.any? %>
|
7
|
+
<% flash.now[:error] = @post.errors.full_messages.join(', and ') %>
|
8
|
+
<% end %>
|
9
|
+
<div class="fieldset">
|
10
|
+
<span class="label indent smaller">
|
11
|
+
<%= f.label :body %><br />
|
12
|
+
<small>(Required)</small>
|
13
|
+
</span>
|
14
|
+
<span class="input indent smaller"><%= f.text_area :body, :cols => 60, :rows => 15 %></span>
|
15
|
+
<div class="clear"></div>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<div class="module_footer">
|
19
|
+
<div class="fieldset">
|
20
|
+
<span class="input"><%= f.submit "submit" %> or <%= link_to "cancel", @topic %></span>
|
21
|
+
<div class="clear"></div>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
26
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<%= form_for [@forum, @topic] do |f| %>
|
2
|
+
<% if @topic.errors.any? %>
|
3
|
+
<% flash.now[:error] = @topic.errors.full_messages.join(', and ') %>
|
4
|
+
<% end %>
|
5
|
+
<div class="module">
|
6
|
+
<div class="module_header"><%= action_name.humanize %> Topic</div>
|
7
|
+
<div class="module_subheader smaller"></div>
|
8
|
+
<div class="module_body">
|
9
|
+
<div class="fieldset">
|
10
|
+
<span class="label indent smaller">
|
11
|
+
<%= f.label :title %><br />
|
12
|
+
<small>(Required)</small>
|
13
|
+
</span>
|
14
|
+
<span class="input indent smaller"><%= f.text_field :title, :size => 75 %></span>
|
15
|
+
<div class="clear"></div>
|
16
|
+
</div>
|
17
|
+
<% unless @topic.id %>
|
18
|
+
<div class="fieldset">
|
19
|
+
<span class="label indent smaller">
|
20
|
+
<%= f.label :body %><br />
|
21
|
+
<small>(Required)</small>
|
22
|
+
</span>
|
23
|
+
<span class="input indent smaller"><%= f.text_area :body, :cols => 60, :rows => 15 %></span>
|
24
|
+
<div class="clear"></div>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
<div class="module_footer">
|
29
|
+
<div class="fieldset">
|
30
|
+
<span class="input"><%= f.submit "submit" %> or <%= link_to "cancel", @topic.nil? ? @topic : @forum %></span>
|
31
|
+
<div class="clear"></div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render :partial => 'form' %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<div class="right controls"><%= link_to "Back to Forum", forum_path(@topic.forum) %></div>
|
2
|
+
<div class="module">
|
3
|
+
<div class="module_header">
|
4
|
+
<%= @topic.title %>
|
5
|
+
<span class="right controls">
|
6
|
+
<%= link_to "Edit", edit_topic_path(@topic) %>
|
7
|
+
<%= link_to "Delete", @topic, :confirm => "Are you sure?", :method => :delete %>
|
8
|
+
<%= link_to @topic.sticky ? "Unstick" : "Sticky", {:controller => 'topics', :action => 'update', :topic => {:sticky => @topic.sticky ? "false" : "true" }}, :method => :put %>
|
9
|
+
<%= link_to @topic.locked ? "Unlock" : "Lock", {:controller => 'topics', :action => 'update', :topic => {:locked => @topic.locked ? "false" : "true" }}, :method => :put %>
|
10
|
+
</span>
|
11
|
+
</div>
|
12
|
+
<div>
|
13
|
+
<table>
|
14
|
+
<% @topic.posts.each do |post| %>
|
15
|
+
<tr>
|
16
|
+
<td class="post_author" rowspan="2">
|
17
|
+
<span class="name"><%= post.user.username %></span>
|
18
|
+
<span class="avatar"><!-- This space reserved for Avatar --></span>
|
19
|
+
<span class="info smaller">
|
20
|
+
Posts <%= post.user.posts.size %><br />
|
21
|
+
Registered <%= post.user.created_at.to_s(:joined) %><br />
|
22
|
+
</span>
|
23
|
+
</td>
|
24
|
+
<td class="post_header">
|
25
|
+
<span class="left post_date smaller">Posted <%= post.created_at %></span>
|
26
|
+
<span class="right controls">
|
27
|
+
<%= link_to "Reply", new_topic_post_path(@topic) %>
|
28
|
+
<%= link_to "Quote", new_topic_post_path(@topic, :quote => post) %>
|
29
|
+
<%= link_to "Edit", edit_post_path(post) %>
|
30
|
+
<%= link_to "Delete", post, :confirm => "Are you sure?", :method => :delete %>
|
31
|
+
</span>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
<tr>
|
35
|
+
<td class="post_body">
|
36
|
+
<%= post.body %>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</table>
|
41
|
+
</div>
|
42
|
+
</div>
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: forum_monster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mike Kelley
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-03-28 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A Rails 3 Forum Generator
|
15
|
+
email: mike@codezombie.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files:
|
19
|
+
- LICENSE
|
20
|
+
- README.rdoc
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
- Rakefile
|
26
|
+
- VERSION
|
27
|
+
- lib/forum_monster.rb
|
28
|
+
- lib/generators/forum_monster/install_generator.rb
|
29
|
+
- lib/generators/forum_monster/templates/controllers/categories_controller.rb
|
30
|
+
- lib/generators/forum_monster/templates/controllers/forums_controller.rb
|
31
|
+
- lib/generators/forum_monster/templates/controllers/posts_controller.rb
|
32
|
+
- lib/generators/forum_monster/templates/controllers/topics_controller.rb
|
33
|
+
- lib/generators/forum_monster/templates/migrations/categories.rb
|
34
|
+
- lib/generators/forum_monster/templates/migrations/forums.rb
|
35
|
+
- lib/generators/forum_monster/templates/migrations/posts.rb
|
36
|
+
- lib/generators/forum_monster/templates/migrations/topics.rb
|
37
|
+
- lib/generators/forum_monster/templates/migrations/user.rb
|
38
|
+
- lib/generators/forum_monster/templates/models/category.rb
|
39
|
+
- lib/generators/forum_monster/templates/models/forum.rb
|
40
|
+
- lib/generators/forum_monster/templates/models/post.rb
|
41
|
+
- lib/generators/forum_monster/templates/models/topic.rb
|
42
|
+
- lib/generators/forum_monster/templates/public/images/ruby.png
|
43
|
+
- lib/generators/forum_monster/templates/public/stylesheets/forum-monster.css
|
44
|
+
- lib/generators/forum_monster/templates/views/categories/_form.html.erb
|
45
|
+
- lib/generators/forum_monster/templates/views/categories/edit.html.erb
|
46
|
+
- lib/generators/forum_monster/templates/views/categories/index.html.erb
|
47
|
+
- lib/generators/forum_monster/templates/views/categories/new.html.erb
|
48
|
+
- lib/generators/forum_monster/templates/views/forums/_form.html.erb
|
49
|
+
- lib/generators/forum_monster/templates/views/forums/edit.html.erb
|
50
|
+
- lib/generators/forum_monster/templates/views/forums/index.html.erb
|
51
|
+
- lib/generators/forum_monster/templates/views/forums/new.html.erb
|
52
|
+
- lib/generators/forum_monster/templates/views/forums/show.html.erb
|
53
|
+
- lib/generators/forum_monster/templates/views/posts/_form.html.erb
|
54
|
+
- lib/generators/forum_monster/templates/views/posts/edit.html.erb
|
55
|
+
- lib/generators/forum_monster/templates/views/posts/new.html.erb
|
56
|
+
- lib/generators/forum_monster/templates/views/topics/_form.html.erb
|
57
|
+
- lib/generators/forum_monster/templates/views/topics/edit.html.erb
|
58
|
+
- lib/generators/forum_monster/templates/views/topics/new.html.erb
|
59
|
+
- lib/generators/forum_monster/templates/views/topics/show.html.erb
|
60
|
+
homepage: http://github.com/gitt/forum_monster
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.8.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: A Simple Rails 3 Forum Generator
|
84
|
+
test_files: []
|