caboose-cms 0.2.70 → 0.2.71

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MWE2N2IxNDliN2ZmNjM3MDk5NzNkYjgxMWY0NGQ0NzhjZTFjMjkwMA==
4
+ YjZiMGI3ZWI5NTY4YTBkNDA2NjlhMjVlM2E5YjUzODVkYWNhY2NhNg==
5
5
  data.tar.gz: !binary |-
6
- YjI3MDM4NmU3MWI5YmEyMjM3N2MzZjdhMzFiOGEwNzBiNzNmM2I3Mg==
6
+ YjZlZmM5YWY2NWMxNjNlNDlhNGZiNzYwNDQ2ZWQ1OTg5ZmE4OTQyMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NGJkMmY5NWQxZjFjNDdmMDUwNDYwZGU3MTU3MmQ4Y2FkNDZmOGE1Y2VkYWQ3
10
- NjViZWE0NmRkZjEyMGNlZDJhODQzYWQ2NzdjNjY0YWY0YWNmZmUwMTEwODQ5
11
- ODZjYTc3MTMyODQ2YzUzNTk5Mjk0NWQ0MWZkOThmMTFmYjUzMzk=
9
+ ZmRiN2VkMDRhMWNhNWU3Mzg4YTY5YzZlZGE2ZmMyNTU2MGU2NTg2NDMxOTEw
10
+ NjliYTU2ZTBmNzlhOTA0MDc0MzQ1MGQyZDg3MDFhYzRhYjUxY2MxZWRjYTFj
11
+ ZmM2ZDczZDJiNmUxOGRiMzJjNDUzMzNkN2U3NjZmZTJkZDYwMzU=
12
12
  data.tar.gz: !binary |-
