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
master
andrew 2008-01-02 07:58:03 +00:00
parent 704b5de94a
commit 56abbbfe8d
20 changed files with 194 additions and 160 deletions

View File

@ -1,9 +1,12 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
session :session_key => '_barleysodas_session_id' session :session_key => '_barleysodas_session_id'
append_before_filter :block_prefetching_links append_before_filter :block_prefetching_links
append_before_filter :authorized? append_before_filter :authorized?
append_before_filter :set_current_people_id append_before_filter :set_current_people_id
helper_method :logged_in? helper_method :logged_in?
cattr_accessor :current_people_id cattr_accessor :current_people_id
## ##
@ -21,23 +24,6 @@ class ApplicationController < ActionController::Base
return !session[:people_title].nil? return !session[:people_title].nil?
end 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. # Determines if a user can access an action.
# #
@ -45,16 +31,15 @@ class ApplicationController < ActionController::Base
return true if has_permission_for_action? return true if has_permission_for_action?
respond_to do |format| respond_to do |format|
format.html { format.html {
# prevent double-redirects to the login page if for some reason it is if !logged_in?
# not allowed session[:request_url] = request.request_uri
unless logged_in? and !already_saved_request_url
save_request_url
redirect_to new_session_path redirect_to new_session_path
return return
end end
@content_title = 'Forbidden' @content_title = 'Forbidden'
@secondary_title = '' @secondary_title = ''
@hide_sidebar = true @hide_sidebar = true
session[:request_url] = nil if !logged_in?
render :template => 'shared/unauthorized' render :template => 'shared/unauthorized'
} }
format.xml { render :nothing => true, :status => 403 } format.xml { render :nothing => true, :status => 403 }
@ -81,13 +66,64 @@ class ApplicationController < ActionController::Base
end end
## ##
# Sets the <tt>@page</tt> 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. # have some kind of permission availability check later on.
# #
def allow_page_discussions def allow_page_discussions
@page.allow_discussions = true @page.allow_discussions = true
end 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 private
## ##

View File

@ -24,4 +24,14 @@ class AutocompleteController < ApplicationController
"%#{params[key][@value].downcase}%" ]) "%#{params[key][@value].downcase}%" ])
render :partial => 'autocomplete/results' render :partial => 'autocomplete/results'
end 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 end

View File

@ -1,6 +1,6 @@
class BeersController < ApplicationController class BeersController < ApplicationController
append_before_filter :get_beer_and_page, :only => [ :show, :edit, :update, append_before_filter :fetch_model,
:destroy ] :only => [ :show, :edit, :update, :destroy ]
# GET /beers # GET /beers
# GET /beers.xml # GET /beers.xml
@ -32,6 +32,7 @@ class BeersController < ApplicationController
def new def new
@secondary_title = 'Create a new beer' @secondary_title = 'Create a new beer'
@beer = Beer.new @beer = Beer.new
@beer.title = params[:new_title] if params[:new_title]
@page = Page.new @page = Page.new
end end
@ -91,16 +92,4 @@ class BeersController < ApplicationController
format.xml { head :ok } format.xml { head :ok }
end end
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 end

View File

@ -1,6 +1,6 @@
class BreweriesController < ApplicationController class BreweriesController < ApplicationController
append_before_filter :get_brewery_and_page, :only => [ :show, :edit, :update, append_before_filter :fetch_model,
:destroy ] :only => [ :show, :edit, :update, :destroy ]
# GET /breweries # GET /breweries
# GET /breweries.xml # GET /breweries.xml
@ -31,6 +31,7 @@ class BreweriesController < ApplicationController
# GET /breweries/new # GET /breweries/new
def new def new
@brewery = Brewery.new @brewery = Brewery.new
@brewery.title = params[:new_title] if params[:new_title]
@page = Page.new @page = Page.new
end end
@ -84,13 +85,4 @@ class BreweriesController < ApplicationController
format.xml { head :ok } format.xml { head :ok }
end end
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 end

View File

