Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #3 from dimko/master

Many fixes for rails3-beast
  • Loading branch information...
commit dc64588efcbaf5d155192e7cb78fc7c41606a7a5 2 parents 7100e23 + 17e4502
@stiff authored
Showing with 738 additions and 840 deletions.
  1. +3 −4 Gemfile
  2. +34 −34 Gemfile.lock
  3. +3 −10 app/controllers/application_controller.rb
  4. +9 −5 app/controllers/forums_controller.rb
  5. +5 −3 app/controllers/monitorships_controller.rb
  6. +19 −16 app/controllers/posts_controller.rb
  7. +39 −41 app/controllers/sessions_controller.rb
  8. +10 −6 app/controllers/sites_controller.rb
  9. +10 −9 app/controllers/topics_controller.rb
  10. +20 −22 app/controllers/users_controller.rb
  11. +13 −8 app/helpers/application_helper.rb
  12. +22 −0 app/helpers/error_messages_helper.rb
  13. +2 −3 app/helpers/forums_helper.rb
  14. +9 −10 app/helpers/users_helper.rb
  15. +22 −0 app/mailers/user_mailer.rb
  16. +7 −10 app/models/forum.rb
  17. +14 −12 app/models/moderatorship.rb
  18. +16 −15 app/models/monitorship.rb
  19. +17 −16 app/models/post.rb
  20. +0 −12 app/models/posts_sweeper.rb
  21. +22 −20 app/models/site.rb
  22. +41 −42 app/models/topic.rb
  23. +24 −22 app/models/user.rb
  24. +1 −1  app/models/user/editable.rb
  25. +8 −8 app/models/user/posting.rb
  26. +25 −24 app/models/user/states.rb
  27. +28 −28 app/models/user/validation.rb
  28. +0 −22 app/models/user_mailer.rb
  29. +4 −4 app/{models → sweepers}/monitorships_sweeper.rb
  30. +12 −0 app/sweepers/posts_sweeper.rb
  31. +16 −18 app/views/forums/_form.html.erb
  32. +5 −7 app/views/forums/edit.html.erb
  33. +8 −11 app/views/forums/index.html.erb
  34. +4 −4 app/views/forums/new.html.erb
  35. +15 −15 app/views/forums/show.html.erb
  36. +16 −0 app/views/layouts/_footer.html.erb
  37. +20 −40 app/views/layouts/_head.html.erb
  38. +33 −40 app/views/layouts/application.html.erb
  39. +22 −23 app/views/posts/_edit.html.erb
  40. 0  app/views/posts/{_formatting.erb → _formatting.html.erb}
  41. +7 −8 app/views/posts/edit.html.erb
  42. +8 −8 app/views/posts/index.html.erb
  43. +4 −4 app/views/sessions/new.html.erb
  44. +0 −10 app/views/shared/_error_messages.html.erb
  45. +1 −2  app/views/sites/_form.html.erb
  46. +4 −6 app/views/sites/edit.html.erb
  47. +3 −3 app/views/sites/index.html.erb
  48. +5 −5 app/views/sites/new.html.erb
  49. +1 −1  app/views/sites/show.html.erb
  50. +17 −19 app/views/topics/_form.html.erb
  51. +5 −8 app/views/topics/edit.html.erb
  52. +5 −8 app/views/topics/new.html.erb
  53. +26 −26 app/views/topics/show.html.erb
  54. +0 −3  app/views/user_mailer/activation.html.erb
  55. +3 −0  app/views/user_mailer/activation.text.erb
  56. +1 −1  app/views/user_mailer/{signup_notification.html.erb → signup_notification.text.erb}
  57. +0 −1  app/views/users/_settings.html.erb
  58. +7 −8 app/views/users/edit.html.erb
  59. +8 −8 app/views/users/index.html.erb
  60. +17 −16 app/views/users/new.html.erb
  61. +16 −17 app/views/users/show.html.erb
  62. +1 −1  config/application.rb
  63. +3 −10 config/boot.rb
  64. +3 −0  config/initializers/error_messages.rb
  65. +0 −20 config/preinitializer.rb
  66. +2 −2 lib/tasks/app_bootstrap.rake
  67. +0 −74 public/stylesheets/scaffold.css
  68. +13 −6 spec/models/user_spec.rb
