monologue 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +73 -0
- data/Rakefile +32 -0
- data/app/assets/javascripts/monologue/admin/application.js +13 -0
- data/app/assets/javascripts/monologue/admin/tinymce-config.js +21 -0
- data/app/assets/javascripts/monologue/blog/application.js +9 -0
- data/app/assets/stylesheets/monologue/admin/application.css +10 -0
- data/app/assets/stylesheets/monologue/blog/application.css +13 -0
- data/app/assets/stylesheets/monologue/blog/custom.css +1 -0
- data/app/assets/stylesheets/monologue/blog/fonts.css +1 -0
- data/app/assets/stylesheets/monologue/blog/monologue.css +37 -0
- data/app/assets/stylesheets/monologue/blog/skeleton/base.css +343 -0
- data/app/assets/stylesheets/monologue/blog/skeleton/layout.css +58 -0
- data/app/assets/stylesheets/monologue/blog/skeleton/skeleton.css +242 -0
- data/app/controllers/monologue/admin/base_controller.rb +12 -0
- data/app/controllers/monologue/admin/posts_controller.rb +54 -0
- data/app/controllers/monologue/admin/sessions_controller.rb +22 -0
- data/app/controllers/monologue/application_controller.rb +22 -0
- data/app/controllers/monologue/posts_controller.rb +25 -0
- data/app/form_builders/monologue_admin_form_builder.rb +61 -0
- data/app/helpers/monologue/admin/admin_helper.rb +4 -0
- data/app/helpers/monologue/application_helper.rb +8 -0
- data/app/helpers/monologue/posts_helper.rb +4 -0
- data/app/helpers/monologue/sessions_helper.rb +6 -0
- data/app/models/monologue/post.rb +40 -0
- data/app/models/monologue/posts_revision.rb +34 -0
- data/app/models/monologue/user.rb +6 -0
- data/app/sweepers/monologue/posts_sweeper.rb +28 -0
- data/app/views/layouts/monologue/_google_analytics.html.erb +15 -0
- data/app/views/layouts/monologue/admin.html.erb +21 -0
- data/app/views/layouts/monologue/admin/_nav_bar.html.erb +24 -0
- data/app/views/layouts/monologue/application.html.erb +60 -0
- data/app/views/monologue/admin/posts/_form.html.erb +16 -0
- data/app/views/monologue/admin/posts/edit.html.erb +4 -0
- data/app/views/monologue/admin/posts/index.html.erb +20 -0
- data/app/views/monologue/admin/posts/new.html.erb +4 -0
- data/app/views/monologue/admin/sessions/new.html.erb +13 -0
- data/app/views/monologue/posts/404.html.erb +9 -0
- data/app/views/monologue/posts/_pagination.html.erb +9 -0
- data/app/views/monologue/posts/_social_sharing.html.erb +42 -0
- data/app/views/monologue/posts/feed.rss.builder +19 -0
- data/app/views/monologue/posts/index.html.erb +18 -0
- data/app/views/monologue/posts/show.html.erb +38 -0
- data/config/locales/en.yml +106 -0
- data/config/locales/fr.yml +106 -0
- data/config/routes.rb +15 -0
- data/db/migrate/20120114001001_create_monologue_users.rb +11 -0
- data/db/migrate/20120120193858_create_monologue_posts_revisions.rb +18 -0
- data/db/migrate/20120120193907_create_monologue_posts.rb +10 -0
- data/db/seeds.rb +1 -0
- data/lib/monologue.rb +17 -0
- data/lib/monologue/engine.rb +11 -0
- data/lib/monologue/version.rb +3 -0
- data/lib/tasks/monologue_tasks.rake +4 -0
- data/vendor/assets/images/monologue/bootstrap/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/monologue/bootstrap/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/monologue/bootstrap/bootstrap-datepicker-fr.js +9 -0
- data/vendor/assets/javascripts/monologue/bootstrap/bootstrap-datepicker.js +338 -0
- data/vendor/assets/javascripts/monologue/bootstrap/bootstrap.min.js +1 -0
- data/vendor/assets/stylesheets/monologue/bootstrap/bootstrap-datepicker.css +130 -0
- data/vendor/assets/stylesheets/monologue/bootstrap/bootstrap-responsive.min.css +3 -0
- data/vendor/assets/stylesheets/monologue/bootstrap/bootstrap.min.css +610 -0
- metadata +285 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
/*
|
2
|
+
* Skeleton V1.1
|
3
|
+
* Copyright 2011, Dave Gamache
|
4
|
+
* www.getskeleton.com
|
5
|
+
* Free to use under the MIT license.
|
6
|
+
* http://www.opensource.org/licenses/mit-license.php
|
7
|
+
* 8/17/2011
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* Table of Content
|
11
|
+
==================================================
|
12
|
+
#Site Styles
|
13
|
+
#Page Styles
|
14
|
+
#Media Queries
|
15
|
+
#Font-Face */
|
16
|
+
|
17
|
+
/* #Site Styles
|
18
|
+
================================================== */
|
19
|
+
|
20
|
+
/* #Page Styles
|
21
|
+
================================================== */
|
22
|
+
|
23
|
+
/* #Media Queries
|
24
|
+
================================================== */
|
25
|
+
|
26
|
+
/* Smaller than standard 960 (devices and browsers) */
|
27
|
+
@media only screen and (max-width: 959px) {}
|
28
|
+
|
29
|
+
/* Tablet Portrait size to standard 960 (devices and browsers) */
|
30
|
+
@media only screen and (min-width: 768px) and (max-width: 959px) {}
|
31
|
+
|
32
|
+
/* All Mobile Sizes (devices and browser) */
|
33
|
+
@media only screen and (max-width: 767px) {}
|
34
|
+
|
35
|
+
/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
|
36
|
+
@media only screen and (min-width: 480px) and (max-width: 767px) {}
|
37
|
+
|
38
|
+
/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
|
39
|
+
@media only screen and (max-width: 479px) {}
|
40
|
+
|
41
|
+
|
42
|
+
/* #Font-Face
|
43
|
+
================================================== */
|
44
|
+
/* This is the proper syntax for an @font-face file
|
45
|
+
Just create a "fonts" folder at the root,
|
46
|
+
copy your FontName into code below and remove
|
47
|
+
comment brackets */
|
48
|
+
|
49
|
+
/* @font-face {
|
50
|
+
font-family: 'FontName';
|
51
|
+
src: url('../fonts/FontName.eot');
|
52
|
+
src: url('../fonts/FontName.eot?iefix') format('eot'),
|
53
|
+
url('../fonts/FontName.woff') format('woff'),
|
54
|
+
url('../fonts/FontName.ttf') format('truetype'),
|
55
|
+
url('../fonts/FontName.svg#webfontZam02nTh') format('svg');
|
56
|
+
font-weight: normal;
|
57
|
+
font-style: normal; }
|
58
|
+
*/
|
@@ -0,0 +1,242 @@
|
|
1
|
+
/*
|
2
|
+
* Skeleton V1.1
|
3
|
+
* Copyright 2011, Dave Gamache
|
4
|
+
* www.getskeleton.com
|
5
|
+
* Free to use under the MIT license.
|
6
|
+
* http://www.opensource.org/licenses/mit-license.php
|
7
|
+
* 8/17/2011
|
8
|
+
*/
|
9
|
+
|
10
|
+
|
11
|
+
/* Table of Contents
|
12
|
+
==================================================
|
13
|
+
#Base 960 Grid
|
14
|
+
#Tablet (Portrait)
|
15
|
+
#Mobile (Portrait)
|
16
|
+
#Mobile (Landscape)
|
17
|
+
#Clearing */
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
/* #Base 960 Grid
|
22
|
+
================================================== */
|
23
|
+
|
24
|
+
.container { position: relative; width: 960px; margin: 0 auto; padding: 0; }
|
25
|
+
.container .column,
|
26
|
+
.container .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; }
|
27
|
+
.row { margin-bottom: 20px; }
|
28
|
+
|
29
|
+
/* Nested Column Classes */
|
30
|
+
.column.alpha, .columns.alpha { margin-left: 0; }
|
31
|
+
.column.omega, .columns.omega { margin-right: 0; }
|
32
|
+
|
33
|
+
/* Base Grid */
|
34
|
+
.container .one.column,
|
35
|
+
.container .one.columns { width: 40px; }
|
36
|
+
.container .two.columns { width: 100px; }
|
37
|
+
.container .three.columns { width: 160px; }
|
38
|
+
.container .four.columns { width: 220px; }
|
39
|
+
.container .five.columns { width: 280px; }
|
40
|
+
.container .six.columns { width: 340px; }
|
41
|
+
.container .seven.columns { width: 400px; }
|
42
|
+
.container .eight.columns { width: 460px; }
|
43
|
+
.container .nine.columns { width: 520px; }
|
44
|
+
.container .ten.columns { width: 580px; }
|
45
|
+
.container .eleven.columns { width: 640px; }
|
46
|
+
.container .twelve.columns { width: 700px; }
|
47
|
+
.container .thirteen.columns { width: 760px; }
|
48
|
+
.container .fourteen.columns { width: 820px; }
|
49
|
+
.container .fifteen.columns { width: 880px; }
|
50
|
+
.container .sixteen.columns { width: 940px; }
|
51
|
+
|
52
|
+
.container .one-third.column { width: 300px; }
|
53
|
+
.container .two-thirds.column { width: 620px; }
|
54
|
+
|
55
|
+
/* Offsets */
|
56
|
+
.container .offset-by-one { padding-left: 60px; }
|
57
|
+
.container .offset-by-two { padding-left: 120px; }
|
58
|
+
.container .offset-by-three { padding-left: 180px; }
|
59
|
+
.container .offset-by-four { padding-left: 240px; }
|
60
|
+
.container .offset-by-five { padding-left: 300px; }
|
61
|
+
.container .offset-by-six { padding-left: 360px; }
|
62
|
+
.container .offset-by-seven { padding-left: 420px; }
|
63
|
+
.container .offset-by-eight { padding-left: 480px; }
|
64
|
+
.container .offset-by-nine { padding-left: 540px; }
|
65
|
+
.container .offset-by-ten { padding-left: 600px; }
|
66
|
+
.container .offset-by-eleven { padding-left: 660px; }
|
67
|
+
.container .offset-by-twelve { padding-left: 720px; }
|
68
|
+
.container .offset-by-thirteen { padding-left: 780px; }
|
69
|
+
.container .offset-by-fourteen { padding-left: 840px; }
|
70
|
+
.container .offset-by-fifteen { padding-left: 900px; }
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
/* #Tablet (Portrait)
|
75
|
+
================================================== */
|
76
|
+
|
77
|
+
/* Note: Design for a width of 768px */
|
78
|
+
|
79
|
+
@media only screen and (min-width: 768px) and (max-width: 959px) {
|
80
|
+
.container { width: 768px; }
|
81
|
+
.container .column,
|
82
|
+
.container .columns { margin-left: 10px; margin-right: 10px; }
|
83
|
+
.column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }
|
84
|
+
.column.omega, .columns.omega { margin-right: 0; margin-left: 10px; }
|
85
|
+
.alpha.omega { margin-left: 0; margin-right: 0; }
|
86
|
+
|
87
|
+
.container .one.column,
|
88
|
+
.container .one.columns { width: 28px; }
|
89
|
+
.container .two.columns { width: 76px; }
|
90
|
+
.container .three.columns { width: 124px; }
|
91
|
+
.container .four.columns { width: 172px; }
|
92
|
+
.container .five.columns { width: 220px; }
|
93
|
+
.container .six.columns { width: 268px; }
|
94
|
+
.container .seven.columns { width: 316px; }
|
95
|
+
.container .eight.columns { width: 364px; }
|
96
|
+
.container .nine.columns { width: 412px; }
|
97
|
+
.container .ten.columns { width: 460px; }
|
98
|
+
.container .eleven.columns { width: 508px; }
|
99
|
+
.container .twelve.columns { width: 556px; }
|
100
|
+
.container .thirteen.columns { width: 604px; }
|
101
|
+
.container .fourteen.columns { width: 652px; }
|
102
|
+
.container .fifteen.columns { width: 700px; }
|
103
|
+
.container .sixteen.columns { width: 748px; }
|
104
|
+
|
105
|
+
.container .one-third.column { width: 236px; }
|
106
|
+
.container .two-thirds.column { width: 492px; }
|
107
|
+
|
108
|
+
/* Offsets */
|
109
|
+
.container .offset-by-one { padding-left: 48px; }
|
110
|
+
.container .offset-by-two { padding-left: 96px; }
|
111
|
+
.container .offset-by-three { padding-left: 144px; }
|
112
|
+
.container .offset-by-four { padding-left: 192px; }
|
113
|
+
.container .offset-by-five { padding-left: 240px; }
|
114
|
+
.container .offset-by-six { padding-left: 288px; }
|
115
|
+
.container .offset-by-seven { padding-left: 336px; }
|
116
|
+
.container .offset-by-eight { padding-left: 384px; }
|
117
|
+
.container .offset-by-nine { padding-left: 432px; }
|
118
|
+
.container .offset-by-ten { padding-left: 480px; }
|
119
|
+
.container .offset-by-eleven { padding-left: 528px; }
|
120
|
+
.container .offset-by-twelve { padding-left: 576px; }
|
121
|
+
.container .offset-by-thirteen { padding-left: 624px; }
|
122
|
+
.container .offset-by-fourteen { padding-left: 672px; }
|
123
|
+
.container .offset-by-fifteen { padding-left: 720px; }
|
124
|
+
}
|
125
|
+
|
126
|
+
|
127
|
+
/* #Mobile (Portrait)
|
128
|
+
================================================== */
|
129
|
+
|
130
|
+
/* Note: Design for a width of 320px */
|
131
|
+
|
132
|
+
@media only screen and (max-width: 767px) {
|
133
|
+
.container { width: 300px; }
|
134
|
+
.container .columns,
|
135
|
+
.container .column { margin: 0; }
|
136
|
+
|
137
|
+
.container .one.column,
|
138
|
+
.container .one.columns,
|
139
|
+
.container .two.columns,
|
140
|
+
.container .three.columns,
|
141
|
+
.container .four.columns,
|
142
|
+
.container .five.columns,
|
143
|
+
.container .six.columns,
|
144
|
+
.container .seven.columns,
|
145
|
+
.container .eight.columns,
|
146
|
+
.container .nine.columns,
|
147
|
+
.container .ten.columns,
|
148
|
+
.container .eleven.columns,
|
149
|
+
.container .twelve.columns,
|
150
|
+
.container .thirteen.columns,
|
151
|
+
.container .fourteen.columns,
|
152
|
+
.container .fifteen.columns,
|
153
|
+
.container .sixteen.columns,
|
154
|
+
.container .one-third.column,
|
155
|
+
.container .two-thirds.column { width: 300px; }
|
156
|
+
|
157
|
+
/* Offsets */
|
158
|
+
.container .offset-by-one,
|
159
|
+
.container .offset-by-two,
|
160
|
+
.container .offset-by-three,
|
161
|
+
.container .offset-by-four,
|
162
|
+
.container .offset-by-five,
|
163
|
+
.container .offset-by-six,
|
164
|
+
.container .offset-by-seven,
|
165
|
+
.container .offset-by-eight,
|
166
|
+
.container .offset-by-nine,
|
167
|
+
.container .offset-by-ten,
|
168
|
+
.container .offset-by-eleven,
|
169
|
+
.container .offset-by-twelve,
|
170
|
+
.container .offset-by-thirteen,
|
171
|
+
.container .offset-by-fourteen,
|
172
|
+
.container .offset-by-fifteen { padding-left: 0; }
|
173
|
+
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
/* #Mobile (Landscape)
|
178
|
+
================================================== */
|
179
|
+
|
180
|
+
/* Note: Design for a width of 480px */
|
181
|
+
|
182
|
+
@media only screen and (min-width: 480px) and (max-width: 767px) {
|
183
|
+
.container { width: 420px; }
|
184
|
+
.container .columns,
|
185
|
+
.container .column { margin: 0; }
|
186
|
+
|
187
|
+
.container .one.column,
|
188
|
+
.container .one.columns,
|
189
|
+
.container .two.columns,
|
190
|
+
.container .three.columns,
|
191
|
+
.container .four.columns,
|
192
|
+
.container .five.columns,
|
193
|
+
.container .six.columns,
|
194
|
+
.container .seven.columns,
|
195
|
+
.container .eight.columns,
|
196
|
+
.container .nine.columns,
|
197
|
+
.container .ten.columns,
|
198
|
+
.container .eleven.columns,
|
199
|
+
.container .twelve.columns,
|
200
|
+
.container .thirteen.columns,
|
201
|
+
.container .fourteen.columns,
|
202
|
+
.container .fifteen.columns,
|
203
|
+
.container .sixteen.columns,
|
204
|
+
.container .one-third.column,
|
205
|
+
.container .two-thirds.column { width: 420px; }
|
206
|
+
}
|
207
|
+
|
208
|
+
|
209
|
+
/* #Clearing
|
210
|
+
================================================== */
|
211
|
+
|
212
|
+
/* Self Clearing Goodness */
|
213
|
+
.container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
|
214
|
+
|
215
|
+
/* Use clearfix class on parent to clear nested columns,
|
216
|
+
or wrap each row of columns in a <div class="row"> */
|
217
|
+
.clearfix:before,
|
218
|
+
.clearfix:after,
|
219
|
+
.row:before,
|
220
|
+
.row:after {
|
221
|
+
content: '\0020';
|
222
|
+
display: block;
|
223
|
+
overflow: hidden;
|
224
|
+
visibility: hidden;
|
225
|
+
width: 0;
|
226
|
+
height: 0; }
|
227
|
+
.row:after,
|
228
|
+
.clearfix:after {
|
229
|
+
clear: both; }
|
230
|
+
.row,
|
231
|
+
.clearfix {
|
232
|
+
zoom: 1; }
|
233
|
+
|
234
|
+
/* You can also use a <br class="clear" /> to clear columns */
|
235
|
+
.clear {
|
236
|
+
clear: both;
|
237
|
+
display: block;
|
238
|
+
overflow: hidden;
|
239
|
+
visibility: hidden;
|
240
|
+
width: 0;
|
241
|
+
height: 0;
|
242
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Monologue::Admin::BaseController < Monologue::ApplicationController
|
2
|
+
before_filter :authenticate_user!
|
3
|
+
force_ssl if Monologue.admin_force_ssl # TODO: find a way to test that with capybara
|
4
|
+
|
5
|
+
layout "layouts/monologue/admin"
|
6
|
+
|
7
|
+
def authenticate_user!
|
8
|
+
if current_user.nil?
|
9
|
+
redirect_to admin_login_url, :alert => "You must first log in to access admin section."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Monologue::Admin::PostsController < Monologue::Admin::BaseController
|
2
|
+
respond_to :html
|
3
|
+
cache_sweeper Monologue::PostsSweeper, :only => [:create, :update, :destroy]
|
4
|
+
|
5
|
+
def index
|
6
|
+
@posts = Monologue::Post.default
|
7
|
+
end
|
8
|
+
|
9
|
+
def new
|
10
|
+
@post = Monologue::Post.new
|
11
|
+
@revision = @post.posts_revisions.build
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
params[:post][:posts_revisions_attributes] = {}
|
16
|
+
params[:post][:posts_revisions_attributes][0] = params[:post][:posts_revision]
|
17
|
+
params[:post].delete("posts_revision")
|
18
|
+
@post = Monologue::Post.new(params[:post])
|
19
|
+
@revision = @post.posts_revisions.first
|
20
|
+
@revision.user_id = current_user.id
|
21
|
+
|
22
|
+
if @post.save
|
23
|
+
redirect_to edit_admin_post_path(@post), :notice => 'Monologue created'
|
24
|
+
else
|
25
|
+
render :action => "new"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit
|
30
|
+
@post = Monologue::Post.includes(:posts_revisions).find(params[:id])
|
31
|
+
@revision = @post.posts_revisions.last
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
@post = Monologue::Post.includes(:posts_revisions).find(params[:id])
|
36
|
+
@post.published = params[:post][:published]
|
37
|
+
@revision = @post.posts_revisions.build(params[:post][:posts_revision])
|
38
|
+
@revision.user_id = current_user.id
|
39
|
+
if @post.save
|
40
|
+
redirect_to edit_admin_post_path(@post), :notice => 'Monologue saved'
|
41
|
+
else
|
42
|
+
render :edit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
post = Monologue::Post.find(params[:id])
|
48
|
+
if post.destroy
|
49
|
+
redirect_to admin_posts_path, :notice => "Monologue removed"
|
50
|
+
else
|
51
|
+
redirect_to admin_posts_path, :alert => "Failed to remove monologue!"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Monologue::Admin::SessionsController < Monologue::Admin::BaseController
|
2
|
+
skip_before_filter :authenticate_user!
|
3
|
+
|
4
|
+
def new
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
user = Monologue::User.find_by_email(params[:email])
|
9
|
+
if user && user.authenticate(params[:password])
|
10
|
+
session[:user_id] = user.id
|
11
|
+
redirect_to admin_url, :notice => t("monologue.admin.sessions.messages.logged_in")
|
12
|
+
else
|
13
|
+
flash.now.alert = t("monologue.admin.sessions.messages.invalid")
|
14
|
+
render "new"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
session[:user_id] = nil
|
20
|
+
redirect_to admin_url, :notice => t("monologue.admin.sessions.messages.logged_out")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Monologue::ApplicationController < ApplicationController
|
2
|
+
|
3
|
+
def not_found
|
4
|
+
# fallback to the default 404.html page from main_app.
|
5
|
+
file = Rails.root.join('public', '404.html')
|
6
|
+
if file.exist?
|
7
|
+
render :file => file.cleanpath.to_s.gsub(%r{#{file.extname}$}, ''),
|
8
|
+
:layout => false, :status => 404, :formats => [:html]
|
9
|
+
else
|
10
|
+
render :action => "404", :status => 404, :formats => [:html]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def current_user
|
18
|
+
@current_user ||= Monologue::User.find(session[:user_id]) if session[:user_id]
|
19
|
+
end
|
20
|
+
|
21
|
+
helper_method :current_user
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Monologue::PostsController < Monologue::ApplicationController
|
2
|
+
caches_page :index, :show, :feed , :if => Proc.new { current_user.nil? }
|
3
|
+
|
4
|
+
def index
|
5
|
+
@page = params[:page].nil? ? 1 : params[:page]
|
6
|
+
@posts = Monologue::Post.published.page(@page)
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
unless current_user
|
11
|
+
post = Monologue::Post.published.where("monologue_posts_revisions.url = :url", {:url => root_path + params[:post_url]}).first
|
12
|
+
else
|
13
|
+
post = Monologue::Post.default.where("monologue_posts_revisions.url = :url", {:url => root_path + params[:post_url]}).first
|
14
|
+
end
|
15
|
+
if post.nil?
|
16
|
+
not_found
|
17
|
+
return
|
18
|
+
end
|
19
|
+
@revision = post.posts_revisions.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def feed
|
23
|
+
@posts = Monologue::Post.published.limit(25)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class MonologueAdminFormBuilder < ActionView::Helpers::FormBuilder
|
2
|
+
delegate :content_tag, :tag, :to => :@template
|
3
|
+
|
4
|
+
%w[text_field text_area password_field collection_select select file_field].each do |method_name|
|
5
|
+
define_method(method_name) do |name, *args|
|
6
|
+
content_tag :div, :class => "field" do
|
7
|
+
field_label(name, *args) + super(name, *args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_box(name, *args)
|
13
|
+
options = args.extract_options!
|
14
|
+
required = object.class.validators_on(name).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator }
|
15
|
+
content_tag :label, :class => (required ? "required checkbox inline" : "checkbox inline") do
|
16
|
+
super + (options[:label] || name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def collection_check_boxes(attribute, records, record_id, record_name)
|
21
|
+
content_tag :div, :class => "field" do
|
22
|
+
@template.hidden_field_tag("#{object_name}[#{attribute}][]") +
|
23
|
+
records.map do |record|
|
24
|
+
element_id = "#{object_name}_#{attribute}_#{record.send(record_id)}"
|
25
|
+
checkbox = @template.check_box_tag("#{object_name}[#{attribute}][]", record.send(record_id), object.send(attribute).include?(record.send(record_id)), :id => element_id)
|
26
|
+
checkbox + " " + @template.label_tag(element_id, record.send(record_name))
|
27
|
+
end.join(tag(:br)).html_safe
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def submit(*args)
|
32
|
+
content_tag :div, :class => "actions" do
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def error_messages
|
38
|
+
if object.errors.full_messages.any?
|
39
|
+
content_tag(:div, :class => "alert alert-error error_messages") do
|
40
|
+
content_tag(:strong, "Invalid Fields") +
|
41
|
+
content_tag(:ul) do
|
42
|
+
object.errors.messages.map do |msg|
|
43
|
+
content_tag(:li, msg[1][0])
|
44
|
+
end.join.html_safe
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def field_label(name, *args)
|
53
|
+
options = args.extract_options!
|
54
|
+
required = object.class.validators_on(name).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator }
|
55
|
+
label(name, options[:label], :class => ("required" if required))
|
56
|
+
end
|
57
|
+
|
58
|
+
def objectify_options(options)
|
59
|
+
super.except(:label)
|
60
|
+
end
|
61
|
+
end
|