jeffrafter-spreadhead 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.textile +3 -0
- data/LICENSE +20 -0
- data/README.textile +77 -0
- data/Rakefile +76 -0
- data/TODO.textile +4 -0
- data/VERSION +1 -0
- data/app/controllers/spreadhead/pages_controller.rb +56 -0
- data/app/views/spreadhead/pages/_form.html.erb +32 -0
- data/app/views/spreadhead/pages/edit.html.erb +8 -0
- data/app/views/spreadhead/pages/index.html.erb +21 -0
- data/app/views/spreadhead/pages/new.html.erb +8 -0
- data/app/views/spreadhead/pages/show.html.erb +5 -0
- data/config/spreadhead_routes.rb +4 -0
- data/generators/spreadhead/USAGE +1 -0
- data/generators/spreadhead/lib/insert_commands.rb +33 -0
- data/generators/spreadhead/lib/rake_commands.rb +22 -0
- data/generators/spreadhead/spreadhead_generator.rb +39 -0
- data/generators/spreadhead/templates/README +24 -0
- data/generators/spreadhead/templates/factories.rb +12 -0
- data/generators/spreadhead/templates/initializer.rb +12 -0
- data/generators/spreadhead/templates/migrations/create_pages.rb +20 -0
- data/generators/spreadhead/templates/migrations/update_pages.rb +41 -0
- data/generators/spreadhead/templates/page.rb +3 -0
- data/lib/spreadhead.rb +6 -0
- data/lib/spreadhead/extensions/routes.rb +14 -0
- data/lib/spreadhead/page.rb +77 -0
- data/lib/spreadhead/render.rb +35 -0
- data/rails/init.rb +1 -0
- data/test/controllers/pages_controller_test.rb +83 -0
- data/test/models/page_test.rb +31 -0
- data/test/test_helper.rb +4 -0
- metadata +116 -0
data/CHANGELOG.textile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jeff Rafter, SocialRange, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
h1. Spreadhead
|
2
|
+
|
3
|
+
<strong>spreadhead</strong> <em>noun</em> two facing pages of a book or other publication.
|
4
|
+
|
5
|
+
Rails content mangement for pages that shouldn't be views.
|
6
|
+
|
7
|
+
h2. Installation
|
8
|
+
|
9
|
+
Spreadhead is a Rails engine. It works with versions of Rails greater than 2.3.
|
10
|
+
|
11
|
+
In config/environment.rb:
|
12
|
+
|
13
|
+
<pre>
|
14
|
+
config.gem "jeffrafter-spreadhead",
|
15
|
+
:lib => 'spreadhead',
|
16
|
+
:source => 'http://gems.github.com'
|
17
|
+
</pre>
|
18
|
+
|
19
|
+
Vendor the gem:
|
20
|
+
|
21
|
+
<pre>
|
22
|
+
rake gems:install
|
23
|
+
rake gems:unpack
|
24
|
+
</pre>
|
25
|
+
|
26
|
+
Make sure the development database exists and run the generator:
|
27
|
+
|
28
|
+
<pre>
|
29
|
+
script/generate spreadhead
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
A number of files will be created and instructions will be printed.
|
33
|
+
|
34
|
+
You may already have some of these files. Don't worry. You'll be asked if you want to overwrite them.
|
35
|
+
|
36
|
+
Run the migration:
|
37
|
+
|
38
|
+
<pre>
|
39
|
+
rake db:migrate
|
40
|
+
</pre>
|
41
|
+
|
42
|
+
h2. Routes
|
43
|
+
|
44
|
+
Spreadhead installs default catch-all routes. These are given the lowest priority in your application. If your application is already catching these routes then you may not be able to access your spreadhead pages.
|
45
|
+
|
46
|
+
h2. Cucumber Features
|
47
|
+
|
48
|
+
As your application evolves, you want to know that your pages still work. Cucumber tests are included.
|
49
|
+
|
50
|
+
Run the Cucumber generator (if you haven't already) and the feature generator:
|
51
|
+
|
52
|
+
<pre>
|
53
|
+
script/generate cucumber
|
54
|
+
script/generate spreadhead_features
|
55
|
+
</pre>
|
56
|
+
|
57
|
+
h2. Authors
|
58
|
+
|
59
|
+
Spreadhead is based on the blog post "http://neverlet.be/2008/12/17/building-a-content-managment-system":http://neverlet.be/2008/12/17/building-a-content-managment-system by Jeff Rafter
|
60
|
+
|
61
|
+
The engine implementation and gem was patterned after the Clearance gem by Thoughtbot.
|
62
|
+
|
63
|
+
h2. Suggestions, Bugs, Refactoring?
|
64
|
+
|
65
|
+
Fork away and create a "Github Issue":http://github.com/jeffrafter/spreadhead/issues. Please send pull requests.
|
66
|
+
|
67
|
+
When you do:
|
68
|
+
|
69
|
+
* Fork the project.
|
70
|
+
* Make your feature addition or bug fix.
|
71
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
72
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
73
|
+
* Send me a pull request. Bonus points for topic branches.
|
74
|
+
|
75
|
+
h2. Documentation
|
76
|
+
|
77
|
+
Documentation is available at "http://rdoc.info/projects/jeffrafter/spreadhead":http://rdoc.info/jeffrafter/spreadhead
|
data/Rakefile
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "spreadhead"
|
8
|
+
gem.summary = %Q{Rails content mangement for pages that shouldn't be views.}
|
9
|
+
gem.description = %Q{Rails content mangement for pages that shouldn't be views.}
|
10
|
+
gem.email = "jeff@socialrange.org"
|
11
|
+
gem.homepage = "http://github.com/jeffrafter/spreadhead"
|
12
|
+
gem.authors = ["Jeff Rafter"]
|
13
|
+
gem.add_dependency "BlueCloth"
|
14
|
+
gem.add_dependency "RedCloth"
|
15
|
+
gem.add_dependency "rsl-stringex"
|
16
|
+
gem.files = FileList["[A-Z]*", "{app,config,generators,lib,rails}/**/*", "test/{controllers,models}/**/*", "test/test_helper.rb"]
|
17
|
+
gem.test_files = FileList["test/{controllers,models}/**/*", "test/test_helper.rb"]
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test => ["generator:cleanup", "generator:spreadhead"]) do |task|
|
27
|
+
task.libs << "lib" << "test"
|
28
|
+
task.pattern = "test/**/*_test.rb"
|
29
|
+
task.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
generators = %w(spreadhead)
|
33
|
+
|
34
|
+
namespace :generator do
|
35
|
+
desc "Cleans up the test app before running the generator"
|
36
|
+
task :cleanup do
|
37
|
+
FileUtils.rm_rf("test/rails")
|
38
|
+
system "cd test && rails rails"
|
39
|
+
|
40
|
+
# I don't like testing performance!
|
41
|
+
FileUtils.rm_rf("test/rails/test/performance")
|
42
|
+
|
43
|
+
system "echo \"\" >> test/rails/config/environments/test.rb"
|
44
|
+
system "echo \"config.gem 'thoughtbot-shoulda', :lib => 'shoulda'\" >> test/rails/config/environments/test.rb"
|
45
|
+
system "echo \"config.gem 'thoughtbot-factory_girl', :lib => 'factory_girl'\" >> test/rails/config/environments/test.rb"
|
46
|
+
|
47
|
+
FileUtils.mkdir_p("test/rails/vendor/plugins")
|
48
|
+
spreadhead_root = File.expand_path(File.dirname(__FILE__))
|
49
|
+
system("ln -s #{spreadhead_root} test/rails/vendor/plugins/spreadhead")
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Run the spreadhead generator"
|
53
|
+
task :spreadhead do
|
54
|
+
system "cd test/rails && ./script/generate spreadhead && rake db:migrate db:test:prepare"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
task :default => :test
|
59
|
+
|
60
|
+
require 'rake/rdoctask'
|
61
|
+
Rake::RDocTask.new do |rdoc|
|
62
|
+
if File.exist?('VERSION.yml')
|
63
|
+
config = YAML.load(File.read('VERSION.yml'))
|
64
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
65
|
+
else
|
66
|
+
version = ""
|
67
|
+
end
|
68
|
+
|
69
|
+
rdoc.rdoc_dir = 'rdoc'
|
70
|
+
rdoc.title = "spreadhead #{version}"
|
71
|
+
rdoc.rdoc_files.include('README*')
|
72
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
73
|
+
rdoc.rdoc_files.include('app/**/*.rb')
|
74
|
+
rdoc.rdoc_files.include('generators/**/*.rb')
|
75
|
+
end
|
76
|
+
|
data/TODO.textile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Spreadhead
|
2
|
+
class PagesController < ApplicationController
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
def new
|
6
|
+
@page = ::Page.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
@pages = ::Page.find(:all)
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
@page = ::Page.published.find_by_url!(params[:id] || params[:url].join('-slash-'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def edit
|
18
|
+
@page = ::Page.find_by_url!(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
@page = ::Page.new(params[:page])
|
23
|
+
respond_to do |format|
|
24
|
+
if @page.save
|
25
|
+
format.html { redirect_to page_url(@page) }
|
26
|
+
format.xml { head :created, :location => pages_url }
|
27
|
+
else
|
28
|
+
format.html { render :action => "new" }
|
29
|
+
format.xml { render :xml => @page.errors.to_xml }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
@page = ::Page.find_by_url!(params[:id])
|
36
|
+
respond_to do |format|
|
37
|
+
if @page.update_attributes(params[:page])
|
38
|
+
format.html { redirect_to pages_url }
|
39
|
+
format.xml { head :ok }
|
40
|
+
else
|
41
|
+
format.html { render :action => "edit" }
|
42
|
+
format.xml { render :xml => @page.errors.to_xml }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
@page = ::Page.find_by_url!(params[:id])
|
49
|
+
@page.destroy
|
50
|
+
respond_to do |format|
|
51
|
+
format.html { redirect_to pages_url }
|
52
|
+
format.xml { head :ok }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="errors">
|
2
|
+
<%= form.error_messages %>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<div class="text">
|
6
|
+
<%= form.label :title %>
|
7
|
+
<%= form.text_field :title %>
|
8
|
+
</div>
|
9
|
+
<div class="text">
|
10
|
+
<%= form.label :description %>
|
11
|
+
<%= form.text_field :description %>
|
12
|
+
</div>
|
13
|
+
<div class="text">
|
14
|
+
<%= form.label :keywords %>
|
15
|
+
<%= form.text_field :keywords %>
|
16
|
+
</div>
|
17
|
+
<div class="text">
|
18
|
+
<%= form.label :category %>
|
19
|
+
<%= form.text_field :category %>
|
20
|
+
</div>
|
21
|
+
<div class="textarea">
|
22
|
+
<%= form.label :text %>
|
23
|
+
<%= form.text_area :text %>
|
24
|
+
</div>
|
25
|
+
<div class="checkbox">
|
26
|
+
<%= form.label :published %>
|
27
|
+
<%= form.check_box :published %>
|
28
|
+
</div>
|
29
|
+
<div class="select">
|
30
|
+
<%= form.label :formatting %>
|
31
|
+
<%= form.select :formatting, [['Plain','plain'], ['Markdown', 'markdown'], ['Textile', 'textile']] %>
|
32
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<h2>Pages</h2>
|
2
|
+
|
3
|
+
<table class="pages">
|
4
|
+
<tr>
|
5
|
+
<th class="title">Title</th>
|
6
|
+
<th class="path">Path</th>
|
7
|
+
<th class="published">Published</th>
|
8
|
+
<th class="commands"></th>
|
9
|
+
</tr>
|
10
|
+
<% for page in @pages %>
|
11
|
+
<tr class="<%= cycle("even","odd") -%>" >
|
12
|
+
<td class="title"><%= link_to page.title || 'No title', edit_page_url(page) %></td>
|
13
|
+
<td class="path"><%= page.url || 'No url' %></td>
|
14
|
+
<td class="published"><%=h page.published ? 'Y' : 'N' %></td>
|
15
|
+
<td class="commands"><%= link_to 'Destroy', page_url(page), :confirm => 'Are you sure?', :method => :delete %></td>
|
16
|
+
</tr>
|
17
|
+
<% end %>
|
18
|
+
</table>
|
19
|
+
<div>
|
20
|
+
<%= link_to 'New page', new_page_url %>
|
21
|
+
</div>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<% content_for(:title) do %><%= @page.title || '' %><% end %>
|
2
|
+
<% content_for(:keywords) do %><%= @page.keywords || '' %><% end %>
|
3
|
+
<% content_for(:description) do %><%= @page.description || '' %><% end %>
|
4
|
+
<!-- Updated: <%= @page.updated_at %> -->
|
5
|
+
<%= spreadhead @page %>
|
@@ -0,0 +1 @@
|
|
1
|
+
script/generate spreadhead
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master
|
2
|
+
|
3
|
+
Rails::Generator::Commands::Base.class_eval do
|
4
|
+
def file_contains?(relative_destination, line)
|
5
|
+
File.read(destination_path(relative_destination)).include?(line)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Rails::Generator::Commands::Create.class_eval do
|
10
|
+
def insert_into(file, line)
|
11
|
+
logger.insert "#{line} into #{file}"
|
12
|
+
unless options[:pretend] || file_contains?(file, line)
|
13
|
+
gsub_file file, /^(class|module) .+$/ do |match|
|
14
|
+
"#{match}\n #{line}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
21
|
+
def insert_into(file, line)
|
22
|
+
logger.remove "#{line} from #{file}"
|
23
|
+
unless options[:pretend]
|
24
|
+
gsub_file file, "\n #{line}", ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Rails::Generator::Commands::List.class_eval do
|
30
|
+
def insert_into(file, line)
|
31
|
+
logger.insert "#{line} into #{file}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Rails::Generator::Commands::Create.class_eval do
|
2
|
+
def rake_db_migrate
|
3
|
+
logger.rake "db:migrate"
|
4
|
+
unless system("rake db:migrate")
|
5
|
+
logger.rake "db:migrate failed. Rolling back"
|
6
|
+
command(:destroy).invoke!
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Rails::Generator::Commands::Destroy.class_eval do
|
12
|
+
def rake_db_migrate
|
13
|
+
logger.rake "db:rollback"
|
14
|
+
system "rake db:rollback"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Rails::Generator::Commands::List.class_eval do
|
19
|
+
def rake_db_migrate
|
20
|
+
logger.rake "db:migrate"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb")
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb")
|
3
|
+
|
4
|
+
class SpreadheadGenerator < Rails::Generator::Base
|
5
|
+
|
6
|
+
def manifest
|
7
|
+
record do |m|
|
8
|
+
m.insert_into "app/controllers/application_controller.rb",
|
9
|
+
"include Spreadhead::Render"
|
10
|
+
|
11
|
+
page_model = "app/models/page.rb"
|
12
|
+
if File.exists?(page_model)
|
13
|
+
m.insert_into page_model, "include Spreadhead::Page"
|
14
|
+
else
|
15
|
+
m.directory File.join("app", "models")
|
16
|
+
m.file "page.rb", page_model
|
17
|
+
end
|
18
|
+
|
19
|
+
m.directory File.join("test", "factories")
|
20
|
+
m.file "factories.rb", "test/factories/spreadhead.rb"
|
21
|
+
|
22
|
+
m.migration_template "migrations/#{migration_name}.rb", 'db/migrate',
|
23
|
+
:migration_file_name => "spreadhead_#{migration_name}"
|
24
|
+
|
25
|
+
m.readme "README"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def migration_name
|
32
|
+
if ActiveRecord::Base.connection.table_exists?(:pages)
|
33
|
+
'update_pages'
|
34
|
+
else
|
35
|
+
'create_pages'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
*******************************************************************************
|
3
|
+
|
4
|
+
Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
|
5
|
+
|
6
|
+
By default, Spreadhead does not restrict access to page creation, updating and
|
7
|
+
deleting. To implement this you will need to modify
|
8
|
+
|
9
|
+
config/initializers/spreadhead.rb
|
10
|
+
|
11
|
+
If you want to define an extension point in a view simply add:
|
12
|
+
|
13
|
+
<%= spreadhead "PAGE_URL" %> or <%= spreadhead @page %>
|
14
|
+
|
15
|
+
By default, Spreadhead tries to insert the content_for the title, description,
|
16
|
+
and keywords on your page. You can make use of these by inserting the following
|
17
|
+
into the head section in your application layout:
|
18
|
+
|
19
|
+
<title><%= yield :title %></title>
|
20
|
+
<meta name="Description" content="<%= yield :description %>" />
|
21
|
+
<meta name="Keywords" content="<%= yield :keywords %>" />
|
22
|
+
|
23
|
+
|
24
|
+
*******************************************************************************
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Factory.sequence :page_title do |n|
|
2
|
+
"Mr. Smith's #{n}th Request"
|
3
|
+
end
|
4
|
+
|
5
|
+
Factory.define :page do |page|
|
6
|
+
page.title { Factory.next :page_title }
|
7
|
+
page.text { "Paging Mrs. Smith" }
|
8
|
+
page.description { "What Mr. Smith Says" }
|
9
|
+
page.keywords { "smith paging" }
|
10
|
+
page.formatting { "plain" }
|
11
|
+
page.published { true }
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Spreadhead Initializer
|
2
|
+
#
|
3
|
+
# In this file you can do any kind of initialization you need but it is mainly
|
4
|
+
# for controlling which users get access to create, edit, destroy and update
|
5
|
+
# pages. By default, any user can modify the pages. If only logged in users can
|
6
|
+
# do this, while everyone else can view the pages then you can add a before
|
7
|
+
# filter. If you are using a toolkit like Clearance, then you can use the
|
8
|
+
# following:
|
9
|
+
#
|
10
|
+
# Spreadhead::PagesController.before_filter :redirect_to_root,
|
11
|
+
# :except => [:show],
|
12
|
+
# :unless => :signed_in?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class SpreadheadCreatePages < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:pages) do |t|
|
4
|
+
t.string :url, :null => false
|
5
|
+
t.string :text, :null => false
|
6
|
+
t.string :title, :null => false
|
7
|
+
t.string :keywords
|
8
|
+
t.string :description
|
9
|
+
t.string :formatting
|
10
|
+
t.string :category
|
11
|
+
t.boolean :published, :default => false, :null => false
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
add_index :pages, [:url, :id, :published]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
drop_table :pages
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class SpreadheadUpdatePages < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<%
|
4
|
+
existing_columns = ActiveRecord::Base.connection.columns(:pages).collect { |each| each.name }
|
5
|
+
columns = [
|
6
|
+
[:url, 't.string :url, :null => false'],
|
7
|
+
[:text, 't.string :text, :null => false'],
|
8
|
+
[:title, 't.string :title, :null => false'],
|
9
|
+
[:keywords, 't.string :keywords'],
|
10
|
+
[:description, 't.string :description'],
|
11
|
+
[:category, 't.string :category'],
|
12
|
+
[:formatting, 't.string :formatting, :default => "plain", :null => false'],
|
13
|
+
[:published, 't.boolean :published, :default => false, :null => false']
|
14
|
+
].delete_if {|c| existing_columns.include?(c.first.to_s)}
|
15
|
+
-%>
|
16
|
+
change_table(:pages) do |t|
|
17
|
+
<% columns.each do |c| -%>
|
18
|
+
<%= c.last %>
|
19
|
+
<% end -%>
|
20
|
+
end
|
21
|
+
|
22
|
+
<%
|
23
|
+
existing_indexes = ActiveRecord::Base.connection.indexes(:pages)
|
24
|
+
index_names = existing_indexes.collect { |each| each.name }
|
25
|
+
new_indexes = [
|
26
|
+
[:index_pages_on_id_and_url_and_published, 'add_index :pages, [:id, :url, :published]']
|
27
|
+
].delete_if { |each| index_names.include?(each.first.to_s) }
|
28
|
+
-%>
|
29
|
+
<% new_indexes.each do |each| -%>
|
30
|
+
<%= each.last %>
|
31
|
+
<% end -%>
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.down
|
35
|
+
change_table(:pages) do |t|
|
36
|
+
<% unless columns.empty? -%>
|
37
|
+
t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %>
|
38
|
+
<% end -%>
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/spreadhead.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
if defined?(ActionController::Routing::RouteSet)
|
2
|
+
class ActionController::Routing::RouteSet
|
3
|
+
def load_routes_with_spreadhead!
|
4
|
+
lib_path = File.dirname(__FILE__)
|
5
|
+
spreadhead_routes = File.join(lib_path, *%w[.. .. .. config spreadhead_routes.rb])
|
6
|
+
unless configuration_files.include?(spreadhead_routes)
|
7
|
+
add_configuration_file(spreadhead_routes)
|
8
|
+
end
|
9
|
+
load_routes_without_spreadhead!
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :load_routes!, :spreadhead
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Spreadhead
|
2
|
+
module Page
|
3
|
+
|
4
|
+
# Hook for all Spreadhead::Page modules.
|
5
|
+
#
|
6
|
+
# If you need to override parts of Spreadhead::Page,
|
7
|
+
# extend and include à la carte.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# extend ClassMethods
|
11
|
+
# include InstanceMethods
|
12
|
+
# include AttrAccessor
|
13
|
+
# include Callbacks
|
14
|
+
#
|
15
|
+
# @see ClassMethods
|
16
|
+
# @see InstanceMethods
|
17
|
+
# @see Validations
|
18
|
+
# @see Scopes
|
19
|
+
# @see Callbacks
|
20
|
+
def self.included(model)
|
21
|
+
model.extend(ClassMethods)
|
22
|
+
model.send(:include, InstanceMethods)
|
23
|
+
model.send(:include, Validations)
|
24
|
+
model.send(:include, Scopes)
|
25
|
+
model.send(:include, Callbacks)
|
26
|
+
end
|
27
|
+
|
28
|
+
module Validations
|
29
|
+
# Hook for validations.
|
30
|
+
#
|
31
|
+
# :title must be present and unique
|
32
|
+
# :text must be present
|
33
|
+
# :url must be unique
|
34
|
+
def self.included(model)
|
35
|
+
model.class_eval do
|
36
|
+
validates_presence_of :text
|
37
|
+
validates_presence_of :title
|
38
|
+
validates_uniqueness_of :title
|
39
|
+
validates_uniqueness_of :url
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Scopes
|
45
|
+
# Hook for scopes.
|
46
|
+
#
|
47
|
+
# :published should have its own scope
|
48
|
+
def self.included(model)
|
49
|
+
model.class_eval do
|
50
|
+
named_scope :published, :conditions => ['published = ?', true]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Callbacks
|
56
|
+
# Hook for callbacks.
|
57
|
+
#
|
58
|
+
# :title should act like a url.
|
59
|
+
def self.included(model)
|
60
|
+
model.class_eval do
|
61
|
+
attr_protected :url
|
62
|
+
acts_as_url :title, :sync_url => true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module InstanceMethods
|
68
|
+
# The default parameter method for pages is the url
|
69
|
+
def to_param
|
70
|
+
url
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module ClassMethods
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'redcloth'
|
2
|
+
require 'bluecloth'
|
3
|
+
|
4
|
+
module Spreadhead
|
5
|
+
module Render
|
6
|
+
|
7
|
+
def self.included(controller) # :nodoc:
|
8
|
+
controller.send(:include, InstanceMethods)
|
9
|
+
controller.class_eval do
|
10
|
+
helper_method :spreadhead
|
11
|
+
hide_action :spreadhead
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
# Show the contents of the specified page to be used when rendering. The
|
17
|
+
# page parameter can be either a string (the page url) or a Page object.
|
18
|
+
#
|
19
|
+
# @return The page text as a string
|
20
|
+
def spreadhead(page)
|
21
|
+
return '' unless page
|
22
|
+
page = ::Page.find_by_url!(page) if page.is_a? String
|
23
|
+
|
24
|
+
case page.formatting
|
25
|
+
when 'markdown'
|
26
|
+
markdown(page.text)
|
27
|
+
when 'textile'
|
28
|
+
RedCloth.new(page.text).to_html
|
29
|
+
else
|
30
|
+
page.text
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'spreadhead'
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../rails/test/factories/spreadhead")
|
3
|
+
|
4
|
+
class PagesControllerTest < ActionController::TestCase
|
5
|
+
|
6
|
+
tests Spreadhead::PagesController
|
7
|
+
|
8
|
+
context "on GET to #new" do
|
9
|
+
setup { get :new }
|
10
|
+
|
11
|
+
should_respond_with :success
|
12
|
+
should_render_template :new
|
13
|
+
should_not_set_the_flash
|
14
|
+
end
|
15
|
+
|
16
|
+
context "on GET to #index" do
|
17
|
+
setup { get :index }
|
18
|
+
|
19
|
+
should_respond_with :success
|
20
|
+
should_render_template :index
|
21
|
+
should_not_set_the_flash
|
22
|
+
end
|
23
|
+
|
24
|
+
context "on GET to #show" do
|
25
|
+
setup do
|
26
|
+
page = Factory(:page)
|
27
|
+
get :show, :id => page.url
|
28
|
+
end
|
29
|
+
|
30
|
+
should_respond_with :success
|
31
|
+
should_render_template :show
|
32
|
+
should_not_set_the_flash
|
33
|
+
end
|
34
|
+
|
35
|
+
context "on GET to #edit" do
|
36
|
+
setup do
|
37
|
+
page = Factory(:page)
|
38
|
+
get :edit, :id => page.url
|
39
|
+
end
|
40
|
+
|
41
|
+
should_respond_with :success
|
42
|
+
should_render_template :edit
|
43
|
+
should_not_set_the_flash
|
44
|
+
end
|
45
|
+
|
46
|
+
context "on POST to #create with valid attributes" do
|
47
|
+
setup do
|
48
|
+
page_attributes = Factory.attributes_for(:page)
|
49
|
+
post :create, :page => page_attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
should_respond_with :redirect
|
53
|
+
should_not_set_the_flash
|
54
|
+
end
|
55
|
+
|
56
|
+
context "on PUT to #update with valid attributes" do
|
57
|
+
setup do
|
58
|
+
page = Factory(:page)
|
59
|
+
put :update, :id => page.url, :page => page.attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
should_respond_with :redirect
|
63
|
+
should_not_set_the_flash
|
64
|
+
end
|
65
|
+
|
66
|
+
context "on DELETE to #destroy with valid attributes" do
|
67
|
+
setup do
|
68
|
+
page = Factory(:page)
|
69
|
+
delete :destroy, :id => page.url
|
70
|
+
end
|
71
|
+
|
72
|
+
should_respond_with :redirect
|
73
|
+
should_not_set_the_flash
|
74
|
+
|
75
|
+
should "Destroy the page" do
|
76
|
+
count = Page.count
|
77
|
+
page = Factory(:page)
|
78
|
+
delete :destroy, :id => page.url
|
79
|
+
assert_equal Page.count, count
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../rails/test/factories/spreadhead")
|
3
|
+
|
4
|
+
class PageTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
context "When creating a page" do
|
7
|
+
setup { Factory(:page) }
|
8
|
+
|
9
|
+
should_validate_presence_of :text, :title
|
10
|
+
should_validate_uniqueness_of :title, :url
|
11
|
+
should_not_allow_mass_assignment_of :url
|
12
|
+
|
13
|
+
should "generate a url" do
|
14
|
+
page = Factory.build(:page, :title => 'smack!')
|
15
|
+
assert page.save
|
16
|
+
assert_not_nil page.url
|
17
|
+
assert_equal 'smack', page.url
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "When retrieving a page" do
|
22
|
+
setup { Factory(:page) }
|
23
|
+
|
24
|
+
should_have_named_scope :published
|
25
|
+
|
26
|
+
should "use the url as the default parameter" do
|
27
|
+
page = Factory(:page, :title => 'whammo')
|
28
|
+
assert_equal 'whammo', page.to_param
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jeffrafter-spreadhead
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Rafter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-14 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: BlueCloth
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: RedCloth
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rsl-stringex
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: Rails content mangement for pages that shouldn't be views.
|
46
|
+
email: jeff@socialrange.org
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README.textile
|
54
|
+
files:
|
55
|
+
- CHANGELOG.textile
|
56
|
+
- LICENSE
|
57
|
+
- README.textile
|
58
|
+
- Rakefile
|
59
|
+
- TODO.textile
|
60
|
+
- VERSION
|
61
|
+
- app/controllers/spreadhead/pages_controller.rb
|
62
|
+
- app/views/spreadhead/pages/_form.html.erb
|
63
|
+
- app/views/spreadhead/pages/edit.html.erb
|
64
|
+
- app/views/spreadhead/pages/index.html.erb
|
65
|
+
- app/views/spreadhead/pages/new.html.erb
|
66
|
+
- app/views/spreadhead/pages/show.html.erb
|
67
|
+
- config/spreadhead_routes.rb
|
68
|
+
- generators/spreadhead/USAGE
|
69
|
+
- generators/spreadhead/lib/insert_commands.rb
|
70
|
+
- generators/spreadhead/lib/rake_commands.rb
|
71
|
+
- generators/spreadhead/spreadhead_generator.rb
|
72
|
+
- generators/spreadhead/templates/README
|
73
|
+
- generators/spreadhead/templates/factories.rb
|
74
|
+
- generators/spreadhead/templates/initializer.rb
|
75
|
+
- generators/spreadhead/templates/migrations/create_pages.rb
|
76
|
+
- generators/spreadhead/templates/migrations/update_pages.rb
|
77
|
+
- generators/spreadhead/templates/page.rb
|
78
|
+
- lib/spreadhead.rb
|
79
|
+
- lib/spreadhead/extensions/routes.rb
|
80
|
+
- lib/spreadhead/page.rb
|
81
|
+
- lib/spreadhead/render.rb
|
82
|
+
- rails/init.rb
|
83
|
+
- test/controllers/pages_controller_test.rb
|
84
|
+
- test/models/page_test.rb
|
85
|
+
- test/test_helper.rb
|
86
|
+
has_rdoc: false
|
87
|
+
homepage: http://github.com/jeffrafter/spreadhead
|
88
|
+
licenses:
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options:
|
91
|
+
- --charset=UTF-8
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
version:
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: "0"
|
105
|
+
version:
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 1.3.5
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Rails content mangement for pages that shouldn't be views.
|
113
|
+
test_files:
|
114
|
+
- test/controllers/pages_controller_test.rb
|
115
|
+
- test/models/page_test.rb
|
116
|
+
- test/test_helper.rb
|