spreadhead 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/CHANGELOG.textile +24 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +72 -0
  4. data/Rakefile +76 -0
  5. data/TODO.textile +6 -0
  6. data/TUTORIAL.textile +248 -0
  7. data/VERSION +1 -0
  8. data/app/controllers/spreadhead/pages_controller.rb +62 -0
  9. data/app/views/spreadhead/pages/_form.html.erb +40 -0
  10. data/app/views/spreadhead/pages/edit.html.erb +8 -0
  11. data/app/views/spreadhead/pages/index.html.erb +25 -0
  12. data/app/views/spreadhead/pages/new.html.erb +8 -0
  13. data/app/views/spreadhead/pages/show.html.erb +5 -0
  14. data/config/spreadhead_routes.rb +4 -0
  15. data/generators/spreadhead/USAGE +1 -0
  16. data/generators/spreadhead/lib/insert_commands.rb +33 -0
  17. data/generators/spreadhead/lib/rake_commands.rb +22 -0
  18. data/generators/spreadhead/spreadhead_generator.rb +42 -0
  19. data/generators/spreadhead/templates/README +24 -0
  20. data/generators/spreadhead/templates/factories.rb +12 -0
  21. data/generators/spreadhead/templates/initializer.rb +27 -0
  22. data/generators/spreadhead/templates/migrations/create_pages.rb +20 -0
  23. data/generators/spreadhead/templates/migrations/update_pages.rb +41 -0
  24. data/generators/spreadhead/templates/page.rb +3 -0
  25. data/lib/spreadhead.rb +7 -0
  26. data/lib/spreadhead/extensions/routes.rb +14 -0
  27. data/lib/spreadhead/filter.rb +7 -0
  28. data/lib/spreadhead/page.rb +82 -0
  29. data/lib/spreadhead/render.rb +35 -0
  30. data/lib/tasks/spreadhead_tasks.rake +16 -0
  31. data/rails/init.rb +1 -0
  32. data/test/controllers/pages_controller_test.rb +118 -0
  33. data/test/models/page_test.rb +67 -0
  34. data/test/models/render_test.rb +50 -0
  35. data/test/test_helper.rb +4 -0
  36. metadata +122 -0