13
- OTkwYjM4NmU4ZTMyNDEzODkzNmU2YTEyOGZiMTczOGYyOTYxZDk5MmEzNjYy
14
- OTk3YTY5NmNlNmJhNTM1MWU2NDMzODFmYWQ4MTVhNDE4YzRiZDhkMTAxODRl
15
- NThlNzYwZmI1MzI3ZjhmMmIxNDQ5MjYwMmE0NmY4NzQ1NmQzYjI=
13
+ NjJkYzUxYmNhZGFmMjMxYjA3MmE5YTBkMzliNWNmYmY3MGVlZDY0YzdlYmJl
14
+ MzBlNjc0NTJkN2VkOWRkM2FhYWFjYjBlMGUzZDgyMDg4M2NiNzU5NGYwZmNh
15
+ ZTU4NDI4NTQ0ZmM1YmEwNGQ2ODZhOGM3ZDU0MWI4MTliYmVlOWY=
@@ -0,0 +1,169 @@
1
+ module Caboose
2
+ class PostsController < ApplicationController
3
+
4
+ # GET /posts
5
+ def index
6
+ @posts = Post.where(:published => true).limit(5).order('created_at DESC')
7
+ end
8
+
9
+ # GET /posts/:id
10
+ def detail
11
+ @post = Post.find_by_id(params[:id])
12
+ unless @post.present?
13
+ flash[:notice] = 'The posts post you tried to access does not exist.'
14
+ redirect_to action: :index
15
+ end
16
+ end
17
+
18
+ #=============================================================================
19
+ # Admin actions
20
+ #=============================================================================
21
+
22
+ # GET /admin/posts
23
+ def admin_index
24
+ return if !user_is_allowed('posts', 'view')
25
+
26
+ @gen = Caboose::PageBarGenerator.new(params, {
27
+ 'name' => ''
28
+ },{
29
+ 'model' => 'Caboose::Post',
30
+ 'sort' => 'created_at DESC',
31
+ 'desc' => false,
32
+ 'base_url' => '/admin/posts'
33
+ })
34
+ @posts = @gen.items
35
+ render :layout => 'caboose/admin'
36
+ end
37
+
38
+ # GET /admin/posts/:id/edit
39
+ def admin_edit_general
40
+ return if !user_is_allowed('posts', 'edit')
41
+ @post = Post.find(params[:id])
42
+ render :layout => 'caboose/admin'
43
+ end
44
+
45
+ # GET /admin/posts/:id/content
46
+ def admin_edit_content
47
+ return if !user_is_allowed('posts', 'edit')
48
+ @post = Post.find(params[:id])
49
+ render :layout => 'caboose/admin'
50
+ end
51
+
52
+ # GET /admin/posts/:id/categories
53
+ def admin_edit_categories
54
+ return if !user_is_allowed('posts', 'edit')
55
+ @post = Post.find(params[:id])
56
+ @categories = PostCategory.reorder(:name).all
57
+ render :layout => 'caboose/admin'
58
+ end
59
+
60
+ # POST /admin/posts/:id
61
+ def admin_update
62
+ Caboose.log(params)
63
+ return if !user_is_allowed('posts', 'edit')
64
+
65
+ resp = Caboose::StdClass.new({'attributes' => {}})
66
+ post = Post.find(params[:id])
67
+
68
+ save = true
69
+ params.each do |name, value|
70
+ case name
71
+ when 'category_id'
72
+ post.category_id = value
73
+ when 'title'
74
+ post.title = value
75
+ when 'body'
76
+ post.body = value
77
+ when 'image'
78
+ post.image = value
79
+ when 'published'
80
+ post.published = value.to_i == 1
81
+ when 'created_at'
82
+ post.created_at = DateTime.parse(value)
83
+ end
84
+ end
85
+ resp.success = save && post.save
86
+ if params[:image]
87
+ resp.attributes['image'] = { 'value' => post.image.url(:thumb) }
88
+ end
89
+ render :json => resp
90
+ end
91
+
92
+ # GET /admin/posts/new
93
+ def admin_new
94
+ return if !user_is_allowed('posts', 'new')
95
+ @new_post = Post.new
96
+ render :layout => 'caboose/admin'
97
+ end
98
+
99
+ # POST /admin/posts
100
+ def admin_add
101
+ return if !user_is_allowed('posts', 'add')
102
+
103
+ resp = Caboose::StdClass.new({
104
+ 'error' => nil,
105
+ 'redirect' => nil
106
+ })
107
+
108
+ post = Post.new
109
+ post.title = params[:title]
110
+ post.published = false
111
+
112
+ if post.title == nil || post.title.length == 0
113
+ resp.error = 'A title is required.'
114
+ else
115
+ post.save
116
+ resp.redirect = "/admin/posts/#{post.id}/edit"
117
+ end
118
+
119
+ render :json => resp
120
+ end
121
+
122
+ # PUT /admin/posts/:id/add-to-category
123
+ def admin_add_to_category
124
+ return if !user_is_allowed('posts', 'edit')
125
+
126
+ post_id = params[:id]
127
+ cat_id = params[:post_category_id]
128
+
129
+ if !PostCategoryMembership.exists?(:post_id => post_id, :post_category_id => cat_id)
130
+ PostCategoryMembership.create(:post_id => post_id, :post_category_id => cat_id)
131
+ end
132
+
133
+ render :json => true
134
+ end
135
+
136
+ # PUT /admin/posts/:id/remove-from-category
137
+ def admin_remove_from_category
138
+ return if !user_is_allowed('posts', 'edit')
139
+
140
+ post_id = params[:id]
141
+ cat_id = params[:post_category_id]
142
+
143
+ if PostCategoryMembership.exists?(:post_id => post_id, :post_category_id => cat_id)
144
+ PostCategoryMembership.where(:post_id => post_id, :post_category_id => cat_id).destroy_all
145
+ end
146
+
147
+ render :json => true
148
+ end
149
+
150
+ # GET /admin/posts/:id/delete
151
+ def admin_delete_form
152
+ return if !user_is_allowed('posts', 'delete')
153
+ @post = Post.find(params[:id])
154
+ render :layout => 'caboose/admin'
155
+ end
156
+
157
+ # DELETE /admin/posts/:id
158
+ def admin_delete
159
+ return if !user_is_allowed('posts', 'edit')
160
+
161
+ post_id = params[:id]
162
+ PostCategoryMembership.where(:post_id => post_id).destroy_all
163
+ Post.where(:id => post_id).destroy_all
164
+
165
+ render :json => { 'redirect' => '/admin/posts' }
166
+ end
167
+
168
+ end
169
+ end
@@ -1,8 +1,16 @@
1
1
 
