From 56abbbfe8d9ec913ae79637d8fa9da37c2d26e53 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 2 Jan 2008 07:58:03 +0000 Subject: [PATCH] adding WikiWords to the wiki and allowing for users to make new pages if they do not exist by using a title git-svn-id: http://svn.barleysodas.com/barleysodas/trunk@76 0f7b21a7-9e3a-4941-bbeb-ce5c7c368fa7 --- app/controllers/application.rb | 80 ++++++++++++++----- app/controllers/autocomplete_controller.rb | 10 +++ app/controllers/beers_controller.rb | 17 +--- app/controllers/breweries_controller.rb | 14 +--- app/controllers/help_controller.rb | 36 ++++----- app/controllers/pages_controller.rb | 23 +++--- app/controllers/peoples_controller.rb | 12 +-- app/controllers/sessions_controller.rb | 9 +++ app/helpers/application_helper.rb | 25 ++++++ app/models/page.rb | 29 +++++-- app/models/people.rb | 8 +- app/views/pages/_page.rhtml | 4 +- app/views/pages/index.rhtml | 2 +- db/migrate/002_create_pages.rb | 4 + db/migrate/007_create_peoples.rb | 13 --- ...08_create_roles.rb => 007_create_roles.rb} | 6 -- db/migrate/008_create_peoples.rb | 17 ++++ ...p_start_page.rb => 010_help_start_page.rb} | 0 db/migrate/010_page_people_ownership.rb | 19 ----- generate_permissions | 26 ++---- 20 files changed, 194 insertions(+), 160 deletions(-) delete mode 100644 db/migrate/007_create_peoples.rb rename db/migrate/{008_create_roles.rb => 007_create_roles.rb} (73%) create mode 100644 db/migrate/008_create_peoples.rb rename db/migrate/{011_help_start_page.rb => 010_help_start_page.rb} (100%) delete mode 100644 db/migrate/010_page_people_ownership.rb diff --git a/app/controllers/application.rb b/app/controllers/application.rb index ec2ed17..fadfaaf 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -1,9 +1,12 @@ class ApplicationController < ActionController::Base session :session_key => '_barleysodas_session_id' + append_before_filter :block_prefetching_links append_before_filter :authorized? append_before_filter :set_current_people_id + helper_method :logged_in? + cattr_accessor :current_people_id ## @@ -21,23 +24,6 @@ class ApplicationController < ActionController::Base return !session[:people_title].nil? end - ## - # Saves the request uri in the session for later redirect after a login. - # - def save_request_url - session[:request_url] = request.request_uri - end - - ## - # Checks to see if the currently requested uri is the same as the uri saved - # in the session. - # - def already_saved_request_url - return true if session[:request_url] and - session[:request_url] == request.request_uri - false - end - ## # Determines if a user can access an action. # @@ -45,16 +31,15 @@ class ApplicationController < ActionController::Base return true if has_permission_for_action? respond_to do |format| format.html { - # prevent double-redirects to the login page if for some reason it is - # not allowed - unless logged_in? and !already_saved_request_url - save_request_url + if !logged_in? + session[:request_url] = request.request_uri redirect_to new_session_path return end @content_title = 'Forbidden' @secondary_title = '' @hide_sidebar = true + session[:request_url] = nil if !logged_in? render :template => 'shared/unauthorized' } format.xml { render :nothing => true, :status => 403 } @@ -81,13 +66,64 @@ class ApplicationController < ActionController::Base end ## - # Sets the @page variable to allow discussions. This should probably + # Sets the +@page+ variable to allow discussions. This should probably # have some kind of permission availability check later on. # def allow_page_discussions @page.allow_discussions = true end + protected + + ## + # Finds an object model for the particular resource requested. This will be + # used to find any model in the current pattern and maybe even the associated + # Page model. + # + def fetch_model + # where + obj_type = params[:controller] + # what + tfu = Page.title_from_url(params[:id]) + + # conditions for find + cond_ary = [ + 'title = :model_title' + ] + cond_var = { + :model_title => tfu, + :help_owner_type => 'Help' + } + # specific overrides for help, this has an owner type but it is just a Page + if obj_type == 'help' + cond_ary << 'owner_type = :help_owner_type' + obj_type = 'pages' + elsif obj_type == 'pages' + cond_ary << 'owner_type IS NULL' + end + # the eventual name of the instance variable, like +@page+ + obj_name = obj_type.singularize + + # find the object + obj = Class.class_eval(obj_name.camelize).find(:first, + :conditions => [ cond_ary.join(' AND '), cond_var ]) + + # allow the chance to make a new one if you GET the URL + if request.get? and obj.nil? + flash[:info] = "The #{obj_name} was not found, would you like to make it?" + redirect_to :action => 'new', :new_title => tfu + return + elsif obj.nil? + # fail if not found + raise ActiveRecord::RecordNotFound.new + end + # set the class variable + instance_variable_set("@#{obj_name}", obj) + # set the associated page if necessary + @page = obj.page if obj.respond_to?('page') + true + end + private ## diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 9852436..2924e25 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -24,4 +24,14 @@ class AutocompleteController < ApplicationController "%#{params[key][@value].downcase}%" ]) render :partial => 'autocomplete/results' end + + protected + + ## + # Allow pretty much everybody in here. Most likely this will not be able to + # be misused. At least not right now. + # + def authorized? + true + end end diff --git a/app/controllers/beers_controller.rb b/app/controllers/beers_controller.rb index 9fd47a3..6d04b3e 100644 --- a/app/controllers/beers_controller.rb +++ b/app/controllers/beers_controller.rb @@ -1,6 +1,6 @@ class BeersController < ApplicationController - append_before_filter :get_beer_and_page, :only => [ :show, :edit, :update, - :destroy ] + append_before_filter :fetch_model, + :only => [ :show, :edit, :update, :destroy ] # GET /beers # GET /beers.xml @@ -32,6 +32,7 @@ class BeersController < ApplicationController def new @secondary_title = 'Create a new beer' @beer = Beer.new + @beer.title = params[:new_title] if params[:new_title] @page = Page.new end @@ -91,16 +92,4 @@ class BeersController < ApplicationController format.xml { head :ok } end end - - protected - - ## - # Fetches the Beer and Page model for the actions. - # - def get_beer_and_page - @beer = Beer.find_by_title(Page.title_from_url(params[:id]), - :include => [ 'page' ]) - raise ActiveRecord::RecordNotFound.new if @beer.nil? - @page = @beer.page - end end diff --git a/app/controllers/breweries_controller.rb b/app/controllers/breweries_controller.rb index 54e32b5..49a15f0 100644 --- a/app/controllers/breweries_controller.rb +++ b/app/controllers/breweries_controller.rb @@ -1,6 +1,6 @@ class BreweriesController < ApplicationController - append_before_filter :get_brewery_and_page, :only => [ :show, :edit, :update, - :destroy ] + append_before_filter :fetch_model, + :only => [ :show, :edit, :update, :destroy ] # GET /breweries # GET /breweries.xml @@ -31,6 +31,7 @@ class BreweriesController < ApplicationController # GET /breweries/new def new @brewery = Brewery.new + @brewery.title = params[:new_title] if params[:new_title] @page = Page.new end @@ -84,13 +85,4 @@ class BreweriesController < ApplicationController format.xml { head :ok } end end - - protected - - def get_brewery_and_page - @brewery = Brewery.find_by_title(Page.title_from_url(params[:id]), - :include => [ 'page' ]) - raise ActiveRecord::RecordNotFound.new if @brewery.nil? - @page = @brewery.page - end end diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index fa21b58..c456904 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -1,8 +1,9 @@ class HelpController < ApplicationController - append_before_filter :fetch_page, :only => [ :show, :edit, :update, :destroy ] + append_before_filter :fetch_model, + :only => [ :show, :edit, :update, :destroy ] - # GET /helps - # GET /helps.xml + # GET /help + # GET /help.xml def index @page = Page.find_by_title_and_owner_type 'HomePage', 'Help' @content_title = 'BarleySodas Help' @@ -11,8 +12,8 @@ class HelpController < ApplicationController :owner_type => 'Help') end - # GET /helps/1 - # GET /helps/1.xml + # GET /help/1 + # GET /help/1.xml def show @secondary_title = '' respond_to do |format| @@ -21,19 +22,20 @@ class HelpController < ApplicationController end end - # GET /helps/new + # GET /help/new def new @page = Page.new + @page.title = params[:new_title] if params[:new_title] @secondary_title = 'Creating help page' end - # GET /helps/1;edit + # GET /help/1;edit def edit @secondary_title = 'Updating help page' end - # POST /helps - # POST /helps.xml + # POST /help + # POST /help.xml def create @page = Page.new(params[:page]) @page.owner_type = 'Help' @@ -59,8 +61,8 @@ class HelpController < ApplicationController end end - # PUT /helps/1 - # PUT /helps/1.xml + # PUT /help/1 + # PUT /help/1.xml def update @page.attributes = params[:page] respond_to do |format| @@ -84,8 +86,8 @@ class HelpController < ApplicationController end end - # DELETE /helps/1 - # DELETE /helps/1.xml + # DELETE /help/1 + # DELETE /help/1.xml def destroy @page.destroy respond_to do |format| @@ -93,12 +95,4 @@ class HelpController < ApplicationController format.xml { head :ok } end end - - protected - - def fetch_page - @page = Page.find_by_title_and_owner_type(Page.title_from_url(params[:id]), - 'Help') - raise ActiveRecord::RecordNotFound.new if @page.nil? - end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index b67919e..0b19735 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,10 +1,11 @@ class PagesController < ApplicationController - append_before_filter :fetch_page, :only => [ :show, :edit, :update, :destroy ] + append_before_filter :fetch_model, + :only => [ :show, :edit, :update, :destroy ] # GET /pages # GET /pages.xml def index - @page = Page.find_by_title 'HomePage' + @page = Page.find_by_title_and_owner_type 'HomePage', nil @page ||= Page.create :title => 'HomePage', :redcloth => 'Welcome to BarleySodas!' @content_title = 'The Beer Wiki' @@ -15,7 +16,7 @@ class PagesController < ApplicationController @pages, @wiki_pages = paginate :page, :per_page => 25, :order => 'title ASC', :conditions => [ cond_ary.join(' AND ') ] - @tags = Page.tags(:limit => 25, :order => "name DESC") + @tags = Page.tags(:limit => 25, :order => "name ASC") respond_to do |format| format.html # index.rhtml @@ -34,6 +35,7 @@ class PagesController < ApplicationController # GET /pages/new def new @page = Page.new + @page.title = params[:new_title] if params[:new_title] end # GET /pages/1;edit @@ -65,7 +67,13 @@ class PagesController < ApplicationController respond_to do |format| if @page.save flash[:notice] = 'Page was successfully updated.' - format.html { redirect_to page_url({ :id => @page.title_for_url }) } + format.html { + if @page.title == 'HomePage' + redirect_to pages_url + else + redirect_to page_url({ :id => @page.title_for_url }) + end + } format.xml { head :ok } else format.html { render :action => "edit" } @@ -90,11 +98,4 @@ class PagesController < ApplicationController def default_action redirect_to(pages_path) end - - protected - - def fetch_page - @page = Page.find_by_title(Page.title_from_url(params[:id])) - raise ActiveRecord::RecordNotFound.new if @page.nil? - end end diff --git a/app/controllers/peoples_controller.rb b/app/controllers/peoples_controller.rb index 6b51c7a..ac59540 100644 --- a/app/controllers/peoples_controller.rb +++ b/app/controllers/peoples_controller.rb @@ -1,6 +1,6 @@ class PeoplesController < ApplicationController - append_before_filter :fetch_people_and_page, :only => [ :show, :edit, - :update, :destroy ] + append_before_filter :fetch_model, + :only => [ :show, :edit, :update, :destroy ] # GET /peoples # GET /peoples.xml @@ -30,6 +30,7 @@ class PeoplesController < ApplicationController def new @secondary_title = 'Sign up for BarleySodas!' @people = People.new + @people.title = params[:new_title] if params[:new_title] @page = Page.new end @@ -87,13 +88,6 @@ class PeoplesController < ApplicationController protected - def fetch_people_and_page - @people = People.find_by_title(Page.title_from_url(params[:id]), - :include => [ 'page' ]) - raise ActiveRecord::RecordNotFound.new if @people.nil? - @page = @people.page - end - def set_people_role # set checks here for valid role assignment if params[:people] and params[:people][:role_id] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index aea9802..35ec24c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -39,4 +39,13 @@ class SessionsController < ApplicationController reset_session redirect_to '/' end + + protected + + ## + # Always allow People to log in and out of the system. + # + def authorized? + true + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index eb31244..319a220 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -68,4 +68,29 @@ module ApplicationHelper def tag_cloud_styles %w(tag_cloud_1 tag_cloud_2 tag_cloud_3 tag_cloud_4 tag_cloud_5) end + + ## + # Replaces a WikiWord link with a link to a Page, if it exists. + # + def replace_wiki_words(str) + str.gsub(/\[\[([A-Za-z0-9 \\]+)\]\]/) do |match| + c_string, page_string = params[:controller], $1 + if $1.match(/\\/) + ary = $1.split(/\\/) + c_string, page_string = ary.first, ary.last + end + owner_type = c_string.singularize.humanize + res = '' + if Page.exists?(page_string, owner_type) + res = link_to(page_string, { :controller => c_string, :action => :show, + :id => page_string.gsub(/ /, '_') }, + { :title => "View #{page_string}" }) + else + res = link_to(page_string, { :controller => c_string, + :action => :new, :new_title => page_string }, + { :title => "Create #{page_string}" }) + '?' + end + res + end + end end diff --git a/app/models/page.rb b/app/models/page.rb index 26da827..91936d8 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -67,6 +67,25 @@ class Page < ActiveRecord::Base tags = Tag.find_by_sql(query) end + ## + # Determines if a Page exists. + # + def self.exists?(page_name, owner_type = nil) + cond_ary = [ + 'title = :page_name' + ] + cond_var = { + :page_name => page_name, + :owner_type => owner_type + } + if owner_type.nil? or owner_type == 'Page' + cond_ary << 'owner_type IS NULL' + else + cond_ary << 'owner_type = :owner_type' + end + self.count(:conditions => [ cond_ary.join(' AND '), cond_var ]) > 0 + end + protected ## @@ -74,7 +93,7 @@ class Page < ActiveRecord::Base # def set_created_person self[:created_by] = ApplicationController.current_people_id rescue nil - self[:created_by] ||= People.penguincoder.id + self[:created_by] ||= People.penguincoder.id rescue nil end ## @@ -82,7 +101,7 @@ class Page < ActiveRecord::Base # def set_updated_person self[:updated_by] = ApplicationController.current_people_id rescue nil - self[:updated_by] ||= People.penguincoder.id + self[:updated_by] ||= People.penguincoder.id rescue nil end ## @@ -90,8 +109,8 @@ class Page < ActiveRecord::Base # def update_html # need to filter HTML first... remove