browsercms 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/app/models/content_type.rb +2 -2
- data/app/views/cms/form_builder/_cms_text_field.html.erb +2 -1
- data/browsercms.gemspec +1278 -1272
- data/doc/guides/html/building_modules.html +193 -0
- data/doc/guides/html/designer_guide.html +11 -1
- data/doc/guides/html/developer_guide.html +43 -1
- data/doc/guides/html/getting_started.html +1 -1
- data/lib/cms/authentication/controller.rb +3 -2
- data/lib/cms/extensions/active_record/connection_adapters/abstract/schema_statements.rb +41 -25
- data/lib/cms/routes.rb +4 -1
- data/lib/tasks/db.rake +5 -1
- data/rails_generators/content_block/templates/migration.rb +2 -1
- data/test/unit/lib/routes_test.rb +57 -0
- data/test/unit/models/content_type_test.rb +22 -1
- data/test/unit/schema_statements_test.rb +41 -0
- metadata +51 -48
@@ -0,0 +1,193 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<title></title>
|
6
|
+
<link rel="stylesheet" type="text/css" href="files/stylesheets/syntax.css" />
|
7
|
+
<script type="text/javascript" src="files/javascripts/code_highlighter.js"></script>
|
8
|
+
<script type="text/javascript" src="files/javascripts/highlighters.js"></script>
|
9
|
+
<style type="text/css">
|
10
|
+
body {
|
11
|
+
background: #FFFFFF url(images/bg.png) repeat-x scroll 0 0;
|
12
|
+
font-family: "Trebuchet MS", Helvetica, Verdana, Arial, sans-serif;
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
}
|
16
|
+
|
17
|
+
#page {
|
18
|
+
margin: 0 auto;
|
19
|
+
text-align: left;
|
20
|
+
width: 1000px;
|
21
|
+
}
|
22
|
+
|
23
|
+
#header {
|
24
|
+
height: 110px;
|
25
|
+
}
|
26
|
+
|
27
|
+
div.top_cap {
|
28
|
+
background: transparent url(images/top_cap.png) no-repeat scroll 0 0;
|
29
|
+
height: 10px;
|
30
|
+
}
|
31
|
+
|
32
|
+
#contentwrap {
|
33
|
+
background: transparent url(images/dot.png) repeat scroll 0 0;
|
34
|
+
float: left;
|
35
|
+
width: 1000px;
|
36
|
+
}
|
37
|
+
|
38
|
+
div.bottom_cap {
|
39
|
+
background: transparent url(images/bottom_cap.png) no-repeat scroll 0 0;
|
40
|
+
height: 9px;
|
41
|
+
}
|
42
|
+
|
43
|
+
div.top_cap_content {
|
44
|
+
background: transparent url(images/top_cap_content.png) no-repeat scroll 0 0;
|
45
|
+
height: 5px;
|
46
|
+
}
|
47
|
+
|
48
|
+
#content {
|
49
|
+
background-color: #FFFFFF;
|
50
|
+
margin: 0 5px;
|
51
|
+
padding: 0 10px;
|
52
|
+
}
|
53
|
+
|
54
|
+
div.title {
|
55
|
+
padding: 20px;
|
56
|
+
}
|
57
|
+
|
58
|
+
div.title h1 {
|
59
|
+
border-bottom: 3px solid #505358;
|
60
|
+
color: #FFFFFF;
|
61
|
+
font-size: 24pt;
|
62
|
+
font-weight: normal;
|
63
|
+
line-height: 1;
|
64
|
+
margin: 0 0 10px;
|
65
|
+
padding-bottom: 10px;
|
66
|
+
}
|
67
|
+
|
68
|
+
td.sidebar {
|
69
|
+
font-size: 8pt;
|
70
|
+
width: 165px;
|
71
|
+
padding: 5px;
|
72
|
+
}
|
73
|
+
|
74
|
+
td.sidebar ol {
|
75
|
+
margin-left: 20px;
|
76
|
+
padding: 0;
|
77
|
+
line-height: 1.5;
|
78
|
+
}
|
79
|
+
|
80
|
+
td.sidebar ol li {
|
81
|
+
margin: 0;
|
82
|
+
padding: 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
td.sidebar ol li ul {
|
86
|
+
list-style-type: none;
|
87
|
+
padding-left: 10px;
|
88
|
+
}
|
89
|
+
|
90
|
+
td.guides {
|
91
|
+
font-size: 10pt;
|
92
|
+
width: 800px;
|
93
|
+
padding: 10px;
|
94
|
+
}
|
95
|
+
|
96
|
+
.code_container {
|
97
|
+
padding: 10px;
|
98
|
+
background: #eee;
|
99
|
+
border: 1px solid #ccc;
|
100
|
+
overflow: auto;
|
101
|
+
width: 760px;
|
102
|
+
}
|
103
|
+
|
104
|
+
pre, code {
|
105
|
+
overflow: auto;
|
106
|
+
white-space:pre;
|
107
|
+
}
|
108
|
+
|
109
|
+
</style>
|
110
|
+
</head>
|
111
|
+
<body>
|
112
|
+
<div id="page">
|
113
|
+
<div id="header">
|
114
|
+
<a href="index.html"><img style="border:0px" src="images/browsercms_logo.png" alt="BrowserCMS"/></a>
|
115
|
+
</div>
|
116
|
+
<div id="main">
|
117
|
+
<div class="top_cap"></div>
|
118
|
+
<div id="contentwrap">
|
119
|
+
<div class="title">
|
120
|
+
<h1></h1>
|
121
|
+
</div>
|
122
|
+
<div class="top_cap_content"></div>
|
123
|
+
<div id="content">
|
124
|
+
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
125
|
+
<tr>
|
126
|
+
<td class="sidebar" valign="top">
|
127
|
+
<div id="subCol">
|
128
|
+
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
|
129
|
+
<ol class="chapters">
|
130
|
+
</ol></div>
|
131
|
+
</td>
|
132
|
+
<td class="guides">
|
133
|
+
|
134
|
+
<h2>Using <span class="caps">CMS</span> Authentication</h2>
|
135
|
+
<p>When you create public controllers, you may want to take advantage of the <span class="caps">CMS</span> authentication system. Create an action that
|
136
|
+
looks like this:</p>
|
137
|
+
<div class="code_container"><code class="ruby">class MyNewController < ApplicationController
|
138
|
+
|
139
|
+
# This adds methods to your controller to work with the authenticated user.
|
140
|
+
include Cms::Authentication::Controller
|
141
|
+
|
142
|
+
def do_something_interesting
|
143
|
+
# The current_user method looks up the user based on either a cookie, or session variable.
|
144
|
+
user = current_user
|
145
|
+
|
146
|
+
if user.guest?
|
147
|
+
redirect_to "/system/access-denied"
|
148
|
+
else
|
149
|
+
redirect_to "/my_target/page"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end</code></div>
|
153
|
+
<p>The current_user method is also available in Portlets (maybe), as well as in the view files for both portlets and templates.</p>
|
154
|
+
<h3>Understanding Guest users
|
155
|
+
Many visitors to a <span class="caps">CMS</span> site will not be logged in. These users are considered to be members of a special group, called ‘Guest’. This
|
156
|
+
group allows staff to set permissions for denying entry to specific sections. When you call the following:</h3>
|
157
|
+
<div class="code_container"><code class="ruby">user = current_user</code></div>
|
158
|
+
<p>if there the user is not logged in, a
|
159
|
+
dirty_workaround_for_notextile_2
|
160
|
+
object will be returned. This user has all the permissions of the guest group, which are
|
161
|
+
usually limited to viewing public sections.</p>
|
162
|
+
<h2>Working with the Content <span class="caps">API</span>
|
163
|
+
One of the central features that the content <span class="caps">API</span> adds to models is versioning and publishing. Each content block can either be published or in draft. The data for a block is split between two tables, the primary table and it’s version table. The primary table
|
164
|
+
stores the ‘live’ version of a block, typically the last ‘Published’ version of a block. The versions table stores all other versions, including future edits which are unpublished.</h2>
|
165
|
+
<h3>Differences between ActiveRecord and Content <span class="caps">API</span>
|
166
|
+
This can cause some confusion when using basic ActiveRecord operations, where you might not get what you expect. For example, suppose we create an Event Block</h3>
|
167
|
+
<div class="code_container"><code class="ruby">class Event < ActiveRecord::Base
|
168
|
+
acts_as_content_block
|
169
|
+
end
|
170
|
+
|
171
|
+
event = Event.create!(:name=>"Event #1", :save_and_publish=>true)
|
172
|
+
event.name = "Event #2"
|
173
|
+
event.save!
|
174
|
+
|
175
|
+
assert_equals "Event #2", Event.find(event.id) # This is false, and will fail.</code></div>
|
176
|
+
<p>In this case, “Event #2” is a draft, stored in the ‘events_versions’ table. To create and publish the event, you can do this:</p>
|
177
|
+
<div class="code_container"><code class="ruby">event = Event.create!(:name=>"Event #1", :save_and_publish=>true)
|
178
|
+
event.name = "Event #2"
|
179
|
+
event.publish! # This will both publish and save the record.
|
180
|
+
|
181
|
+
assert_equals "Event #2", Event.find(event.id) # This is now true.</code></div>
|
182
|
+
</td>
|
183
|
+
</tr>
|
184
|
+
</table>
|
185
|
+
</div>
|
186
|
+
</div>
|
187
|
+
<br clear="all"/>
|
188
|
+
<div class="bottom_cap"></div>
|
189
|
+
</div>
|
190
|
+
</div>
|
191
|
+
</body>
|
192
|
+
</html>
|
193
|
+
|
@@ -138,7 +138,17 @@
|
|
138
138
|
<li>How to use helpers to add dynamic content to templates and partials</li>
|
139
139
|
<li>How to use the <span class="caps">CMS</span>-specific form builder extensions</li>
|
140
140
|
</ul>
|
141
|
-
|
141
|
+
<h2>Creating a template
|
142
|
+
Each page in BrowserCMS uses a single template, which is designed to provide overall layout structure of the page. Here’s the general process
|
143
|
+
that a design team might follow to create a <span class="caps">CMS</span> template.</h2>
|
144
|
+
<p>1. Start with a <span class="caps">PSD</span> or <span class="caps">JPG</span> of the design, which represents the end result of what the webpage should look like.
|
145
|
+
2. Create a static html file which implements that design.
|
146
|
+
3. When creating menus, use the same structural <span class="caps">HTML</span> markup as will be generated by the Menu <span class="caps">API</span>. (See Menu’s below)
|
147
|
+
4. Change the file extension from .htm to .html.erb and add it as a template to the <span class="caps">CMS</span>.</p>
|
148
|
+
<h2>Menus
|
149
|
+
BrowserCMS provides an <span class="caps">API</span> to allow menus to be dynamically generated based on the sitemap. The purpose of this is to make
|
150
|
+
it easy to add new pages, without having to modify templates.</h2>
|
151
|
+
<div class="code_container"><code class="ruby">render_menu</code></div>
|
142
152
|
</td>
|
143
153
|
</tr>
|
144
154
|
</table>
|
@@ -127,7 +127,7 @@
|
|
127
127
|
<div id="subCol">
|
128
128
|
<h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
|
129
129
|
<ol class="chapters">
|
130
|
-
<li><a href="#content-blocks">Content Blocks</a><ul></ul></li><li><a href="#creating-a-custom-content-block">Creating A Custom Content Block</a><ul></ul></li><li><a href="#creating-a-custom-portlet">Creating A Custom Portlet</a><ul><li><a href="#using-file-system-templates">Using File system templates</a></li><li><a href="#pre-selecting-a-handler">Pre-selecting a handler</a></li></ul></li><li><a href="#page-routes">Page Routes</a><ul></ul></li></ol></div>
|
130
|
+
<li><a href="#content-blocks">Content Blocks</a><ul></ul></li><li><a href="#creating-a-custom-content-block">Creating A Custom Content Block</a><ul><li><a href="#attribute-types">Attribute Types</a></li></ul></li><li><a href="#creating-a-custom-portlet">Creating A Custom Portlet</a><ul><li><a href="#using-file-system-templates">Using File system templates</a></li><li><a href="#pre-selecting-a-handler">Pre-selecting a handler</a></li></ul></li><li><a href="#page-routes">Page Routes</a><ul></ul></li></ol></div>
|
131
131
|
</td>
|
132
132
|
<td class="guides">
|
133
133
|
<h2>BrowserCMS Developer Guide</h2>
|
@@ -170,6 +170,48 @@ end</code></div>
|
|
170
170
|
<p>The form helper methods that are prefixed with <tt>cms_</tt> will wrap that form helper with the <span class="caps">CMS</span> styling and extra functionality. The <tt>cms_text_editor</tt> will show the user a <span class="caps">WYSIWYG</span> editor for editing <span class="caps">HTML</span>. Additional <span class="caps">CMS</span> form builder extensions are covered in the <a href="designer_guide.html">BrowserCMS Designer Guide</a>.</p>
|
171
171
|
<p>The render template at <tt>app/views/cms/products/render.html.erb</tt> is the template that will be used to render the <span class="caps">HTML</span> when this product is placed directly on a page. It is also what is shown when you view a product within the content library of the <span class="caps">CMS</span>.</p>
|
172
172
|
<p>As you will see in the next section, custom content blocks are often not placed directly on a page, instead the data of a product is displayed through a portlet. For this reason, a more informational display, similar to what is automatically generated by the generator, is what the render template often contains. Depending on what your content block is, you may want to place the content block directly on a page, in which case you would most likely customize the render template.</p>
|
173
|
+
<h4 id="attribute-types">2.1 Attribute Types
|
174
|
+
This section covers some of the different attribute types that Content Blocks can have. Each attribute represents a
|
175
|
+
persistent column in the database, will appear as an editable control on the <em>form.html.erb, and may also need to need to be configured
|
176
|
+
on the content</em>block itself.</h4>
|
177
|
+
<p>List of Content Types</p>
|
178
|
+
<ul>
|
179
|
+
<li>Text Fields</li>
|
180
|
+
<li>Text Areas</li>
|
181
|
+
<li>Drop Down (Select)</li>
|
182
|
+
<li>Text Editor (<span class="caps">WYWIWYG</span>)</li>
|
183
|
+
<li>Attachment (File Upload)</li>
|
184
|
+
<li>Tag List (Allow</li>
|
185
|
+
<li>Date Picker</li>
|
186
|
+
</ul>
|
187
|
+
<h5 id="drop-down--selects">2.1.1 Drop Down / Selects
|
188
|
+
This is similar to the traditional ‘select’ helper, it renders a stylized select control which allows users to choose one item from a list.</h5>
|
189
|
+
<h6 id="cms-drop-down">2.1.1.1 cms_drop_down
|
190
|
+
In _form.html.erb:</h6>
|
191
|
+
<div class="code_container"><code class="html"><%= f.cms_drop_down :category_id, Category.all(:order => "name").map{|c| [c.name, c.id]},
|
192
|
+
:prompt => "Select a Category", :label => "Category",
|
193
|
+
:instructions=>"Determines which category is used on the homepage." %></code></div>
|
194
|
+
<p>In product.rb:</p>
|
195
|
+
<div class="code_container"><code class="ruby">class Product < ActiveRecord::Base
|
196
|
+
belongs_to :category
|
197
|
+
end</code></div>
|
198
|
+
<h5 id="attachments">2.1.2 Attachments
|
199
|
+
Each content block can have a single file attachment, which will allow users to upload files into the content repository. After uploading, the file will be
|
200
|
+
stored in a section within the <span class="caps">CMS</span>. Since sections determine permissions, this will allow you to control which users can access the file itself. Attached files
|
201
|
+
will have their own versioning history, which will keep track of changes.</h5>
|
202
|
+
<h6 id="cms-file-field">2.1.2.1 cms_file_field
|
203
|
+
This helper will create a stylized file upload file. An uploaded file will be associated with the content_block to which it is attached.</h6>
|
204
|
+
<p>In _form.html.erb (View)</p>
|
205
|
+
<div class="code_container"><code class="html"><%= f.cms_file_field :attachment_file, :label => "File" %></code></div>
|
206
|
+
<p>In product.rb (Model)</p>
|
207
|
+
<div class="code_container"><code class="ruby">class Product < ActiveRecord::Base
|
208
|
+
acts_as_content_block :belongs_to_attachment => true
|
209
|
+
end</code></div>
|
210
|
+
<p>In create_products.rb (Migration)</p>
|
211
|
+
<div class="code_container"><code class="ruby">create_content_table :products do |t|
|
212
|
+
t.belongs_to :attachment
|
213
|
+
t.integer :attachment_version
|
214
|
+
end</code></div>
|
173
215
|
<h3 id="creating-a-custom-portlet">3 Creating A Custom Portlet</h3>
|
174
216
|
<p>Once you have created the product content block and created a few products in the content library, you need a way to display them on a page. To do that, you will want to create a portlet.</p>
|
175
217
|
<p>A portlet is used to display dynamic data on a page. A portlet is a content block. A portlet will typically perform some kind of database query in the render method and then render it’s view. One difference between a portlet and typical content block is that each instance of a portlet can have a unique template because that template is stored as data along with the portlet. Let’s generate a portlet to display the most recently created products:</p>
|
@@ -155,7 +155,7 @@ $ script/server</code></div>
|
|
155
155
|
<div class="code_container"><code class="html">$ rails my_new_project_name -d mysql -m http://browsercms.org/templates/demo.rb
|
156
156
|
$ cd my_new_project_name
|
157
157
|
$ script/server</code></div>
|
158
|
-
<p>Here we specify the -
|
158
|
+
<p>Here we specify the -d mysql flag to rails, which will create our project using MySQL. You need to have the mysql gem installed for this to work.</p>
|
159
159
|
<h4 id="using-your-site">2.3 Using your Site</h4>
|
160
160
|
<p>Open your browser to <a href="http://localhost:3000/cms">http://localhost:3000/cms</a> to log into the admin for the <span class="caps">CMS</span>. Enter the default username/password (in development mode) is username=cmsadmin, password=cmsadmin. You should be now be logged in, viewing the home page of the site. You can now edit or add new content via the admin interface.</p>
|
161
161
|
<p>To learn more about the types of things you can do with BrowserCMS, see the <a href="user_guide.html">User’s Guide</a>.</p>
|
@@ -8,8 +8,9 @@ module Cms
|
|
8
8
|
!current_user.nil? && !current_user.guest?
|
9
9
|
end
|
10
10
|
|
11
|
-
# Accesses the current user from the session.
|
12
|
-
# If the user is not logged in, this will be set to the guest user
|
11
|
+
# Accesses the current user from the session or 'remember me' cookie.
|
12
|
+
# If the user is not logged in, this will be set to the guest user, which represents a public
|
13
|
+
# user, who will likely have more limited permissions
|
13
14
|
def current_user
|
14
15
|
@current_user ||= begin
|
15
16
|
User.current = (login_from_session || login_from_cookie || User.guest)
|
@@ -1,14 +1,19 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters # :nodoc:
|
3
3
|
module SchemaStatements
|
4
|
-
|
4
|
+
|
5
|
+
# Pass in ":versioned => false" in the options hash to create a non-versioned table.
|
6
|
+
def create_content_table(table_name, options={}, &block)
|
5
7
|
|
6
8
|
#Do the primary table
|
7
9
|
t = TableDefinition.new(self)
|
8
10
|
t.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
unless options[:versioned] == false
|
13
|
+
t.integer :version
|
14
|
+
t.integer :lock_version, :default => 0
|
15
|
+
end
|
16
|
+
|
12
17
|
yield t
|
13
18
|
|
14
19
|
# Blocks currently must have a name column, otherwise the UI fails in several places.
|
@@ -21,35 +26,40 @@ module ActiveRecord
|
|
21
26
|
t.integer :created_by_id
|
22
27
|
t.integer :updated_by_id
|
23
28
|
t.timestamps
|
24
|
-
|
25
29
|
|
26
30
|
create_table_from_definition(table_name, options, t)
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
unless options[:versioned] == false
|
33
|
+
#Do the versions table
|
34
|
+
vt = TableDefinition.new(self)
|
35
|
+
vt.primary_key(options[:primary_key] || Base.get_primary_key(table_name)) unless options[:id] == false
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
vt.integer "#{table_name.to_s.singularize}_id".to_sym
|
38
|
+
vt.integer :version
|
39
|
+
yield vt
|
35
40
|
|
36
|
-
|
37
|
-
|
41
|
+
# Create implicit name column in version table as well.
|
42
|
+
vt.string :name unless vt[:name]
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
vt.boolean :published, :default => false
|
45
|
+
vt.boolean :deleted, :default => false
|
46
|
+
vt.boolean :archived, :default => false
|
47
|
+
vt.string :version_comment
|
48
|
+
vt.integer :created_by_id
|
49
|
+
vt.integer :updated_by_id
|
50
|
+
vt.timestamps
|
47
51
|
|
48
|
-
|
49
|
-
|
52
|
+
create_table_from_definition("#{table_name.to_s.singularize}_versions".to_sym, options, vt)
|
53
|
+
end
|
50
54
|
|
51
55
|
end
|
52
|
-
|
56
|
+
|
57
|
+
#
|
58
|
+
# @deprecated - create_versioned_table should be considered deprecated and may be removed in a future version.
|
59
|
+
# Use create_content_table instead in your migrations
|
60
|
+
#
|
61
|
+
alias :create_versioned_table :create_content_table
|
62
|
+
|
53
63
|
def create_table_from_definition(table_name, options, table_definition)
|
54
64
|
if options[:force] && table_exists?(table_name)
|
55
65
|
drop_table(table_name, options)
|
@@ -66,7 +76,13 @@ module ActiveRecord
|
|
66
76
|
drop_table "#{table_name.singularize}_versions".to_sym
|
67
77
|
drop_table table_name
|
68
78
|
end
|
69
|
-
|
79
|
+
|
80
|
+
# Adds a column to both the primary and versioned table. Save needing two calls.
|
81
|
+
# This is only needed if your content block is versioned, otherwise add_column will work just fine.
|
82
|
+
def add_content_column(table_name, column_name, type, options={})
|
83
|
+
add_column table_name, column_name, type, options
|
84
|
+
add_column "#{table_name.to_s.singularize}_versions".to_sym, column_name, type, options
|
85
|
+
end
|
70
86
|
end
|
71
87
|
end
|
72
|
-
end
|
88
|
+
end
|
data/lib/cms/routes.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module Cms::Routes
|
2
|
-
|
2
|
+
|
3
|
+
#
|
4
|
+
# content_block_name - Should be a plural symbol matching the name of the content_block, like :dogs or donation_statuses
|
5
|
+
#
|
3
6
|
def content_blocks(content_block_name, options={}, &block)
|
4
7
|
content_block = content_block_name.to_s.classify.constantize
|
5
8
|
resources(*[content_block_name, default_routes_for_content_block(content_block).deep_merge(options)], &block)
|
data/lib/tasks/db.rake
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'find'
|
2
2
|
|
3
3
|
namespace :db do
|
4
|
+
|
5
|
+
desc "Drop, create and migrate the database"
|
6
|
+
task :redo => ["db:drop", "db:create", "db:migrate"]
|
7
|
+
|
4
8
|
namespace :fixtures do
|
5
9
|
desc 'Dumps all models into fixtures.'
|
6
10
|
task :dump => :environment do
|
@@ -14,7 +18,7 @@ namespace :db do
|
|
14
18
|
puts "Models: " + models.join(', ')
|
15
19
|
|
16
20
|
models.each do |m|
|
17
|
-
model = m.classify.constantize
|
21
|
+
model = m.tableize.classify.constantize
|
18
22
|
create_fixture(model)
|
19
23
|
create_fixture(model.version_class) if model.versioned?
|
20
24
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class <%= migration_name %> < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
|
-
|
3
|
+
create_content_table :<%= table_name %> do |t|
|
4
4
|
<% for attribute in attributes -%>
|
5
5
|
<%=
|
6
6
|
case attribute.type
|
@@ -31,6 +31,7 @@ class <%= migration_name %> < ActiveRecord::Migration
|
|
31
31
|
def self.down
|
32
32
|
ContentType.delete_all(['name = ?', '<%= class_name %>'])
|
33
33
|
CategoryType.all(:conditions => ['name = ?', '<%= class_name.titleize %>']).each(&:destroy)
|
34
|
+
#If you aren't creating a versioned table, be sure to comment this out.
|
34
35
|
drop_table :<%= table_name.singularize %>_versions
|
35
36
|
drop_table :<%= table_name %>
|
36
37
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '/../../test_helper')
|
2
|
+
|
3
|
+
class RouteBuilder
|
4
|
+
include Cms::Routes
|
5
|
+
end
|
6
|
+
|
7
|
+
class Bear < ActiveRecord::Base
|
8
|
+
acts_as_content_block
|
9
|
+
end
|
10
|
+
|
11
|
+
class Kindness < ActiveRecord::Base
|
12
|
+
acts_as_content_block
|
13
|
+
end
|
14
|
+
|
15
|
+
class RoutesTest < ActiveSupport::TestCase
|
16
|
+
|
17
|
+
test "Verify behavior of classify, and how it works with already pluralized symbols" do
|
18
|
+
assert_equal "Kindness", :kindnesses.to_s.classify, "routes will pass 'plural' symbols to 'content_block', rather than single"
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
test "behavior of 'content_blocks' route generator" do
|
23
|
+
rb = RouteBuilder.new
|
24
|
+
|
25
|
+
# Expect
|
26
|
+
rb.expects(:resources).with(:bears, {:member => {:publish => :put, :usages => :get, :versions => :get}})
|
27
|
+
rb.expects(:version_cms_bears).with("/cms/bears/:id/version/:version", :controller => "cms/bears", :action => "version", :conditions => {:method => :get})
|
28
|
+
rb.expects(:revert_to_cms_bears).with(
|
29
|
+
"/cms/bears/:id/revert_to/:version",
|
30
|
+
:controller => "cms/bears",
|
31
|
+
:action => "revert_to",
|
32
|
+
:conditions => {:method => :put})
|
33
|
+
|
34
|
+
rb.content_blocks :bears
|
35
|
+
|
36
|
+
# Verifies the exact messages being passed to the route generator
|
37
|
+
end
|
38
|
+
|
39
|
+
test "model names with s at the end behave identically (since content_blocks expects plural symbols)" do
|
40
|
+
rb = RouteBuilder.new
|
41
|
+
|
42
|
+
# Expect
|
43
|
+
rb.expects(:resources).with(:kindnesses, {:member => {:publish => :put, :usages => :get, :versions => :get}})
|
44
|
+
rb.expects(:version_cms_kindnesses).with("/cms/kindnesses/:id/version/:version", :controller => "cms/kindnesses", :action => "version", :conditions => {:method => :get})
|
45
|
+
rb.expects(:revert_to_cms_kindnesses).with(
|
46
|
+
"/cms/kindnesses/:id/revert_to/:version",
|
47
|
+
:controller => "cms/kindnesses",
|
48
|
+
:action => "revert_to",
|
49
|
+
:conditions => {:method => :put})
|
50
|
+
|
51
|
+
rb.content_blocks :kindnesses
|
52
|
+
|
53
|
+
# Verifies the exact messages being passed to the route generator
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
end
|