2
2
  class Caboose::Post < ActiveRecord::Base
3
3
  self.table_name = "posts"
4
- belongs_to :category
5
- attr_accessible :id, :category_id, :title, :body, :published
4
+
5
+ has_many :post_category_memberships
6
+ has_many :post_categories, :through => :post_category_memberships
7
+
8
+ attr_accessible :id,
9
+ :category_id,
10
+ :title,
11
+ :body,
12
+ :published,
13
+ :created_at
6
14
  has_attached_file :image,
7
15
  :path => 'posts/:id_:style.:extension',
8
16
  :styles => {
@@ -0,0 +1,10 @@
1
+
2
+ class Caboose::PostCategory < ActiveRecord::Base
3
+ self.table_name = "post_categories"
4
+
5
+ has_many :post_category_memberships
6
+ has_many :posts, :through => :post_category_memberships
7
+
8
+ attr_accessible :id, :name
9
+
10
+ end
@@ -0,0 +1,9 @@
1
+
2
+ class Caboose::PostCategoryMembership < ActiveRecord::Base
3
+ self.table_name = "post_category_memberships"
4
+
5
+ belongs_to :post_category
6
+ belongs_to :post
7
+ attr_accessible :post_id, :post_category_id
8
+
9
+ end
@@ -0,0 +1,2 @@
1
+ <br style='clear: left; line-height: 0;' />
2
+ </div><!-- modal_content2 -->
@@ -0,0 +1,23 @@
1
+ <% content_for :caboose_css do %>
2
+ <% end %>
3
+ <% content_for :caboose_js do %>
4
+ <%= javascript_include_tag "caboose/model/all" %>
5
+ <% end %>
6
+
7
+ <h1>Edit Post</h1>
8
+ <ul id='tabs'>
9
+ <%
10
+ tabs = {
11
+ "/admin/posts/#{@post.id}/edit" => 'General',
12
+ "/admin/posts/#{@post.id}/content" => 'Content',
13
+ "/admin/posts/#{@post.id}/categories" => 'Categories',
14
+ "/admin/posts/#{@post.id}/delete" => 'Delete Post'
15
+ }
16
+
17
+ %>
18
+ <% tabs.each do |href,text| %>
19
+ <li<%= raw request.fullpath == href ? " class='selected'" : '' %>><a href='<%= href %>'><%= raw text %></a></li>
20
+ <% end %>
21
+ <li class='back'><input type='button' value='< Back' onclick="window.location='/admin/posts';" /></li>
22
+ </ul>
23
+ <div id='content2'>
@@ -0,0 +1,30 @@
1
+
2
+ <%= render :partial => 'caboose/posts/admin_header' %>
3
+
4
+ <div id='message'>
5
+ <p class='note error'>Are you sure you want to delete the post? This can't be undone.<br /><br />
6
+ <input type='button' value='Yes' onclick='delete_post(<%= @post.id %>, true);' />
7
+ <input type='button' value='No' onclick="window.location='/admin/posts/<%= @post.id %>/edit';" />
8
+ </p>
9
+ </div>
10
+
11
+ <%= render :partial => 'caboose/posts/admin_footer' %>
12
+ <% content_for :caboose_js do %>
13
+ <%= javascript_include_tag "caboose/model/all" %>
14
+ <script type="text/javascript">
15
+
16
+ function delete_post(post_id, confirm)
17
+ {
18
+ $('#message').html("<p class='loading'>Deleting post...</p>");
19
+ $.ajax({
20
+ url: '/admin/posts/' + post_id,
21
+ type: 'delete',
22
+ success: function(resp) {
23
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
24
+ if (resp.redirect) window.location = resp.redirect
25
+ }
26
+ });
27
+ }
28
+
29
+ </script>
30
+ <% end %>
@@ -0,0 +1,42 @@
1
+
2
+ <%= render :partial => 'caboose/posts/admin_header' %>
3
+
4
+ <style type='text/css'>
5
+ #content input[type=checkbox] { position: relative; }
6
+ </style>
7
+
8
+ <% cat_ids = @post.post_categories.collect { |cat| cat.id } %>
9
+ <% @categories.each do |cat| %>
10
+ <% checked = cat_ids.include?(cat.id) %>
11
+ <p>
12
+ <input type='checkbox' id='cat_<%= cat.id %>' value='<%= cat.id %>' <%= checked ? "checked='true'" : '' %> onchange="check_category(<%= @post.id %>, this.value);" />
13
+ <label for="cat_<%= cat.id %>"><%= cat.name %></label>
14
+ </p>
15
+ <% end %>
16
+
17
+ <%= render :partial => 'caboose/posts/admin_footer' %>
18
+
19
+ <% content_for :caboose_js do %>
20
+ <%= javascript_include_tag "caboose/model/all" %>
21
+ <script type='text/javascript'>
22
+
23
+ function check_category(post_id, cat_id)
24
+ {
25
+ var checked = $('#cat_' + cat_id).is(':checked');
26
+
27
+ $.ajax({
28
+ url: '/admin/posts/' + post_id + '/' + (checked ? 'add-to-category' : 'remove-from-category'),
29
+ data: { post_category_id: cat_id },
30
+ success: function(resp) {}
31
+ });
32
+ }
33
+
34
+ var modal = false;
35
+ $(window).load(function() {
36
+ modal = new CabooseModal(800);
37
+ });
38
+
39
+ </script>
40
+ <%= tinymce_assets %>
41
+ <%= tinymce :caboose, 'width' => '575px', 'height' => '240px' %>
42
+ <% end %>
@@ -0,0 +1,32 @@
1
+
2
+ <%= render :partial => 'caboose/posts/admin_header' %>
3
+
4
+ <p><div id='post_<%= @post.id %>_body' ></div></p>
5
+
6
+ <%= render :partial => 'caboose/posts/admin_footer' %>
7
+
8
+ <% content_for :caboose_js do %>
9
+ <%= javascript_include_tag "caboose/model/all" %>
10
+ <script type='text/javascript'>
11
+
12
+ $(document).ready(function() {
13
+ m = new ModelBinder({
14
+ name: 'Post',
15
+ id: <%= @post.id %>,
16
+ update_url: '/admin/posts/<%= @post.id %>',
17
+ authenticity_token: '<%= form_authenticity_token %>',
18
+ attributes: [
19
+ { name: 'body', nice_name: 'Body', type: 'richtext', value: <%= raw Caboose.json(@post.body) %>, width: 600, height: 400 }
20
+ ]
21
+ });
22
+ });
23
+
24
+ var modal = false;
25
+ $(window).load(function() {
26
+ modal = new CabooseModal(800);
27
+ });
28
+
29
+ </script>
30
+ <%= tinymce_assets %>
31
+ <%= tinymce :caboose, 'width' => '575px', 'height' => '240px' %>
32
+ <% end %>
@@ -0,0 +1,36 @@
1
+
2
+ <%= render :partial => 'caboose/posts/admin_header' %>
3
+
4
+ <p><div id='post_<%= @post.id %>_published' ></div></p>
5
+ <p><div id='post_<%= @post.id %>_title' ></div></p>
6
+ <p><div id='post_<%= @post.id %>_image' ></div></p>
7
+
8
+ <%= render :partial => 'caboose/posts/admin_footer' %>
9
+
10
+ <% content_for :caboose_js do %>
11
+ <%= javascript_include_tag "caboose/model/all" %>
12
+ <script type='text/javascript'>
13
+
14
+ $(document).ready(function() {
15
+ m = new ModelBinder({
16
+ name: 'Post',
17
+ id: <%= @post.id %>,
18
+ update_url: '/admin/posts/<%= @post.id %>',
19
+ authenticity_token: '<%= form_authenticity_token %>',
20
+ attributes: [
21
+ { name: 'published' , nice_name: 'Published' , type: 'checkbox' , value: <%= raw @post.published ? true : false %>, width: 600 },
22
+ { name: 'title' , nice_name: 'Title' , type: 'text' , value: <%= raw Caboose.json(@post.title) %>, width: 600 },
23
+ { name: 'image' , nice_name: 'Image' , type: 'image' , value: <%= raw Caboose.json(@post.image.url(:thumb)) %>, width: 600 }
24
+ ]
25
+ });
26
+ });
27
+
28
+ var modal = false;
29
+ $(window).load(function() {
30
+ modal = new CabooseModal(800);
31
+ });
32
+
33
+ </script>
34
+ <%= tinymce_assets %>
35
+ <%= tinymce :caboose, 'width' => '575px', 'height' => '240px' %>
36
+ <% end %>
@@ -0,0 +1,37 @@
1
+ <h1>Posts</h1>
2
+ <p><input type='button' value='New Post' onclick="window.location='/admin/posts/new';" /></p>
3
+
4
+ <% if @posts && @posts.count > 0 %>
5
+ <table class='data'>
6
+ <tr>
7
+ <%= raw @gen.sortable_table_headings({
8
+ 'id' => 'ID #',
9
+ 'published' => 'Published',
10
+ 'title' => 'Title',
11
+ 'body' => 'Body',
12
+ 'created_at' => 'Date Created'
13
+ })
14
+ %>
15
+ </tr>
16
+ <% @posts.each do |p| %>
17
+ <tr onclick="window.location='/admin/posts/<%= p.id %>/edit';">
18
+ <td><%= raw p.id %></td>
19
+ <td><%= p.published ? "Yes" : "No" %></td>
20
+ <td><%= raw p.title %></td>
21
+ <td><%= raw truncate(p.body, :length => 80) %></td>
22
+ <td><%= p.created_at.strftime("%m/%d/%Y") %></td>
23
+ </tr>
24
+ <% end %>
25
+ </table>
26
+ <p><%= raw @gen.generate %></p>
27
+ <% else %>
28
+ <p>There are no posts right now.</p>
29
+ <% end %>
30
+
31
+ <% content_for :caboose_js do %>
32
+ <script type='text/javascript'>
33
+ $(document).ready(function() {
34
+ var modal = new CabooseModal(800);
35
+ });
36
+ </script>
37
+ <% end %>
@@ -0,0 +1,37 @@
1
+
2
+ <h1>New Post</h1>
3
+
4
+ <p><input type='text' id='title' name='title' placeholder='Title' style="width: 400px;" /></p>
5
+ <div id='message'></div>
6
+ <p><input type='submit' value='Add Post' onclick='add_post();' /></p>
7
+
8
+ <% content_for :caboose_js do %>
9
+ <%= javascript_include_tag "caboose/model/all" %>
10
+ <script type='text/javascript'>
11
+
12
+ var modal = false;
13
+ $(document).ready(function() {
14
+ modal = new CabooseModal(420);
15
+ });
16
+
17
+ function add_post()
18
+ {
19
+ modal.autosize("<p class='loading'>Adding post...</p>");
20
+ $.ajax({
21
+ url: '/admin/posts',
22
+ type: 'post',
23
+ data: {
24
+ authenticity_token: "<%= form_authenticity_token %>",
25
+ title: $('#title').val(),
26
+ },
27
+ success: function(resp) {
28
+ if (resp.error)
29
+ modal.autosize("<p class='note error'>" + resp.error + "</p>");
30
+ if (resp.redirect)
31
+ window.location = resp.redirect
32
+ }
33
+ });
34
+ }
35
+
36
+ </script>
37
+ <% end %>
@@ -0,0 +1,6 @@
1
+
2
+ <div class='post'>
3
+ <h1><%= raw @post[:title] %></h1>
4
+ <figure><img src="<%= @post.image.url(:medium) %>" /></figure>
5
+ <article><%= raw @article[:body] %></article>
6
+ </div>
@@ -0,0 +1,18 @@
1
+
2
+ <div class="posts">
3
+ <% if @posts && @posts.count > 0 %>
4
+ <ul>
5
+ <% @posts.each do |p| %>
6
+ <li>
7
+ <figure><a href="/posts/<%= p.id %>"><img src="<%= p.image.url(:thumb) %>" /></a></figure>
8
+ <h5><strong><%= raw a[:title] %></strong></h5>
9
+ <p class="h-space-mvt"><%= a[:created_at].strftime("%m/%d/%Y") %></p>
10
+ <p class="h-space-mbt"><%= truncate(strip_tags(a[:body]), :length => 175) %></p>
11
+ <a class="m-btn-red h-space-mts" href="/news/<%= a.id %>">Read More</a>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <% else %>
16
+ <p>There are no posts right now.</p>
17
+ <% end %>
18
+ </div>
@@ -64,6 +64,23 @@ Caboose::Engine.routes.draw do
64
64
  post "admin/pages" => "pages#admin_create"
65
65
  delete "admin/pages/:id" => "pages#admin_delete"
66
66
 
67
+ get "posts" => "posts#index"
68
+ get "posts/:id" => "posts#detail"
69
+ get "admin/posts/category-options" => "posts#admin_category_options"
70
+ get "admin/posts/new" => "posts#admin_new"
71
+ get "admin/posts/:id/delete" => "posts#admin_delete_form"
72
+ get "admin/posts/:id/edit" => "posts#admin_edit_general"
73
+ get "admin/posts/:id/content" => "posts#admin_edit_content"
74
+ get "admin/posts/:id/categories" => "posts#admin_edit_categories"
75
+ get "admin/posts/:id/add-to-category" => "posts#admin_add_to_category"
76
+ get "admin/posts/:id/remove-from-category" => "posts#admin_remove_from_category"
77
+ get "admin/posts/:id/delete" => "posts#admin_delete_form"
78
+ put "admin/posts/:id" => "posts#admin_update"
79
+ post "admin/posts/:id" => "posts#admin_update"
80
+ get "admin/posts" => "posts#admin_index"
81
+ post "admin/posts" => "posts#admin_add"
82
+ delete "admin/posts/:id" => "posts#admin_delete"
83
+
67
84
  match '*path' => 'pages#show'
68
85
  root :to => 'pages#show'
69
86
 
@@ -1,3 +1,3 @@
1
1
  module Caboose
2
- VERSION = '0.2.70'
2
+ VERSION = '0.2.71'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caboose-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.70
4
+ version: 0.2.71
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Barry
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-15 00:00:00.000000000 Z
11
+ date: 2013-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -181,6 +181,7 @@ files:
181
181
  - app/controllers/caboose/logout_controller.rb
182
182
  - app/controllers/caboose/pages_controller.rb
183
183
  - app/controllers/caboose/permissions_controller.rb
184
+ - app/controllers/caboose/posts_controller.rb
184
185
  - app/controllers/caboose/register_controller.rb
185
186
  - app/controllers/caboose/roles_controller.rb
186
187
  - app/controllers/caboose/settings_controller.rb
@@ -202,6 +203,8 @@ files:
202
203
  - app/models/caboose/pager.rb
203
204
  - app/models/caboose/permission.rb
204
205
  - app/models/caboose/post.rb
206
+ - app/models/caboose/post_category.rb
207
+ - app/models/caboose/post_category_membership.rb
205
208
  - app/models/caboose/role.rb
206
209
  - app/models/caboose/setting.rb
207
210
  - app/models/caboose/std_class.rb
@@ -229,6 +232,16 @@ files:
229
232
  - app/views/caboose/permissions/edit.html.erb
230
233
  - app/views/caboose/permissions/index.html.erb
231
234
  - app/views/caboose/permissions/new.html.erb
235
+ - app/views/caboose/posts/_admin_footer.html.erb
236
+ - app/views/caboose/posts/_admin_header.html.erb
237
+ - app/views/caboose/posts/admin_delete_form.html.erb
238
+ - app/views/caboose/posts/admin_edit_categories.html.erb
239
+ - app/views/caboose/posts/admin_edit_content.html.erb
240
+ - app/views/caboose/posts/admin_edit_general.html.erb
241
+ - app/views/caboose/posts/admin_index.html.erb
242
+ - app/views/caboose/posts/admin_new.html.erb
243
+ - app/views/caboose/posts/detail.html.erb
244
+ - app/views/caboose/posts/index.html.erb
232
245
  - app/views/caboose/register/index.html.erb
233
246
  - app/views/caboose/roles/edit.html.erb
234
247
  - app/views/caboose/roles/index.html.erb