@ -1,8 +1,9 @@
class HelpController < ApplicationController 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 /help
# GET /helps.xml # GET /help.xml
def index def index
@page = Page.find_by_title_and_owner_type 'HomePage', 'Help' @page = Page.find_by_title_and_owner_type 'HomePage', 'Help'
@content_title = 'BarleySodas Help' @content_title = 'BarleySodas Help'
@ -11,8 +12,8 @@ class HelpController < ApplicationController
:owner_type => 'Help') :owner_type => 'Help')
end end
# GET /helps/1 # GET /help/1
# GET /helps/1.xml # GET /help/1.xml
def show def show
@secondary_title = '' @secondary_title = ''
respond_to do |format| respond_to do |format|
@ -21,19 +22,20 @@ class HelpController < ApplicationController
end end
end end
# GET /helps/new # GET /help/new
def new def new
@page = Page.new @page = Page.new
@page.title = params[:new_title] if params[:new_title]
@secondary_title = 'Creating help page' @secondary_title = 'Creating help page'
end end
# GET /helps/1;edit # GET /help/1;edit
def edit def edit
@secondary_title = 'Updating help page' @secondary_title = 'Updating help page'
end end
# POST /helps # POST /help
# POST /helps.xml # POST /help.xml
def create def create
@page = Page.new(params[:page]) @page = Page.new(params[:page])
@page.owner_type = 'Help' @page.owner_type = 'Help'
@ -59,8 +61,8 @@ class HelpController < ApplicationController
end end
end end
# PUT /helps/1 # PUT /help/1
# PUT /helps/1.xml # PUT /help/1.xml
def update def update
@page.attributes = params[:page] @page.attributes = params[:page]
respond_to do |format| respond_to do |format|
@ -84,8 +86,8 @@ class HelpController < ApplicationController
end end
end end
# DELETE /helps/1 # DELETE /help/1
# DELETE /helps/1.xml # DELETE /help/1.xml
def destroy def destroy
@page.destroy @page.destroy
respond_to do |format| respond_to do |format|
@ -93,12 +95,4 @@ class HelpController < ApplicationController
format.xml { head :ok } format.xml { head :ok }
end end
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 end

View File

@ -1,10 +1,11 @@
class PagesController < ApplicationController 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
# GET /pages.xml # GET /pages.xml
def index def index
@page = Page.find_by_title 'HomePage' @page = Page.find_by_title_and_owner_type 'HomePage', nil
@page ||= Page.create :title => 'HomePage', @page ||= Page.create :title => 'HomePage',
:redcloth => 'Welcome to BarleySodas!' :redcloth => 'Welcome to BarleySodas!'
@content_title = 'The Beer Wiki' @content_title = 'The Beer Wiki'
@ -15,7 +16,7 @@ class PagesController < ApplicationController
@pages, @wiki_pages = paginate :page, :per_page => 25, @pages, @wiki_pages = paginate :page, :per_page => 25,
:order => 'title ASC', :conditions => [ cond_ary.join(' AND ') ] :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| respond_to do |format|
format.html # index.rhtml format.html # index.rhtml
@ -34,6 +35,7 @@ class PagesController < ApplicationController
# GET /pages/new # GET /pages/new
def new def new
@page = Page.new @page = Page.new
@page.title = params[:new_title] if params[:new_title]
end end
# GET /pages/1;edit # GET /pages/1;edit
@ -65,7 +67,13 @@ class PagesController < ApplicationController
respond_to do |format| respond_to do |format|
if @page.save if @page.save
flash[:notice] = 'Page was successfully updated.' 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 } format.xml { head :ok }
else else
format.html { render :action => "edit" } format.html { render :action => "edit" }
@ -90,11 +98,4 @@ class PagesController < ApplicationController
def default_action def default_action
redirect_to(pages_path) redirect_to(pages_path)
end 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 end

View File

@ -1,6 +1,6 @@
class PeoplesController < ApplicationController class PeoplesController < ApplicationController
append_before_filter :fetch_people_and_page, :only => [ :show, :edit, append_before_filter :fetch_model,
:update, :destroy ] :only => [ :show, :edit, :update, :destroy ]
# GET /peoples # GET /peoples
# GET /peoples.xml # GET /peoples.xml
@ -30,6 +30,7 @@ class PeoplesController < ApplicationController
def new def new
@secondary_title = 'Sign up for BarleySodas!' @secondary_title = 'Sign up for BarleySodas!'
@people = People.new @people = People.new
@people.title = params[:new_title] if params[:new_title]
@page = Page.new @page = Page.new
end end
@ -87,13 +88,6 @@ class PeoplesController < ApplicationController
protected 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 def set_people_role
# set checks here for valid role assignment # set checks here for valid role assignment
if params[:people] and params[:people][:role_id] if params[:people] and params[:people][:role_id]

View File

@ -39,4 +39,13 @@ class SessionsController < ApplicationController
reset_session reset_session
redirect_to '/' redirect_to '/'
end end
protected
##
# Always allow People to log in and out of the system.
#
def authorized?
true
end
end end

View File