View
7 Gemfile
@@ -1,7 +1,6 @@
-# A sample Gemfile
source "http://rubygems.org"
-gem "rails", "3.0.5"
+gem 'rails', '3.0.7'
gem 'ruby-openid', '>= 2.0.4', :require => "openid"
gem 'rack-openid'
gem 'will_paginate', :git => "http://github.com/mislav/will_paginate.git", :branch => "rails3"
@@ -16,11 +15,11 @@ group :development, :test do
gem 'rspec-rails'
gem 'highline'
gem 'sqlite3-ruby', :require => "sqlite3"
-# gem 'ruby-debug' # XXX linecache gem currently doesn't work in ruby 1.9
+ # gem 'ruby-debug19'
gem 'autotest'
gem 'rails3-generators'
end
group :production do
- gem 'mysql2'
+ gem 'mysql2', '~> 0.2.7'
end
View
68 Gemfile.lock
@@ -11,32 +11,32 @@ GEM
RedCloth (4.2.7)
ZenTest (4.5.0)
abstract (1.0.0)
- actionmailer (3.0.5)
- actionpack (= 3.0.5)
+ actionmailer (3.0.7)
+ actionpack (= 3.0.7)
mail (~> 2.2.15)
- actionpack (3.0.5)
- activemodel (= 3.0.5)
- activesupport (= 3.0.5)
+ actionpack (3.0.7)
+ activemodel (= 3.0.7)
+ activesupport (= 3.0.7)
builder (~> 2.1.2)
erubis (~> 2.6.6)
- i18n (~> 0.4)
+ i18n (~> 0.5.0)
rack (~> 1.2.1)
- rack-mount (~> 0.6.13)
+ rack-mount (~> 0.6.14)
rack-test (~> 0.5.7)
tzinfo (~> 0.3.23)
- activemodel (3.0.5)
- activesupport (= 3.0.5)
+ activemodel (3.0.7)
+ activesupport (= 3.0.7)
builder (~> 2.1.2)
- i18n (~> 0.4)
- activerecord (3.0.5)
- activemodel (= 3.0.5)
- activesupport (= 3.0.5)
+ i18n (~> 0.5.0)
+ activerecord (3.0.7)
+ activemodel (= 3.0.7)
+ activesupport (= 3.0.7)
arel (~> 2.0.2)
tzinfo (~> 0.3.23)
- activeresource (3.0.5)
- activemodel (= 3.0.5)
- activesupport (= 3.0.5)
- activesupport (3.0.5)
+ activeresource (3.0.7)
+ activemodel (= 3.0.7)
+ activesupport (= 3.0.7)
+ activesupport (3.0.7)
acts_as_list (0.1.2)
acts_as_state_machine (2.2.0)
activerecord (>= 2.1)
@@ -50,36 +50,36 @@ GEM
abstract (>= 1.0.0)
highline (1.6.1)
i18n (0.5.0)
- mail (2.2.15)
+ mail (2.2.19)
activesupport (>= 2.3.6)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
- mysql2 (0.2.6)
+ mysql2 (0.2.7)
permalink_fu (1.0.0)
polyglot (0.3.1)
rack (1.2.2)
- rack-mount (0.6.13)
+ rack-mount (0.6.14)
rack (>= 1.0.0)
rack-openid (1.3.1)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-test (0.5.7)
rack (>= 1.0)
- rails (3.0.5)
- actionmailer (= 3.0.5)
- actionpack (= 3.0.5)
- activerecord (= 3.0.5)
- activeresource (= 3.0.5)
- activesupport (= 3.0.5)
+ rails (3.0.7)
+ actionmailer (= 3.0.7)
+ actionpack (= 3.0.7)
+ activerecord (= 3.0.7)
+ activeresource (= 3.0.7)
+ activesupport (= 3.0.7)
bundler (~> 1.0)
- railties (= 3.0.5)
+ railties (= 3.0.7)
rails3-generators (0.17.4)
railties (>= 3.0.0)
- railties (3.0.5)
- actionpack (= 3.0.5)
- activesupport (= 3.0.5)
+ railties (3.0.7)
+ actionpack (= 3.0.7)
+ activesupport (= 3.0.7)
rake (>= 0.8.7)
thor (~> 0.14.4)
rake (0.8.7)
@@ -87,7 +87,7 @@ GEM
rspec-core (~> 2.5.0)
rspec-expectations (~> 2.5.0)
rspec-mocks (~> 2.5.0)
- rspec-core (2.5.1)
+ rspec-core (2.5.2)
rspec-expectations (2.5.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.5.0)
@@ -103,7 +103,7 @@ GEM
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
- tzinfo (0.3.25)
+ tzinfo (0.3.27)
PLATFORMS
ruby
@@ -115,10 +115,10 @@ DEPENDENCIES
autotest
bluecloth
highline
- mysql2
+ mysql2 (~> 0.2.7)
permalink_fu
rack-openid
- rails (= 3.0.5)
+ rails (= 3.0.7)
rails3-generators
rspec-rails
ruby-openid (>= 2.0.4)
View
13 app/controllers/application_controller.rb
@@ -4,9 +4,8 @@ class ApplicationController < ActionController::Base
include AuthenticatedSystem
helper_method :current_page
- before_filter :set_language
before_filter :login_required, :only => [:new, :edit, :create, :update, :destroy]
-
+
# See ActionController::RequestForgeryProtection for details
# Uncomment the :secret if you're not using the cookie session store
protect_from_forgery # :secret => 'e125a4be589f9d81263920581f6e4182'
@@ -15,15 +14,9 @@ class ApplicationController < ActionController::Base
rescue_from Site::UndefinedError do |e|
redirect_to new_site_path
end
-
- def current_page
- @page ||= params[:page].blank? ? 1 : params[:page].to_i
- end
- private
-
- def set_language
- I18n.locale = :en || I18n.default_locale
+ def current_page
+ @page ||= [1, params[:page].to_i].max
end
end
View
14 app/controllers/forums_controller.rb
@@ -1,5 +1,6 @@
class ForumsController < ApplicationController
before_filter :admin_required, :except => [:index, :show]
+ before_filter :find_forum, :only => [:show, :edit, :update, :destroy]
# GET /forums
# GET /forums.xml
@@ -18,7 +19,6 @@ def index
# GET /forums/1
# GET /forums/1.xml
def show
- @forum = current_site.forums.find_by_permalink!(params[:id])
(session[:forums] ||= {})[@forum.id] = Time.now.utc
(session[:forums_page] ||= Hash.new(1))[@forum.id] = current_page if current_page > 1
@@ -33,7 +33,7 @@ def show
# GET /forums/new
# GET /forums/new.xml
def new
- @forum = Forum.new
+ @forum = current_site.forums.new
respond_to do |format|
format.html # new.html.erb
@@ -43,7 +43,6 @@ def new
# GET /forums/1/edit
def edit
- @forum = current_site.forums.find_by_permalink!(params[:id])
end
# POST /forums
@@ -66,7 +65,6 @@ def create
# PUT /forums/1
# PUT /forums/1.xml
def update
- @forum = current_site.forums.find_by_permalink(params[:id])
respond_to do |format|
if @forum.update_attributes(params[:forum])
@@ -83,7 +81,6 @@ def update
# DELETE /forums/1
# DELETE /forums/1.xml
def destroy
- @forum = current_site.forums.find_by_permalink(params[:id])
@forum.destroy
respond_to do |format|
@@ -91,4 +88,11 @@ def destroy
format.xml { head :ok }
end
end
+
+ protected
+
+ def find_forum
+ @forum = current_site.forums.find_by_permalink!(params[:id])
+ end
+
end
View
8 app/controllers/monitorships_controller.rb
@@ -1,6 +1,8 @@
class MonitorshipsController < ApplicationController
before_filter :login_required
+ cache_sweeper :monitorships_sweeper
+
def create
@monitorship = Monitorship.find_or_initialize_by_user_id_and_topic_id(current_user.id, params[:topic_id])
@monitorship.update_attribute :active, true
@@ -9,12 +11,12 @@ def create
format.js
end
end
-
+
def destroy
- Monitorship.update_all ['active = ?', false], ['user_id = ? and topic_id = ?', current_user.id, params[:topic_id]]
+ Monitorship.where(:user_id => current_user.id, :topic_id => params[:topic_id]).update_all(:active => false)
respond_to do |format|
format.html { redirect_to topic_path(params[:forum_id], params[:topic_id]) }
format.js
end
end
-end
+end
View
35 app/controllers/posts_controller.rb
@@ -2,6 +2,8 @@ class PostsController < ApplicationController
before_filter :find_parents
before_filter :find_post, :only => [:edit, :update, :destroy]
+ cache_sweeper :posts_sweeper, :only => [:create, :update, :destroy]
+
# /posts
# /users/1/posts
# /forums/1/posts
@@ -70,22 +72,23 @@ def destroy
end
end
-protected
- def find_parents
- if params[:user_id]
- @parent = @user = User.find(params[:user_id])
- elsif params[:forum_id]
- @parent = @forum = Forum.find_by_permalink(params[:forum_id])
- @parent = @topic = @forum.topics.find_by_permalink(params[:topic_id]) if params[:topic_id]
+ protected
+
+ def find_parents
+ if params[:user_id]
+ @parent = @user = User.find(params[:user_id])
+ elsif params[:forum_id]
+ @parent = @forum = Forum.find_by_permalink(params[:forum_id])
+ @parent = @topic = @forum.topics.find_by_permalink(params[:topic_id]) if params[:topic_id]
+ end
end
- end
- def find_post
- post = @topic.posts.find(params[:id])
- if post.user == current_user || current_user.admin?
- @post = post
- else
- raise ActiveRecord::RecordNotFound
+ def find_post
+ post = @topic.posts.find(params[:id])
+ if post.user == current_user || current_user.admin?
+ @post = post
+ else
+ raise ActiveRecord::RecordNotFound
+ end
end
- end
-end
+end
View
80 app/controllers/sessions_controller.rb
@@ -2,7 +2,6 @@
class SessionsController < ApplicationController
skip_before_filter :login_required
- # render new.rhtml
def new
end
@@ -26,53 +25,52 @@ def destroy
end
protected
-
- def password_authentication(name, password)
- if @current_user = current_site.users.authenticate(name, password)
- successful_login
- else
- failed_login I18n.t('txt.invalid_login', :default => "Invalid login")
- end
- end
- def open_id_authentication(openid_url)
- authenticate_with_open_id(openid_url, :required => [:nickname, :email]) do |result, openid_url, registration|
- if result.successful?
- @user = User.find_or_initialize_by_openid_url(openid_url)
- @current_user = @user
- if @current_user
- if @user.new_record?
- @user.login = openid_url
- @user.email = registration['email']
- @user.password = 123456
- @user.site = Site.find(:first)
- @user.display_name = registration['nickname']
- @user.save(false)
- end
+ def password_authentication(name, password)
+ if @current_user = current_site.users.authenticate(name, password)
successful_login
else
- failed_login I18n.t('txt.invalid_openid', :default => "Sorry, no user by the identity URL #{openid_url} exists")
- end
- else
- failed_login result.message if openid_url
+ failed_login I18n.t('txt.invalid_login', :default => "Invalid login")
+ end
end
- end
- end
+ def open_id_authentication(openid_url)
+ authenticate_with_open_id(openid_url, :required => [:nickname, :email]) do |result, openid_url, registration|
+ if result.successful?
+ @user = User.find_or_initialize_by_openid_url(openid_url)
+ @current_user = @user
+ if @current_user
+ if @user.new_record?
+ @user.login = openid_url
+ @user.email = registration['email']
+ @user.password = 123456
+ @user.site = Site.first
+ @user.display_name = registration['nickname']
+ @user.save(false)
+ end
+ successful_login
+ else
+ failed_login I18n.t('txt.invalid_openid', :default => "Sorry, no user by the identity URL #{openid_url} exists")
+ end
+ else
+ failed_login result.message if openid_url
+ end
+ end
+ end
private
- def successful_login
- flash[:notice] = I18n.t 'txt.successful_login', :default => "Logged in successfully"
- new_cookie_flag = (params[:remember_me] == "1")
- handle_remember_cookie! new_cookie_flag
- session[:user_id] = @current_user.id
- redirect_back_or_default('/')
- end
- def failed_login(message)
- @remember_me = params[:remember_me]
- flash[:error] = message
- render :action => "new"
- end
+ def successful_login
+ flash[:notice] = I18n.t 'txt.successful_login', :default => "Logged in successfully"
+ new_cookie_flag = (params[:remember_me] == "1")
+ handle_remember_cookie! new_cookie_flag
+ session[:user_id] = @current_user.id
+ redirect_back_or_default('/')
+ end
+ def failed_login(message)
+ @remember_me = params[:remember_me]
+ flash[:error] = message
+ render :action => "new"
+ end
end
View
16 app/controllers/sites_controller.rb
@@ -1,5 +1,6 @@
class SitesController < ApplicationController
before_filter :admin_required
+ before_filter :find_site, :only => [:show, :edit, :update, :destroy]
def index
@sites = Site.paginate(:all, :page => current_page, :order => 'host ASC')
@@ -11,7 +12,6 @@ def index
end
def show
- @site = Site.find(params[:id])
respond_to do |format|
format.html # show.html.erb
@@ -29,7 +29,6 @@ def new
end
def edit
- @site = Site.find(params[:id])
end
def create
@@ -51,7 +50,6 @@ def create
end
def update
- @site = Site.find(params[:id])
respond_to do |format|
if @site.update_attributes(params[:site])
@@ -66,7 +64,6 @@ def update
end
def destroy
- @site = Site.find(params[:id])
@site.destroy
respond_to do |format|
@@ -74,8 +71,15 @@ def destroy
format.xml { head :ok }
end
end
-
+
def authorized?
- @site.nil? or @site.new_record? #or current_site == Site.find(:first)
+ @site.nil? or @site.new_record? # or current_site == Site.first
end
+
+ protected
+
+ def find_site
+ @site = Site.find(params[:id])
+ end
+
end
View
19 app/controllers/topics_controller.rb
@@ -11,7 +11,7 @@ def index
end
end
end
-
+
def edit
end
@@ -31,7 +31,7 @@ def show
end
def new
- @topic = Topic.new
+ @topic = @forum.topics.new
respond_to do |format|
format.html # new.html.erb
@@ -77,12 +77,13 @@ def destroy
end
end
-protected
- def find_forum
- @forum = current_site.forums.find_by_permalink(params[:forum_id])
- end
+ protected
+
+ def find_forum
+ @forum = current_site.forums.find_by_permalink!(params[:forum_id])
+ end
- def find_topic
- @topic = @forum.topics.find_by_permalink(params[:id])
- end
+ def find_topic
+ @topic = @forum.topics.find_by_permalink!(params[:id])
+ end
end
View
42 app/controllers/users_controller.rb
@@ -16,7 +16,6 @@ def index
end
end
- # render new.rhtml
def new
@user = User.new
end
@@ -37,12 +36,10 @@ def create
def settings
@user = current_user
- current_site
render :action => "edit"
end
-
+
def edit
- @user = find_user
end
def update
@@ -90,7 +87,7 @@ def purge
@user.destroy
redirect_to users_path
end
-
+
def make_admin
redirect_back_or_default('/') and return unless admin?
@user = find_user
@@ -99,22 +96,23 @@ def make_admin
redirect_to @user
end
-protected
- def find_user
- @user = if admin?
- current_site.all_users.find params[:id]
- elsif params[:id] == current_user.id
- current_user
- else
- current_site.users.find params[:id]
- end or raise ActiveRecord::RecordNotFound
- end
+ protected
- def authorized?
- admin? || params[:id].blank? || params[:id] == current_user.id.to_s
- end
+ def find_user
+ @user = if admin?
+ current_site.all_users.find params[:id]
+ elsif params[:id] == current_user.id
+ current_user
+ else
+ current_site.users.find params[:id]
+ end or raise ActiveRecord::RecordNotFound
+ end
- def render_or_redirect_for_captcha_failure
- render :action => 'new'
- end
-end
+ def authorized?
+ admin? || params[:id].blank? || params[:id] == current_user.id.to_s
+ end
+
+ def render_or_redirect_for_captcha_failure
+ render :action => 'new'
+ end
+end
View
21 app/helpers/application_helper.rb
@@ -5,6 +5,12 @@ def feed_icon_tag(title, url)
link_to image_tag('feed-icon.png', :size => '14x14', :alt => "Subscribe to #{title}"), url
end
+ def flash_messages
+ flash.map do |name, message|
+ content_tag :p, message, :class => [:notice, name].uniq.join(' ')
+ end.join.html_safe if flash.present?
+ end
+
def pagination(collection)
if collection.total_entries > 1
"<p class='pages'>" + I18n.t('txt.pages', :default => 'Pages') + ": <strong>" +
@@ -12,7 +18,7 @@ def pagination(collection)
"</strong></p>"
end
end
-
+
def next_page(collection)
unless collection.current_page == collection.total_entries or collection.total_entries == 0
"<p style='float:right;'>" + link_to(I18n.t('txt.next_page', :default => 'next page'), { :page => collection.current_page.next }.merge(params.reject{|k,v| k=="page"})) + "</p>"
@@ -20,18 +26,18 @@ def next_page(collection)
end
def search_posts_title
- (params[:q].blank? ? I18n.t('txt.recent_posts', :default => 'Recent Posts') : I18n.t('txt.searching_for', :default => 'Searching for') + " '#{h params[:q]}'").tap do |title|
- title << " " + I18n.t('txt.by_user', :default => 'by %{user}', :user => h(@user.display_name)) if @user
- title << " " + I18n.t('txt.in_forum', :default => 'in %{forum}', :forum => h(@forum.name)) if @forum
+ (params[:q].blank? ? I18n.t('txt.recent_posts', :default => 'Recent Posts') : I18n.t('txt.searching_for', :default => 'Searching for') + " '#{params[:q]}'").tap do |title|
+ title << " " + I18n.t('txt.by_user', :default => 'by %{user}', :user => @user.display_name) if @user
+ title << " " + I18n.t('txt.in_forum', :default => 'in %{forum}', :forum => @forum.name) if @forum
end
end
def topic_title_link(topic, options)
if topic.title =~ /^\[([^\]]{1,15})\]((\s+)\w+.*)/
"<span class='flag'>#{$1}</span>" +
- link_to(h($2.strip), forum_topic_path(@forum, topic), options)
+ link_to($2.strip, forum_topic_path(@forum, topic), options)
else
- link_to(h(topic.title), forum_topic_path(@forum, topic), options)
+ link_to(topic.title, forum_topic_path(@forum, topic), options)
end
end
@@ -62,7 +68,6 @@ def search_path(atom = false)
end
def for_moderators_of(record, &block)
- moderator_of?(record) && concat(capture(&block))
+ capture(&block) if moderator_of?(record)
end
-
end
View
22 app/helpers/error_messages_helper.rb
@@ -0,0 +1,22 @@
+module ErrorMessagesHelper
+ # Render error messages for the given objects. The :message and :header_message options are allowed.
+ def error_messages_for(*objects)
+ options = objects.extract_options!
+ options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.")
+ messages = objects.compact.map { |o| o.errors.full_messages }.flatten
+ unless messages.empty?
+ content_tag(:div, :class => "error_messages") do
+ list_items = messages.map { |msg| content_tag(:li, msg.html_safe) }
+ content_tag(:h2, options[:message].html_safe) + content_tag(:ul, list_items.join.html_safe)
+ end
+ end
+ end
+
+ module FormBuilderAdditions
+ def error_messages(options = {})
+ @template.error_messages_for(@object, options)
+ end
+ end
+end
+
+ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions)
View
5 app/helpers/forums_helper.rb
@@ -10,14 +10,13 @@ def recent_forum_activity(forum)
return false unless logged_in? && forum.recent_topic
return forum.recent_topic.last_updated_at > ((session[:forums] ||= {})[forum.id] || last_active)
end
-
+
def last_active
session[:last_active] ||= Time.now.utc
end
-
+
# Ripe for optimization
def voice_count
pluralize current_site.topics.to_a.sum { |t| t.voice_count }, 'voice'
end
-
end
View
19 app/helpers/users_helper.rb
@@ -7,13 +7,13 @@ def user_count
# todo: cache this?
def active_user_count
- count = current_site.users.count(:conditions => "posts_count > 0")
+ count = current_site.users.where("posts_count > 0").count
I18n.t 'txt.count_users_active', :count => count, :num => number_with_delimiter(count)
end
-
+
# todo: cache this?
def lurking_user_count
- count = current_site.users.count(:conditions => "posts_count = 0")
+ count = current_site.users.where(:posts_count => 0).count
I18n.t 'txt.count_users_lurking', :count => count, :num => number_with_delimiter(count)
end
@@ -60,13 +60,13 @@ def if_authorized?(action, resource, &block)
# link_to_user @user, :content_text => 'Your user page'
# # => <a href="/users/3" title="barmy" class="nickname">Your user page</a>
#
- def link_to_user(user, options={})
+ def link_to_user(user, options = {})
raise "Invalid user" unless user
options.reverse_merge! :content_method => :login, :title_method => :login, :class => :nickname
content_text = options.delete(:content_text)
content_text ||= user.send(options.delete(:content_method))
options[:title] ||= user.send(options.delete(:title_method))
- link_to h(content_text), user_path(user), options
+ link_to content_text, user_path(user), options
end
#
@@ -81,14 +81,14 @@ def link_to_user(user, options={})
# link_to_login_with_IP :content_text => 'not signed in'
# # => <a href="/login" title="169.69.69.69">not signed in</a>
#
- def link_to_login_with_IP content_text=nil, options={}
+ def link_to_login_with_IP(content_text = nil, options = {})
ip_addr = request.remote_ip
content_text ||= ip_addr
options.reverse_merge! :title => ip_addr
if tag = options.delete(:tag)
- content_tag tag, h(content_text), options
+ content_tag tag, content_text, options
else
- link_to h(content_text), login_path, options
+ link_to content_text, login_path, options
end
end
@@ -96,7 +96,7 @@ def link_to_login_with_IP content_text=nil, options={}
# Link to the current user's page (using link_to_user) or to the login page
# (using link_to_login_with_IP).
#
- def link_to_current_user(options={})
+ def link_to_current_user(options = {})
if current_user
link_to_user current_user, options
else
@@ -106,5 +106,4 @@ def link_to_current_user(options={})
link_to_login_with_IP content_text, options
end
end
-
end
View
22 app/mailers/user_mailer.rb
@@ -0,0 +1,22 @@
+# coding: utf-8
+class UserMailer < ActionMailer::Base
+ default :from => "your_domain@example.com"
+
+ def signup_notification(user)
+ @user = user
+ @url = activate_url(user.activation_code, :host => user.site.host)
+ mail :to => user.email, :subject => subject(user, "Please activate your new account")
+ end
+
+ def activation(user)
+ @user = user
+ @url = root_url(:host => user.site.host)
+ mail :to => user.email, :subject => subject(user, "Your account has been activated!")
+ end
+
+ protected
+
+ def subject(user, text)
+ [user.site.name, text] * ""
+ end
+end
View
17 app/models/forum.rb
@@ -1,14 +1,14 @@
class Forum < ActiveRecord::Base
formats_attributes :description
-
+
acts_as_list
validates_presence_of :name
-
+
belongs_to :site
-
+
has_permalink :name
-
+
attr_readonly :posts_count, :topics_count
has_many :topics, :order => "#{Topic.table_name}.sticky desc, #{Topic.table_name}.last_updated_at desc", :dependent => :delete_all
@@ -17,7 +17,7 @@ class Forum < ActiveRecord::Base
# stickies first even if they are not the most recently modified
has_many :recent_topics, :class_name => 'Topic', :include => [:user],
:order => "#{Topic.table_name}.last_updated_at DESC",
- :conditions => ["users.state == ?", "active"]
+ :conditions => ["users.state = ?", "active"]
has_one :recent_topic, :class_name => 'Topic', :order => "#{Topic.table_name}.last_updated_at DESC"
has_many :posts, :order => "#{Post.table_name}.created_at DESC", :dependent => :delete_all
@@ -26,11 +26,8 @@ class Forum < ActiveRecord::Base
has_many :moderatorships, :dependent => :delete_all
has_many :moderators, :through => :moderatorships, :source => :user
- # oh has_finder i eagerly await thee
- def self.ordered
- find :all, :order => 'position'
- end
-
+ scope :ordered, order(:position)
+
def to_param
permalink
end
View
26 app/models/moderatorship.rb
@@ -1,20 +1,22 @@
class Moderatorship < ActiveRecord::Base
belongs_to :user
belongs_to :forum
- validates_presence_of :user_id, :forum_id
+
+ validates :user_id, :forum_id, :presence => true
validate :uniqueness_of_relationship
validate :user_and_forum_in_same_site
-
-protected
- def uniqueness_of_relationship
- if self.class.exists?(:user_id => user_id, :forum_id => forum_id)
- errors.add_to_base("Cannot add duplicate user/forum relation")
+
+ protected
+
+ def uniqueness_of_relationship
+ if self.class.exists?(:user_id => user_id, :forum_id => forum_id)
+ errors.add(:base, "Cannot add duplicate user/forum relation")
+ end
end
- end
-
- def user_and_forum_in_same_site
- if user && forum && user.site_id != forum.site_id
- errors.add_to_base("User and Forum must be in the same Site.")
+
+ def user_and_forum_in_same_site
+ if user && forum && user.site_id != forum.site_id
+ errors.add(:base, "User and Forum must be in the same Site")
+ end
end
- end
end
View
31 app/models/monitorship.rb
@@ -1,26 +1,27 @@
class Monitorship < ActiveRecord::Base
belongs_to :user
belongs_to :topic
-
- validates_presence_of :user_id, :topic_id
+
+ validates :user_id, :topic_id, :presence => true
validate :uniqueness_of_relationship
before_create :check_for_inactive
-
+
attr_accessible :user_id, :topic_id
-protected
- def uniqueness_of_relationship
- if self.class.exists?(:user_id => user_id, :topic_id => topic_id, :active => true)
- errors.add_to_base("Cannot add duplicate user/topic relation")
+ protected
+
+ def uniqueness_of_relationship
+ if self.class.exists?(:user_id => user_id, :topic_id => topic_id, :active => true)
+ errors.add(:base, "Cannot add duplicate user/topic relation")
+ end
end
- end
- def check_for_inactive
- monitorship = self.class.find_by_user_id_and_topic_id_and_active(user_id, topic_id, false)
- if monitorship
- monitorship.active = true
- monitorship.save
- false
+ def check_for_inactive
+ monitorship = self.class.find_by_user_id_and_topic_id_and_active(user_id, topic_id, false)
+ if monitorship
+ monitorship.active = true
+ monitorship.save
+ false
+ end
end
- end
end
View
33 app/models/post.rb
@@ -1,19 +1,19 @@
class Post < ActiveRecord::Base
include User::Editable
-
+
formats_attributes :body
# author of post
belongs_to :user, :counter_cache => true
-
+
belongs_to :topic, :counter_cache => true
-
+
# topic's forum (set by callback)
belongs_to :forum, :counter_cache => true
-
+
# topic's site (set by callback)
belongs_to :site, :counter_cache => true
-
+
validates_presence_of :user_id, :site_id, :topic_id, :forum_id, :body
validate :topic_is_not_locked
@@ -22,12 +22,8 @@ class Post < ActiveRecord::Base
attr_accessible :body
- def forum_name
- forum.name
- end
-
def self.search(query, options = {})
- # had to change the other join string since it conflicts when we bring parents in
+ # had to change the other join string since it conflicts when we bring parents in
options[:conditions] ||= ["LOWER(#{Post.table_name}.body) LIKE ?", "%#{query}%"] unless query.blank?
options[:select] ||= "#{Post.table_name}.*, #{Topic.table_name}.title as topic_title, f.name as forum_name"
options[:joins] ||= "inner join #{Topic.table_name} on #{Post.table_name}.topic_id = #{Topic.table_name}.id " +
@@ -37,12 +33,17 @@ def self.search(query, options = {})
paginate options
end
-protected
- def update_cached_fields
- topic.update_cached_post_fields(self)
+ def forum_name
+ forum.name
end
+
+ protected
+
+ def update_cached_fields
+ topic.update_cached_post_fields(self)
+ end
- def topic_is_not_locked
- errors.add_to_base("Topic is locked") if topic && topic.locked? && topic.posts_count > 0
- end
+ def topic_is_not_locked
+ errors.add(:base, "Topic is locked") if topic && topic.locked? && topic.posts_count > 0
+ end
end
View
12 app/models/posts_sweeper.rb
@@ -1,12 +0,0 @@
-class PostsSweeper < ActionController::Caching::Sweeper
- observe Post
-
- def after_save(post)
- FileUtils.rm_rf File.join(Rails.root, 'public', 'forums', post.forum_id.to_s, 'posts.rss')
- FileUtils.rm_rf File.join(Rails.root, 'public', 'forums', post.forum_id.to_s, 'topics', "#{post.topic_id}.rss")
- FileUtils.rm_rf File.join(Rails.root, 'public', 'users')
- FileUtils.rm_rf File.join(Rails.root, 'public', 'posts.rss')
- end
-
- alias_method :after_destroy, :after_save
-end
View
42 app/models/site.rb
@@ -3,38 +3,40 @@ class UndefinedError < StandardError; end
has_many :users, :conditions => {:state => 'active'}
has_many :all_users, :class_name => 'User'
-
+
has_many :forums
has_many :topics, :through => :forums
has_many :posts, :through => :forums
-
+
validates_presence_of :name
validates_uniqueness_of :host
-
+
attr_readonly :posts_count, :users_count, :topics_count
-
- def host=(value)
- write_attribute :host, value.to_s.downcase
- end
-
- def self.main
- @main ||= find :first, :conditions => {:host => ''}
+
+ class << self
+
+ def main
+ @main ||= where(:host => '').first
+ end
+
+ def find_by_host(name)
+ return nil if name.nil?
+ name.downcase! && name.strip! && name.sub!(/^www\./, '')
+ sites = where('host = ? or host = ?', name, '')
+ sites.reject(&:default?).first || sites.first
+ end
+
end
-
- def self.find_by_host(name)
- return nil if name.nil?
- name.downcase!
- name.strip!
- name.sub! /^www\./, ''
- sites = find :all, :conditions => ['host = ? or host = ?', name, '']
- sites.reject { |s| s.default? }.first || sites.first
+
+ def host=(value)
+ write_attribute(:host, value.to_s.downcase)
end
-
+
# <3 rspec
def ordered_forums(*args)
forums.ordered(*args)
end
-
+
def default?
host.blank?
end
View
83 app/models/topic.rb
@@ -2,7 +2,6 @@ class Topic < ActiveRecord::Base
include User::Editable
before_validation :set_default_attributes, :on => :create
- validates_presence_of :title
after_create :create_initial_post
before_update :check_for_moved_forum
@@ -12,12 +11,12 @@ class Topic < ActiveRecord::Base
# creator of forum topic
belongs_to :user
-
+
# creator of recent post
belongs_to :last_user, :class_name => "User"
-
+
belongs_to :forum, :counter_cache => true
-
+
# forum's site, set by callback
belongs_to :site, :counter_cache => true
@@ -36,7 +35,7 @@ class Topic < ActiveRecord::Base
attr_accessible :title, :body
attr_readonly :posts_count, :hits
-
+
has_permalink :title, :scope => :forum_id
def to_s
@@ -54,7 +53,7 @@ def hit!
def paged?
posts_count > Post.per_page
end
-
+
def last_page
[(posts_count.to_f / Post.per_page.to_f).ceil.to_i, 1].max
end
@@ -62,51 +61,51 @@ def last_page
def update_cached_post_fields(post)
# these fields are not accessible to mass assignment
if remaining_post = post.frozen? ? recent_post : post
- self.class.update_all(['last_updated_at = ?, last_user_id = ?, last_post_id = ?, posts_count = ?',
- remaining_post.created_at, remaining_post.user_id, remaining_post.id, posts.count], ['id = ?', id])
+ self.class.where(:id => id).update_all(:last_updated_at => remaining_post.created_at, :last_user_id => remaining_post.user_id, :last_post_id => remaining_post.id, :posts_count => posts.count)
else
destroy
end
end
-
+
def to_param
permalink
end
-protected
- def create_initial_post
- user.reply self, @body #unless locked?
- @body = nil
- end
-
- def set_default_attributes
- self.site_id = forum.site_id if forum_id
- self.sticky ||= 0
- self.last_updated_at ||= Time.now.utc
- end
+ protected
- def check_for_moved_forum
- old = Topic.find(id)
- @old_forum_id = old.forum_id if old.forum_id != forum_id
- true
- end
+ def create_initial_post
+ user.reply self, @body # unless locked?
+ @body = nil
+ end
- def set_post_forum_id
- return unless @old_forum_id
- posts.update_all :forum_id => forum_id
- Forum.update_all "posts_count = posts_count - #{posts_count}", ['id = ?', @old_forum_id]
- Forum.update_all "posts_count = posts_count + #{posts_count}", ['id = ?', forum_id]
- end
-
- def count_user_posts_for_counter_cache
- @user_posts = posts.group_by { |p| p.user_id }
- end
-
- def update_cached_forum_and_user_counts
- Forum.update_all "posts_count = posts_count - #{posts_count}", ['id = ?', forum_id]
- Site.update_all "posts_count = posts_count - #{posts_count}", ['id = ?', site_id]
- @user_posts.each do |user_id, posts|
- User.update_all "posts_count = posts_count - #{posts.size}", ['id = ?', user_id]
+ def set_default_attributes
+ self.site_id = forum.site_id if forum_id
+ self.sticky ||= 0
+ self.last_updated_at ||= Time.now.utc
+ end
+
+ def check_for_moved_forum
+ old = Topic.find(id)
+ @old_forum_id = old.forum_id if old.forum_id != forum_id
+ true
+ end
+
+ def set_post_forum_id
+ return unless @old_forum_id
+ posts.update_all(:forum_id => forum_id)
+ Forum.where(:id => @old_forum_id).update_all("posts_count = posts_count - #{posts_count}")
+ Forum.where(:id => forum_id).update_all("posts_count = posts_count + #{posts_count}")
+ end
+
+ def count_user_posts_for_counter_cache
+ @user_posts = posts.group_by { |p| p.user_id }
+ end
+
+ def update_cached_forum_and_user_counts
+ Forum.where(:id => forum_id).update_all("posts_count = posts_count - #{posts_count}")
+ Site.where(:id => site_id).update_all("posts_count = posts_count - #{posts_count}")
+ @user_posts.each do |user_id, posts|
+ User.where(:id => user_id).update_all("posts_count = posts_count - #{posts.size}")
+ end
end
- end
end
View
46 app/models/user.rb
@@ -4,34 +4,37 @@ class User < ActiveRecord::Base
belongs_to :site, :counter_cache => true
validates_presence_of :site_id
-
+
has_many :posts, :order => "#{Post.table_name}.created_at desc"
has_many :topics, :order => "#{Topic.table_name}.created_at desc"
-
+
has_many :moderatorships, :dependent => :delete_all
has_many :forums, :through => :moderatorships, :source => :forum do
def moderatable
- all :select => "#{Forum.table_name}.*, #{Moderatorship.table_name}.id as moderatorship_id"
+ select("#{Forum.table_name}.*, #{Moderatorship.table_name}.id as moderatorship_id")
end
end
-
+
has_many :monitorships, :dependent => :delete_all
has_many :monitored_topics, :through => :monitorships, :source => :topic, :conditions => {"#{Monitorship.table_name}.active" => true}
-
+
has_permalink :login, :scope => :site_id
-
+
attr_readonly :posts_count, :last_seen_at
- scope :named_like, lambda {|name|
- { :conditions => ["users.display_name like ? or users.login like ?",
- "#{name}%", "#{name}%"] }}
+ scope :named_like, lambda { |name| where("users.display_name like ? or users.login like ?", "#{name}%", "#{name}%") }
+ scope :online, lambda { where("users.last_seen_at >= ?", 10.minutes.ago.utc) }
+
+ class << self
+
+ def prefetch_from(records)
+ select("distinct *").where(:id => records.collect(&:user_id).uniq)
+ end
+
+ def index_from(records)
+ prefetch_from(records).index_by(&:id)
+ end
- def self.prefetch_from(records)
- find(:all, :select => 'distinct *', :conditions => ['id in (?)', records.collect(&:user_id).uniq])
- end
-
- def self.index_from(records)
- prefetch_from(records).index_by(&:id)
end
def available_forums
@@ -48,7 +51,7 @@ def display_name
end
alias_method :to_s, :display_name
-
+
# this is used to keep track of the last time a user has been seen (reading a topic)
# it is used to know when topics are new or old and which should have the green
# activity light next to them
@@ -60,10 +63,10 @@ def display_name
# session based approach, but less code and less overhead.
def seen!
now = Time.now.utc
- self.class.update_all ['last_seen_at = ?', now], ['id = ?', id]
- write_attribute :last_seen_at, now
+ self.class.where(:id => id).update_all(:last_seen_at => now)
+ write_attribute(:last_seen_at, now)
end
-
+
def to_param
id.to_s # permalink || login
end
@@ -75,11 +78,10 @@ def openid_url=(value)
def using_openid
self.openid_url.blank? ? false : true
end
-
+
def to_xml(options = {})
options[:except] ||= []
- options[:except] << :email << :login_key << :login_key_expires_at << :password_hash << :openid_url << :activated << :admin
+ options[:except] += [:email, :login_key, :login_key_expires_at, :password_hash, :openid_url, :activated, :admin]
super
end
-
end
View
2  app/models/user/editable.rb
@@ -3,4 +3,4 @@ def editable_by?(user, is_moderator = nil)
is_moderator = user.moderator_of?(forum) if is_moderator.nil?
user && (user.id == user_id || is_moderator)
end
-end
+end
View
16 app/models/user/posting.rb
@@ -5,7 +5,6 @@ class User
# - changes forum_id if you're an admin
#
def post(forum, attributes)
- attrs = attributes.to_hash.symbolize_keys
Topic.new(attributes) do |topic|
topic.forum = forum
topic.user = self
@@ -21,7 +20,7 @@ def reply(topic, body)
post.save
end
end
-
+
def revise(record, attributes)
is_moderator = moderator_of?(record.forum)
return unless record.editable_by?(self, is_moderator)
@@ -33,10 +32,11 @@ def revise(record, attributes)
record
end
-protected
- def revise_topic(topic, attributes, is_moderator)
- topic.title = attributes[:title] if attributes.key?(:title)
- topic.sticky, topic.locked = attributes[:sticky], attributes[:locked] if is_moderator
- topic.save
- end
+ protected
+
+ def revise_topic(topic, attributes, is_moderator)
+ topic.title = attributes[:title] if attributes.key?(:title)
+ topic.sticky, topic.locked = attributes[:sticky], attributes[:locked] if is_moderator
+ topic.save
+ end
end
View
49 app/models/user/states.rb
@@ -5,29 +5,29 @@ class User
state :active, :enter => :do_activate
state :suspended
state :deleted, :enter => :do_delete
-
+
event :register do
transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) }
end
-
+
event :activate do
transitions :from => :pending, :to => :active
end
-
+
event :suspend do
transitions :from => [:passive, :pending, :active], :to => :suspended, :guard => :remove_moderatorships
end
-
+
event :delete do
transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted
end
-
+
event :unsuspend do
transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| !u.activated_at.blank? }
transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? }
transitions :from => :suspended, :to => :passive
end
-
+
def self.authenticate(login, password)
return nil if login.blank? || password.blank?
u = find_in_state :first, :active, :conditions => {:login => login}
@@ -37,25 +37,26 @@ def self.authenticate(login, password)
def do_activation
self.deleted_at = nil
self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
-
- UserMailer.deliver_signup_notification(self) unless using_openid
- end
-protected
- def do_delete
- self.deleted_at = Time.now.utc
+ UserMailer.signup_notification(self).deliver unless using_openid
end
- def do_activate
- @activated = true
- self.activated_at = Time.now.utc
- self.deleted_at = nil
- self.activation_code = ""
-
- UserMailer.deliver_activation(self) unless using_openid
- end
-
- def remove_moderatorships
- moderatorships.delete_all
- end
+ protected
+
+ def do_delete
+ self.deleted_at = Time.now.utc
+ end
+
+ def do_activate
+ @activated = true
+ self.activated_at = Time.now.utc
+ self.deleted_at = nil
+ self.activation_code = ""
+
+ UserMailer.activation(self).deliver unless using_openid
+ end
+
+ def remove_moderatorships
+ moderatorships.delete_all
+ end
end
View
56 app/models/user/validation.rb
@@ -14,7 +14,7 @@ class User
validates_uniqueness_of :login, :email, :scope => :site_id
before_save :encrypt_password
before_create :set_first_user_as_admin
- # validates_email_format_of :email, :message=>"is invalid"
+ # validates_email_format_of :email, :message=>"is invalid"
validates_uniqueness_of :openid_url, :case_sensitive => false, :allow_nil => true
# prevents a user from submitting a crafted form that bypasses activation
@@ -36,31 +36,31 @@ def authenticated?(password)
crypted_password == encrypt(password)
end
-protected
- # before filter
- def encrypt_password
- return if password.blank?
- self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
- self.crypted_password = encrypt(password)
- end
-
- def using_openid
- self.openid_url.blank? ? false : true
- end
-
- def password_required?
- return false if using_openid
- crypted_password.blank? || !password.blank?
- end
-
- def set_first_user_as_admin
- self.admin = true if site and site.users.size.zero?
- end
-
- def normalize_login_and_email
- login.downcase! if login
- login.strip! if login
- email.downcase! if email
- return true
- end
+ protected
+
+ # before filter
+ def encrypt_password
+ return if password.blank?
+ self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
+ self.crypted_password = encrypt(password)
+ end
+
+ def using_openid
+ self.openid_url.blank? ? false : true
+ end
+
+ def password_required?
+ return false if using_openid
+ crypted_password.blank? || password.present?
+ end
+
+ def set_first_user_as_admin
+ self.admin = true if site && site.users.size.zero?
+ end
+
+ def normalize_login_and_email
+ login.downcase! && login.strip! if login
+ email.downcase! if email
+ return true
+ end
end
View
22 app/models/user_mailer.rb
@@ -1,22 +0,0 @@
-class UserMailer < ActionMailer::Base
- def signup_notification(user)
- setup_email(user)
- @subject += 'Please activate your new account'
- @body[:url] = activate_url(user.activation_code, :host => user.site.host)
- end
-
- def activation(user)
- setup_email(user)
- @subject += 'Your account has been activated!'
- @body[:url] = root_url(:host => user.site.host)
- end
-
- protected
- def setup_email(user)
- @recipients = "#{user.email}"
- @from = "ADMINEMAIL"
- @subject = "[YOURSITE] "
- @sent_on = Time.now
- @body[:user] = user
- end
-end
View
8 app/models/monitorships_sweeper.rb → app/sweepers/monitorships_sweeper.rb
@@ -1,9 +1,9 @@
class MonitorshipsSweeper < ActionController::Caching::Sweeper
observe Monitorship
-
+
def after_save(monitorship)
- FileUtils.rm_rf File.join(Rails.root, 'public', 'users', monitorship.user_id.to_s)
+ FileUtils.rm_rf Rails.root.join('public', 'users', monitorship.user_id.to_s)
end
-
+
alias_method :after_destroy, :after_save
-end
+end
View
12 app/sweepers/posts_sweeper.rb
@@ -0,0 +1,12 @@
+class PostsSweeper < ActionController::Caching::Sweeper
+ observe Post
+
+ def after_save(post)
+ FileUtils.rm_rf Rails.root.join('public', 'forums', post.forum_id.to_s, 'posts.rss')
+ FileUtils.rm_rf Rails.root.join('public', 'forums', post.forum_id.to_s, 'topics', "#{post.topic_id}.rss")
+ FileUtils.rm_rf Rails.root.join('public', 'users')
+ FileUtils.rm_rf Rails.root.join('public', 'posts.rss')
+ end
+
+ alias_method :after_destroy, :after_save
+end
View
34 app/views/forums/_form.html.erb
@@ -1,21 +1,19 @@
-<p style="float:right; margin-top:0">
-</p>
-
-<p id="forum_name">
-
-<table border="0" cellspacing="0" cellpadding="0" class="noborder nopad wide">
- <td>
- <label><%= I18n.t 'txt.views_forums.title', :default => 'Title' %></label><br />
- <%= form.text_field :name, :class => "primary" %>
- </td>
- <td style="text-align:right">
- <label><%= I18n.t 'txt.views_forums.position', :default => 'Position' %></label><br />
- <%= form.text_field :position, :size => 5 %>
+<%= form.error_messages %>
- </td>
-</table>
+<div id="forum_name">
+ <table border="0" cellspacing="0" cellpadding="0" class="noborder nopad wide">
+ <td>
+ <label><%= I18n.t 'txt.views_forums.title', :default => 'Title' %></label><br />
+ <%= form.text_field :name, :class => "primary" %>
+ </td>
+ <td style="text-align:right">
+ <label><%= I18n.t 'txt.views_forums.position', :default => 'Position' %></label><br />
+ <%= form.text_field :position, :size => 5 %>
+ </td>
+ </table>
+</div>
-</p>
<p id="forum_descripion">
-<label><%= I18n.t 'txt.views_forums.desc', :default => 'Description' %></label><br />
-<%= form.text_area :description, :rows => 7 %></p>
+ <label><%= I18n.t 'txt.views_forums.desc', :default => 'Description' %></label><br />
+ <%= form.text_area :description, :rows => 7 %>
+</p>
View
12 app/views/forums/edit.html.erb
@@ -2,11 +2,9 @@
<%= link_to I18n.t('txt.forums', :default => 'Forums'), root_path %> <span class="arrow">&rarr;</span>
</div>
-<h1><%= I18n.t 'txt.views_forums.edit', :default => 'Edit Forum' %></h1>
+<h1><%= I18n.t('txt.views_forums.edit', :default => 'Edit Forum') %></h1>
-<%= form_for :forum,
- :url => forum_path(@forum),
- :html => { :method => :put } do |f| -%>
-<%= render :partial => "form", :object => f %>
-<%= submit_tag I18n.t('txt.save', :default => 'Save Forum') %> <%= I18n.t 'txt.or', :default => 'or' %> <%= link_to(I18n.t('txt.cancel', :default => 'Cancel'), forums_path) %>
-<% end -%>
+<%= form_for @forum do |f| %>
+ <%= render :partial => "form", :object => f %>
+ <%= submit_tag I18n.t('txt.save', :default => 'Save Forum') %> <%= I18n.t 'txt.or', :default => 'or' %> <%= link_to(I18n.t('txt.cancel', :default => 'Cancel'), forums_path) %>
+<% end %>
View
19 app/views/forums/index.html.erb
@@ -36,7 +36,7 @@
<% end %>
</td>
<td class="c2 vat">
- <%= link_to h(forum.name), forum_path(forum), :class => "title" %>
+ <%= link_to forum.name, forum_path(forum), :class => "title" %>
<div class="posts">
<%= I18n.t 'txt.count_topics', :count => forum.topics.size, :num => number_with_delimiter(forum.topics.size) %>,
<%= I18n.t 'txt.count_posts', :count => forum.posts.size, :num => number_with_delimiter(forum.posts.size) %>
@@ -48,11 +48,11 @@
</td>
<td class="inv lp">
- <% if forum.recent_post -%>
+ <% if forum.recent_post %>
<%= I18n.t 'txt.post_age', :when => time_ago_in_words(forum.recent_post.created_at), :default => "posted %{when} ago" %><br />
- <strong><%= I18n.t 'txt.by_user', :default => 'by %{user}', :user => "#{h(forum.recent_post.user.display_name)}" %></strong>
+ <strong><%= I18n.t 'txt.by_user', :default => 'by %{user}', :user => forum.recent_post.user.display_name %></strong>
<span>(<%= link_to I18n.t('txt.view', :default => 'view'), forum_topic_path(forum, forum.recent_post.topic, :page => forum.recent_post.topic.last_page, :anchor => dom_id(forum.recent_post)) %>)</span>
- <% end -%>
+ <% end %>
</td>
</tr>
<% end %>
@@ -62,13 +62,10 @@
<%= link_to I18n.t('txt.show_recent_posts', :default => 'Show recent posts'), posts_path %>
</p>
-<%# TODO: online_users = User.currently_online -%>
-<% if false # TODO: unless online_users.empty? %>
+<% if (online_users = User.online).length > 0 %>
<div class="stats">
-<div class="users">
-<% unless online_users.empty? %>
-<%= 'Users online:'[:users_online] %> <%= online_users.map { |u| link_to "<strong>#{h u.display_name}</strong>", user_path(u) } * ", " %><br />
-<% end %>
-</div>
+ <div class="users">
+ <%= I18n.t('txt.users_online', :default => 'Users online') %>: <%= (online_users.map { |u| link_to content_tag(:strong, u.display_name), user_path(u) } * ", ").html_safe %><br />
+ </div>
</div>
<% end %>
View
8 app/views/forums/new.html.erb
@@ -4,7 +4,7 @@
<h1><%= I18n.t('txt.views_forums.new', :default => 'New Forum') %></h1>
-<%= form_for :forum, :url => forums_path do |f| -%>
-<%= render :partial => "form", :object => f %>
-<%= submit_tag I18n.t('txt.create', :default =>'Create') %> <%= I18n.t 'txt.or', :default => 'or' %> <%= link_to(I18n.t('txt.cancel', :default => 'Cancel'), forums_path) %>
-<% end -%>
+<%= form_for @forum do |f| %>
+ <%= render :partial => "form", :object => f %>
+ <%= submit_tag I18n.t('txt.create', :default =>'Create') %> <%= I18n.t 'txt.or', :default => 'or' %> <%= link_to(I18n.t('txt.cancel', :default => 'Cancel'), forums_path) %>
+<% end %>
View
30 app/views/forums/show.html.erb
@@ -7,15 +7,15 @@
<h5 style="margin-bottom:1.0em;"><%= I18n.t 'txt.moderator', :count => @forum.moderators.size, :default => 'Moderator' %></h5>
-<% unless @forum.moderators.empty? -%>
+<% unless @forum.moderators.empty? %>
<ul class="flat" style="margin-top:1em;">
-<% @forum.moderators.each do |user| -%>
- <li><%= link_to h(user.display_name || user.login), user %></li>
-<% end -%>
+<% @forum.moderators.each do |user| %>
+ <li><%= link_to user.display_name || user.login, user %></li>
+<% end %>
</ul>
-<% else -%>
+<% else %>
<p><%= I18n.t 'txt.views_forums.unmoderated_html', :default => 'This forum is currently unmoderated.<br />Please always be courteous.'.html_safe %></p>
-<% end -%>
+<% end %>
<% end %>
@@ -24,7 +24,7 @@
<div class="crumbs">
<%= link_to I18n.t('txt.forums', :default => 'Forums'), root_path %> <span class="arrow">&rarr;</span>
</div>
-<h1 style="margin-top:0.5em"><%= h @forum.name %></h1>
+<h1 style="margin-top:0.5em"><%= @forum.name %></h1>
<p class="subtitle">
<%= feed_icon_tag @forum.name, forum_posts_path(@forum, :format => :atom) %>
@@ -32,12 +32,12 @@
<%= I18n.t 'txt.count_posts', :count => @forum.posts.size, :num => number_with_delimiter(@forum.posts.size) %>
</p>
-<% if @topics.total_entries -%>
+<% if @topics.total_entries %>
<% if logged_in? %>
<p style="float:right; margin-top:0;"><%= link_to I18n.t('txt.new_topic', :default => 'New topic'), new_forum_topic_path(@forum), :class => "utility" %></p>
<% end %>
<%= will_paginate @topics %>
-<% end -%>
+<% end %>
<table border="0" cellspacing="0" cellpadding="0" class="wide topics">
<tr>
@@ -65,20 +65,20 @@
<% end %>
</td>
<td class="c2">
- <%= I18n.t('txt.sticky', :default => ('[sticky]' + '<strong>')) if topic.sticky? %>
+ <%= I18n.t('txt.sticky', :default => ('[sticky]' + '<strong>')).html_safe if topic.sticky? %>
<%= topic_title_link (topic), :class => "entry-title", :rel => "bookmark" %>
- <%= "</strong>" if topic.sticky? %>
- <% if topic.paged? -%>
+ <%= '</strong>'.html_safe if topic.sticky? %>
+ <% if topic.paged? %>
<small><%= link_to I18n.t('txt.goto_last_page', :default => 'last'), forum_topic_path(@forum, topic, :page => topic.last_page) %></small>
- <% end -%>
+ <% end %>
</td>
<td class="ca inv stat"><%= topic.posts.size %></td>
<td class="ca inv stat"><%= number_with_delimiter(topic.hits) %></td>
<td class="lp">
<abbr class="updated" title="<%= topic.last_updated_at.xmlschema %>"><%= I18n.t 'txt.post_age', :when => time_ago_in_words(topic.last_updated_at), :default => "posted %{when} ago" %></abbr>
- <% if topic.last_user -%>
+ <% if topic.last_user %>
<%= I18n.t 'txt.by_user_html', :default => 'by %{user}'.html_safe, :user => "<span class=\"author\"><strong class=\"fn\">#{h(topic.last_user.display_name)}</strong></span>" %>
- <% end -%>
+ <% end %>
<span><%= link_to I18n.t('txt.view', :default => 'view'), forum_topic_path(@forum, topic, :page => topic.last_page, :anchor => dom_id(topic.recent_post)) %></span>
</td>
</tr>
View
16 app/views/layouts/_footer.html.erb
@@ -0,0 +1,16 @@
+<p class="disclaim">
+ <strong>
+ <% if site = current_site || Site.first %>
+ <%= site.tagline %>
+ <% end %>
+ </strong>
+</p>
+<p>
+ <%= I18n.t 'txt.footer_message', :default => "Two's company. Three's a forum. More's a Beast." %>
+</p>
+<p class="credit">
+ <%= I18n.t('txt.powered_by', :default => 'Powered by') %> <a href="http://github.com/courtenay/altered_beast/">Altered Beast</a><br />
+ &copy; 2006 - 2009 <a href="http://www.workingwithrails.com/person/5337-josh-goebel" class="subtle">Josh Goebel</a>,
+ <a href="http://blog.caboo.se">Courtenay Gasking</a> <%= I18n.t 'txt.and', :default => 'and' %>
+ <a href="http://weblog.techno-weenie.net" class="subtle">Rick Olson</a>
+</p>
View
60 app/views/layouts/_head.html.erb
@@ -1,41 +1,21 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <title><%=h @current_site && current_site.name || I18n.t('txt.beast_title', :default => 'Altered Beast') %><%= " - #{h @page_title}" if @page_title %></title>
- <%= stylesheet_link_tag 'display' %>
- <%= stylesheet_link_tag 'captcha' %>
- <%= javascript_include_tag "prototype", "effects", "lowpro", 'rails', "application", :cache => "beast" %>
-<% unless @feed_icons.blank? -%>
- <% @feed_icons.each do |feed| -%>
- <%= auto_discovery_link_tag :atom, feed[:url], :title => "Subscribe to '#{feed[:title]}'" %>
- <% end -%>
-<% end -%>
- <link rel="search" type="application/opensearchdescription+xml" href="http://<%= request.host_with_port %>/open_search.xml" />
- <%= csrf_meta_tag %>
-</head>
-<body>
+<ul id="nav">
+ <li><%= link_to I18n.t('txt.forums', :default => 'Forums'), root_path, :rel => 'home' %></li>
+ <li><%= link_to I18n.t('txt.users', :default => 'Users'), users_path %></li>
+ <li id="search">
+ <%= form_tag posts_path, :method => 'get' do %>
+ <%= text_field_tag :q, params[:q], :size => 15, :id => :search_box %>
+ <% end %>
+ </li>
+ <li><%= link_to_function I18n.t('txt.search', :default => 'Search'), "#", :href => root_path, :id => 'search-link' %></li>
-<div id="header">
- <ul id="nav">
- <li><%= link_to I18n.t('txt.forums', :default => 'Forums'), root_path, :rel => 'home' %></li>
- <li><%= link_to I18n.t('txt.users', :default => 'Users'), users_path %></li>
- <li id="search">
- <%= form_tag posts_path, :method => 'get' do -%>
- <%= text_field_tag :q, params[:q], :size => 15, :id => :search_box %>
- <% end -%>
- </li>
- <li><%= link_to_function I18n.t('txt.search', :default => 'Search'), "#", :href => root_path, :id => 'search-link' %></li>
-
- <% if @current_site and logged_in? -%>
- <li class="login"><%= link_to current_user.display_name, user_path(current_user) %></li>
- <li class="logout"><%= link_to I18n.t('txt.settings', :default => 'Settings'), settings_path %></li>
- <li class="logout"><%= link_to I18n.t('txt.logout', :default => 'Logout'), logout_path(:to => CGI.escape(request.fullpath)) %></li>
- <% else -%>
- <li><%= link_to I18n.t('txt.signup', :default => 'Signup'), signup_path(:to => CGI.escape(request.fullpath)) %></li>
- <li><%= link_to I18n.t('txt.login', :default => 'Login'), login_path(:to => CGI.escape(request.fullpath)) %></li>
- <% end -%>
- </ul>
- <% name = (site = @current_site || Site.first) && site.name %>
- <h1><%= link_to name || I18n.t('txt.beast_title', :default => 'Altered Beast'), root_path %>
-</div>
+ <% if current_site and logged_in? %>
+ <li class="login"><%= link_to current_user.display_name, user_path(current_user) %></li>
+ <li class="logout"><%= link_to I18n.t('txt.settings', :default => 'Settings'), settings_path %></li>
+ <li class="logout"><%= link_to I18n.t('txt.logout', :default => 'Logout'), logout_path(:to => CGI.escape(request.fullpath)) %></li>
+ <% else %>
+ <li><%= link_to I18n.t('txt.signup', :default => 'Signup'), signup_path(:to => CGI.escape(request.fullpath)) %></li>
+ <li><%= link_to I18n.t('txt.login', :default => 'Login'), login_path(:to => CGI.escape(request.fullpath)) %></li>
+ <% end %>
+</ul>
+<% name = (site = current_site || Site.first) && site.name %>
+<h1><%= link_to name || I18n.t('txt.beast_title', :default => 'Altered Beast'), root_path %>
View
73 app/views/layouts/application.html.erb
@@ -1,44 +1,37 @@
-<%= render :partial => "layouts/head" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title><%= current_site && current_site.name || I18n.t('txt.beast_title', :default => 'Altered Beast') %><%= " - " + @page_title if @page_title %></title>
+ <%= stylesheet_link_tag %w(display captcha) %>
+ <%= javascript_include_tag %w(prototype effects lowpro rails application), :cache => "beast" %>
+ <% @feed_icons.each do |feed| %>
+ <%= auto_discovery_link_tag :atom, feed[:url], :title => "Subscribe to '#{feed[:title]}'" %>
+ <% end if @feed_icons.present? %>
+ <link rel="search" type="application/opensearchdescription+xml" href="http://<%= request.host_with_port %>/open_search.xml" />
+ <%= csrf_meta_tag %>
+ </head>
+ <body>
+ <div id="header">
+ <%= render "layouts/head" %>
+ </div>
-<div id="container">
-<div id="content">
-
-<%= content_tag 'p', h(flash[:notice]), :class => 'notice' if flash[:notice] %>
-<%= content_tag 'p', h(flash[:error]), :class => 'notice error' if flash[:error] %>
+ <div id="container">
+ <div id="content">
+ <%= flash_messages %>
+ <%= yield %>
+ </div>
-<%= yield %>
-</div>
+ <div id="right">
+ <%= yield(:right) %>
+ </div>
-<div id="right">
- <%= yield :right %>
-</div>
+ <br style="clear:both;" />
+ </div>
-<br style="clear:both;" />
-
-</div>
-
-<div id="footer">
- <p class="disclaim">
- <strong>
- <% if site = @current_site || Site.first %>
- <%= site.tagline %>
- <% end %>
- </strong>
- </p>
- <%
- footers=[I18n.t('txt.footer_message', :default => "Two's company. Three's a forum. More's a Beast.")
- ]
- %>
- <%= footers[rand(footers.size)]%>
- </strong>
- </p>
- <p class="credit">
- <%= I18n.t('txt.powered_by', :default => 'Powered by') %> <a href="http://github.com/courtenay/altered_beast/">Altered Beast</a><br />
- &copy; 2006 - 2009 <a href="http://www.workingwithrails.com/person/5337-josh-goebel" class="subtle">Josh Goebel</a>,
- <a href="http://blog.caboo.se">Courtenay Gasking</a> <%= I18n.t 'txt.and', :default => 'and' %>
- <a href="http://weblog.techno-weenie.net" class="subtle">Rick Olson</a>
- </p>
- <br style="clear:both;" />