data/CHANGELOG.textile ADDED
@@ -0,0 +1,24 @@
1
+ h2. 0.6.0
2
+
3
+ * Changed filter behavior, made editing disabled by default (Jeff Rafter)
4
+
5
+ h2. 0.5.0
6
+
7
+ * Added tasks for importing and exporting (Jeff Rafter)
8
+
9
+ h2. 0.4.0
10
+
11
+ * Removed to_param behavior for page resource (Jeff Rafter)
12
+ * Allowed for "/" in urls (Jeff Rafter)
13
+
14
+ h2. 0.3.0
15
+
16
+ * Added a view link (Jeff Rafter)
17
+
18
+ h2. 0.2.0 (unreleased)
19
+
20
+ * Support for URL editing and overriding (Jeff Rafter)
21
+
22
+ h2. 0.1.0
23
+
24
+ * Initial Release (Jeff Rafter)
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,72 @@
1
+ h1. Spreadhead
2
+
3
+ <strong>spreadhead</strong> <em>noun</em> two facing pages of a book or other publication.
4
+
5
+ Rails content management 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
+ Modify the initializer in @config/initializers/spreadhead.rb@ to control access.
43
+
44
+ h2. Routes
45
+
46
+ 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.
47
+
48
+ h2. Tutorial
49
+
50
+ Checkout the "tutorial":http://wiki.github.com/jeffrafter/spreadhead/tutorial.
51
+
52
+ h2. Authors
53
+
54
+ 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
55
+
56
+ The engine implementation and gem was patterned after the Clearance gem by Thoughtbot.
57
+
58
+ h2. Suggestions, Bugs, Refactoring?
59
+
60
+ Fork away and create a "Github Issue":http://github.com/jeffrafter/spreadhead/issues. Please send pull requests.
61
+
62
+ When you do:
63
+
64
+ * Fork the project.
65
+ * Make your feature addition or bug fix.
66
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
67
+ * 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)
68
+ * Send me a pull request. Bonus points for topic branches.
69
+
70
+ h2. Documentation
71
+
72
+ 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
@@ -0,0 +1,6 @@
1
+ h1. To-do
2
+
3
+ * Include alternate views for the forms
4
+ * Allow alternate layouts
5
+ * Caching, clearing cache
6
+ * Uploading images (basic)
data/TUTORIAL.textile ADDED
@@ -0,0 +1,248 @@
1
+ Before you can use Spreadhead you are going to need a few things, most importantly the spreadhead gem:
2
+
3
+ <pre>
4
+ <code>
5
+ sudo gem install jeffrafter-spreadhead --source=http://gems.github.com
6
+ </code>
7
+ </pre>
8
+
9
+ By default this should install the RedCloth gem, the BlueCloth gem, and the rsl-stringex gem. These handle the text and url formatting. If you want to run the spreadhead-specific tests, you will need Thoughtbot's shoulda and factory_girl. Once you have all of the requisite gems, you need to configure your Rails application to use the gem. You can do this by adding a config.gem statement to your environment.rb (or to a specific environment). For example:
10
+
11
+ <pre>
12
+ <code>
13
+ Rails::Initializer.run do |config|
14
+ # Specify gems that this application depends on and have them installed with
15
+ # rake gems:install
16
+ config.gem "spreadhead", :lib => "spreadhead"
17
+
18
+ # Skip frameworks you're not going to use. To use Rails without a database,
19
+ # you must remove the Active Record framework.
20
+ config.frameworks -= [ :active_resource ]
21
+
22
+ # Set Time.zone default to the specified zone and make Active Record
23
+ # auto-convert to this zone. Run "rake -D time" for a list of tasks for
24
+ # finding time zone names.
25
+ config.time_zone = 'UTC'
26
+ end
27
+ </code>
28
+ </pre>
29
+
30
+ After you have done this, you can use the spreadhead generator from the console (while in the rails root).
31
+
32
+ <pre>
33
+ <code>
34
+ script/generate spreadhead
35
+ </code>
36
+ </pre>
37
+
38
+ This will create (or update) a migration for the pages table, which is used to store all of the pages in your system. Additionally, it will create a Page model in your app/models folder. The model is blank except for an include statement to bring in all of the base functionality. By default the page creation and editing is completely disabled, you need to enable it in the @config/initializers/spreadhead.rb@ file.This is all you need to get started, you should be able to run the migration and restart your application and navigate to the "/pages" url.
39
+
40
+ h2. Security
41
+
42
+ It is important to note that allowing users to create pages, especially pages that can contain &lt;script&gt; tags is just a bad idea. You need to trust the user, which is also a bad idea. Because of this, page creation, editing, deleting - _everything_ - is disabled when you install it into your application. This is a safety feature to protect your app from some accidental inclusion or deployment.
43
+
44
+ To enable the application you need to modify initializer, where you can control which users get access to create, edit, destroy and update pages. To do this, you can add a before filter. If you are using a toolkit like Clearance, then you can use the something like the following:
45
+
46
+ <pre>
47
+ <code>
48
+ module Spreadhead
49
+ module PagesAuth
50
+ def self.filter(controller)
51
+ controller.redirect_to_root unless signed_in?
52
+ end
53
+ end
54
+ end
55
+ </code>
56
+ </pre>
57
+
58
+ If you give everyone access, this is probably still a bad idea and you will want to check that the current user is an admin:
59
+
60
+ <pre>
61
+ <code>
62
+ module Spreadhead
63
+ module PagesAuth
64
+ def self.filter(controller)
65
+ controller.redirect_to_root unless admin?
66
+ end
67
+ end
68
+ end
69
+ </code>
70
+ </pre>
71
+
72
+ Of course, you will probably want to add something to your application controller for checking if the current user is an admin:
73
+
74
+ <pre>
75
+ <code>
76
+ def admin?
77
+ signed_in? && current_user.admin?
78
+ end
79
+ </code>
80
+ </pre>
81
+
82
+ Remember to protect that admin attribute in your user model so that it can't be mass assigned.
83
+
84
+ This same kind of methodology will work for authlogic, restful_authentication, or your favorite authorization toolkit or homegrown solution. This really isn't the place for security how-to, but just keep in mind that if the hackers get access to this, they will win.
85
+
86
+ h2. What do I get?
87
+
88
+ By default you will have the "/pages":http://localhost:3000/pages resource. This is where you make new pages:
89
+
90
+ <div class="thumbnail"><a href="http://skitch.com/jeffrafter/b5anb/malachite.org-simpler-message-service"><img src="http://img.skitch.com/20090818-bfje6q835cdcnaf9hx2adj5qxx.preview.jpg" alt="Malachite.org - Simpler message service." /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>'s <a href="http://skitch.com">Skitch</a>!</span></div>
91
+
92
+ Once you have made a page you can access that by the created URL. If you title your page "Brachiosaurus or woozle!" and leave the URL blank it will be located at "/brachiosaurus-or-woozle" (notice that you don't need the leading "/"). If you wanted to get fancy you could set the URL yourself (or change it) to something like "2004/09/13/brachs-and-woo" and then you can access this full path from the root of your site.
93
+
94
+ You can blank the URL out at any time and Spreadhead will generate a new one. If there is a conflict it will add "-1" to the end (or "-2" and so on).
95
+
96
+ h2. Hey my routes aren't working
97
+
98
+ Maybe you have some fancy routes already, maybe something using a glob? Maybe something like:
99
+
100
+ <pre>
101
+ <code>
102
+ map.connect '/:username/:project_name', :controller => 'projects', :action => 'show', :conditions => {:method => :put}
103
+ </code>
104
+ </pre>
105
+
106
+ Well, that is going to catch anything before it gets to Spreadhead's routes (which have the lowest priority). You will probably want to redeclare the pages resource with a higher priority. Put this before the special route:
107
+
108
+ <pre>
109
+ <code>
110
+ map.resources :pages, :controller => 'spreadhead/pages'
111
+ </code>
112
+ </pre>
113
+
114
+ h2. Adding some style
115
+
116
+ The views for the admin interface are pretty plain:
117
+
118
+ <div class="thumbnail"><a href="http://skitch.com/jeffrafter/b5ab9/malachite.org-simpler-message-service"><img src="http://img.skitch.com/20090818-rpcd6uqf9u678a68rc5r4ed1tu.preview.jpg" alt="Malachite.org - Simpler message service." /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>'s <a href="http://skitch.com">Skitch</a>!</span></div>
119
+
120
+ But you might want to dress them up. I wanted to just drop some basic CSS here for now, but updates are welcome:
121
+
122
+ <pre>
123
+ <code>
124
+ div.checkbox,
125
+ div.text,
126
+ div.textarea,
127
+ div.select {
128
+ float:none;
129
+ clear:both;
130
+ padding-top:8px;
131
+ }
132
+ div.checkbox label,
133
+ div.text label,
134
+ div.textarea label,
135
+ div.select label {
136
+ padding-top:5px;
137
+ padding-right:15px;
138
+ display:block;
139
+ width:150px;
140
+ float:left;
141
+ text-align:right;
142
+ }
143
+ div.submit {
144
+ margin-top:10px;
145
+ padding-top:10px;
146
+ width:90%;
147
+ float:right;
148
+ border-top:1px dotted silver;
149
+ }
150
+ div.optional {
151
+ color:gray;
152
+ }
153
+ div.required {
154
+ }
155
+ div.syntax {
156
+ background:#4C5E29;
157
+ padding:4px;
158
+ color:white;
159
+ margin-left:165px;
160
+ margin-top:-3px;
161
+ width:324px;
162
+ text-align:right;
163
+ }
164
+ div.syntax a {
165
+ color:white;
166
+ }
167
+ input {
168
+ margin-top:4px;
169
+ }
170
+ select {
171
+ margin-top:4px;
172
+ }
173
+ textarea {
174
+ margin-top:4px;
175
+ }
176
+ </code>
177
+ </pre>
178
+
179
+ And some basic table styling:
180
+
181
+ <pre>
182
+ <code>
183
+ table.pages {
184
+ background:#FFFFFF none repeat scroll 0 0;
185
+ border-collapse:collapse;
186
+ margin-bottom:20px;
187
+ text-align:left;
188
+ -moz-background-clip:border;
189
+ -moz-background-inline-policy:continuous;
190
+ -moz-background-origin:padding;
191
+ }
192
+ table.pages th {
193
+ border-bottom:2px solid #4C5E29;
194
+ font-family:"Helvetica Neue",Arial,Helvetica,Geneva,sans-serif;
195
+ color:#4C5E29;
196
+ font-weight:normal;
197
+ padding:10px 8px;
198
+ }
199
+ table.pages td {
200
+ border-bottom:1px solid silver;
201
+ padding:6px 8px;
202
+ background:#EAEAEA;
203
+ }
204
+ table.pages td.odd {
205
+ }
206
+ table.pages td.even {
207
+ background:#DBDBDB;
208
+ }
209
+ table.pages tr:hover td {
210
+ background:#F3F3F3;
211
+ }
212
+ table.pages td.published, th.published {
213
+ text-align:center;
214
+ }
215
+ table.pages td.commands {
216
+ text-align:right;
217
+ }
218
+ </code>
219
+ </pre>
220
+
221
+
222
+ h2. Layouts and adding extension points to your site
223
+
224
+ The pages should render using the default application layout just fine, but you can add a few things to make this better. Spreadhead wants to push content for the title, the description, and even keywords. This allows you to do some basic page-specific optimization. Add the following to the &lt;head&gt; section of your site:
225
+
226
+ <pre>
227
+ <code>
228
+ <title>Yoursite.org - <%= @title || yield(:title) -%></title>
229
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
230
+ <meta name="Description" content="<%= yield :description -%>" />
231
+ <meta name="Keywords" content="<%= yield :keywords -%>" />
232
+ </code>
233
+ </pre>
234
+
235
+ You can also create nice little extension points for your users to modify smaller areas of the site. For example, you might have a welcome page that needs to have various cover information, but you want your client to be able to modify the copy on the front. Simply do the following:
236
+
237
+ <pre>
238
+ <code>
239
+ <div id="blurb"><%= spreadhead "welcome" -%></div>
240
+ </code>
241
+ </pre>
242
+
243
+ Then, the client simply needs to create a page with the URL "welcome" and Spreadhead will insert the content. This could be used for headers, footers (including links).
244
+
245
+
246
+ h2. Importing and exporting
247
+
248
+ Spreadhead comes with some basic rake tasks for importing and exporting the pages: @rake spreadhead:export@ and @rake spreadhead:import@. Exporting will dump a set of Yaml fixutres to the file @db/data/pages.yml@ in your rails root. Importing will erase all of the current pages and replace them with those in the @db/data/pages.yml@ file (or none if the file does not exist).