@ -68,4 +68,29 @@ module ApplicationHelper
def tag_cloud_styles def tag_cloud_styles
%w(tag_cloud_1 tag_cloud_2 tag_cloud_3 tag_cloud_4 tag_cloud_5) %w(tag_cloud_1 tag_cloud_2 tag_cloud_3 tag_cloud_4 tag_cloud_5)
end 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 end

View File

@ -67,6 +67,25 @@ class Page < ActiveRecord::Base
tags = Tag.find_by_sql(query) tags = Tag.find_by_sql(query)
end 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 protected
## ##
@ -74,7 +93,7 @@ class Page < ActiveRecord::Base
# #
def set_created_person def set_created_person
self[:created_by] = ApplicationController.current_people_id rescue nil self[:created_by] = ApplicationController.current_people_id rescue nil
self[:created_by] ||= People.penguincoder.id self[:created_by] ||= People.penguincoder.id rescue nil
end end
## ##
@ -82,7 +101,7 @@ class Page < ActiveRecord::Base
# #
def set_updated_person def set_updated_person
self[:updated_by] = ApplicationController.current_people_id rescue nil self[:updated_by] = ApplicationController.current_people_id rescue nil
self[:updated_by] ||= People.penguincoder.id self[:updated_by] ||= People.penguincoder.id rescue nil
end end
## ##
@ -90,8 +109,8 @@ class Page < ActiveRecord::Base
# #
def update_html def update_html
# need to filter HTML first... remove <script> and chunks and the like... # need to filter HTML first... remove <script> and chunks and the like...
res = RedCloth.new(strip_tags(self.redcloth.to_s), [ :no_span_caps ]) self.html = RedCloth.new(strip_tags(self.redcloth.to_s),
self.html = res.to_html( [ :no_span_caps ]).to_html(
# no link references. messes up lines starting with [[WikiWord]] # no link references. messes up lines starting with [[WikiWord]]
:block_textile_table, :block_textile_lists, :block_textile_prefix, :block_textile_table, :block_textile_lists, :block_textile_prefix,
:inline_textile_image, :inline_textile_link, :inline_textile_code, :inline_textile_image, :inline_textile_link, :inline_textile_code,
@ -102,6 +121,6 @@ class Page < ActiveRecord::Base
# Removes HTML tags from a string # Removes HTML tags from a string
# #
def strip_tags(str) def strip_tags(str)
str.gsub(/\</, "&lt;").gsub(/\>/, "&gt;") str.gsub(/\</, "&lt;").gsub(/\>/, "&gt;").gsub(/\&/, "&amp;")
end end
end end

View File

@ -7,13 +7,7 @@ class People < ActiveRecord::Base
attr_protected :role_id attr_protected :role_id
has_many :created_pages, :class_name => 'Page', :foreign_key => 'created_by' has_many :created_pages, :class_name => 'Page', :foreign_key => 'created_by'
has_many :updated_pages, :class_name => 'Page', :foreign_key => 'updated_by' has_many :updated_pages, :class_name => 'Page', :foreign_key => 'updated_by'
validates_uniqueness_of :title
##
# Finds the Guest user for the system.
#
def self.guest_user
self.find_by_title('Guest') rescue nil
end
## ##
# Finds me. # Finds me.

View File

@ -8,10 +8,10 @@
</div><% end -%> </div><% end -%>
<br class="clear" /> <br class="clear" />
<div class="entry-content"> <div class="entry-content">
<%= @page.html %> <%= replace_wiki_words(@page.html) %>
</div> </div>
<% unless simple -%><ul class="meta"> <% unless simple -%><ul class="meta">
<% if @page.tags.size > 0 -%><li>Tags: <%= @page.tag_names.sort.join(' ') -%></li><% end -%> <% if @page.tags.size > 0 -%><li>Tags: <%= @page.tags.collect { |t| t.name }.sort.join(' ') -%></li><% end -%>
<li>Version: <%= @page.version -%></li> <li>Version: <%= @page.version -%></li>
<% @page.owner.page_attributes.each do |x| -%> <% @page.owner.page_attributes.each do |x| -%>
<li><%= x -%></li> <li><%= x -%></li>

View File

@ -1,4 +1,4 @@
<%= render :partial => 'page', :locals => { :simple => true } -%> <%= render :partial => 'page' -%>
<% unless @wiki_pages.empty? -%> <% unless @wiki_pages.empty? -%>
<div class="hentry"> <div class="hentry">

View File

@ -7,8 +7,12 @@ class CreatePages < ActiveRecord::Migration
t.column :owner_id, :integer t.column :owner_id, :integer
t.column :owner_type, :string, :limit => 32 t.column :owner_type, :string, :limit => 32
t.column :version, :integer t.column :version, :integer
t.column :created_by, :integer
t.column :updated_by, :integer
end end
add_index :pages, :owner_id add_index :pages, :owner_id
add_index :pages, :created_by
add_index :pages, :updated_by
Page.create_versioned_table Page.create_versioned_table
end end

View File

@ -1,13 +0,0 @@
class CreatePeoples < ActiveRecord::Migration
def self.up
create_table :peoples do |t|
t.column :title, :string
end
People.create :title => 'Guest', :page => Page.new
People.create :title => 'PenguinCoder', :page => Page.new
end
def self.down
drop_table :peoples
end
end

View File

@ -7,18 +7,12 @@ class CreateRoles < ActiveRecord::Migration
end end
add_index :roles, :parent_id add_index :roles, :parent_id
add_index :roles, :code add_index :roles, :code
add_column :peoples, :role_id, :integer
add_index :peoples, :role_id
br = Role.create :code => 'base', :name => 'Base Role' br = Role.create :code => 'base', :name => 'Base Role'
ar = Role.create :code => 'admin', :name => 'Administrative Role', ar = Role.create :code => 'admin', :name => 'Administrative Role',
:parent_id => br.id :parent_id => br.id
g = People.guest_user
g.role = br
g.save
end end
def self.down def self.down
drop_table :roles drop_table :roles
remove_column :peoples, :role_id
end end
end end

View File

@ -0,0 +1,17 @@
class CreatePeoples < ActiveRecord::Migration
def self.up
create_table :peoples do |t|
t.column :title, :string
t.column :role_id, :integer
end
add_index :peoples, :title
add_index :peoples, :role_id
p = People.new :title => 'PenguinCoder', :page => Page.new
p.role = Role.admin_role
p.save
end
def self.down
drop_table :peoples
end
end

View File

@ -1,19 +0,0 @@
class PagePeopleOwnership < ActiveRecord::Migration
def self.up
add_column :pages, :created_by, :integer
add_index :pages, :created_by
add_column :pages, :updated_by, :integer
add_index :pages, :updated_by
add_column :page_versions, :created_by, :integer
add_index :page_versions, :created_by
add_column :page_versions, :updated_by, :integer
add_index :page_versions, :updated_by
end
def self.down
remove_column :pages, :created_by
remove_column :pages, :updated_by
remove_column :page_versions, :created_by
remove_column :page_versions, :updated_by
end
end

View File

@ -3,9 +3,8 @@ Permission.destroy_all
base_actions = ApplicationController.action_methods base_actions = ApplicationController.action_methods
# i should probably figure out all of the children of ApplicationController # i should probably figure out all of the children of ApplicationController
# rather than defining them here. # rather than defining them here.
controllers = [ AutocompleteController, SessionsController, PagesController, controllers = [ PagesController, HelpController, DiscussionsController,
PeoplesController, BeersController, BreweriesController, RolesController, PeoplesController, BeersController, BreweriesController, RolesController ]
DiscussionsController, HelpController ]
controllers.each do |c| controllers.each do |c|
actions = c.action_methods - base_actions actions = c.action_methods - base_actions
cname = c.controller_name cname = c.controller_name
@ -13,31 +12,20 @@ controllers.each do |c|
end end
r = Role.base_role r = Role.base_role
Permission.find(:all,
:conditions => [ 'controller = ?', 'autocomplete' ]).each do |p|
r.permissions << p
end
Permission.find(:all,
:conditions => [ 'controller = ?', 'sessions' ]).each do |p|
r.permissions << p
end
Permission.find(:all, Permission.find(:all,
:conditions => [ 'controller = ?', 'pages' ]).each do |p| :conditions => [ 'controller = ?', 'pages' ]).each do |p|
next if [ 'new', 'create', 'edit', 'update', 'destroy' ].include?(p.action) next if [ 'new', 'create', 'edit', 'update', 'destroy' ].include?(p.action)
r.permissions << p r.permissions << p
end end
Permission.find(:all,
:conditions => [ 'controller = ?', 'help' ]).each do |p|
next if [ 'new', 'create', 'edit', 'update', 'destroy' ].include?(p.action)
r.permissions << p
end
r2 = Role.admin_role r2 = Role.admin_role
Permission.find(:all).each do |p| Permission.find(:all).each do |p|
r2.permissions << p unless r.permissions.include?(p) r2.permissions << p unless r.permissions.include?(p)
end end
p = People.new :title => 'penguincoder'
page = Page.new
p.page = page
p.role = r2
p.save
puts "All permissions created" puts "All permissions created"