effective_pages 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7a8cb961d2c8e48119552c15b79ba0042e5ed3d
4
- data.tar.gz: d0572a2cc302859052aaabb7d61f9a0f0f3702a0
3
+ metadata.gz: ddac8c5966ed3e1d03290f2faca0b85932cc36a3
4
+ data.tar.gz: 5342d8e6be2b9269a0c419ef1c4ab5420f08d4ca
5
5
  SHA512:
6
- metadata.gz: 711bb11642aa463828cb2bd0231bb284bb8366ce63601fbf73fae30ae60d13ca3d29b1dbb09af1adb9c44a17ab347ee38d249439d306aa17844f530633a944df
7
- data.tar.gz: 459199b5df27a960d9ba4e5e00c5d3b156dad57bd34eb27864eb9fae8aedffa78b68299a4e6e7bee7aab95923c71db842d173148a470609a82198d00552c043a
6
+ metadata.gz: b029523505a15f7a50a3865aac1d40ec63fa334d4f7affb01aaeeff1e21e1afa3a85428bb0b5cecf475daaa65a84239ed23bac450bb01a54b42479a43f4e02ae
7
+ data.tar.gz: 582121876ff42513540c06689f48489b7df190858bac4c32d72179ca7a2a8e51c200b426a860218482ce36ed9387de4299e328acb469b202dd28e0b768125223
data/README.md CHANGED
@@ -1,30 +1,402 @@
1
1
  # Effective Pages
2
2
 
3
- Rise of the effective page!!
3
+ Content pages, bootstrap3 menu builder and page-specific header tag helpers for your Rails app.
4
4
 
5
- This is a work in progress gem that's ALMOST ready for release
5
+ Create content pages ontop of one or more templates -- just regular Rails views -- that you define and control.
6
6
 
7
- TODO: Make a README!
7
+ Edit menus with a WYSIWYG drag-and-drop bootstrap3-strict menu builder.
8
8
 
9
- effective_pages.page_url
10
- effective_pages.page_path
9
+ Use this gem to create a fully-functional CMS that provides full or restricted editing for your end users.
11
10
 
11
+ Built ontop of effective_regions.
12
12
 
13
- No javascript to add for Pages
14
13
 
15
- Put
14
+ ## Getting Started
16
15
 
17
- = effective_page_header_tags
16
+ Please first install the [effective_regions](https://github.com/code-and-effect/effective_regions) and [effective_datatables](https://github.com/code-and-effect/effective_datatables) gems.
18
17
 
19
- in your header, so the page title and meta-description can be saved
18
+ Please download and install [Twitter Bootstrap3](http://getbootstrap.com)
20
19
 
20
+ Add to your Gemfile:
21
21
 
22
- If you want to use regular maxDepth == 2 bootstrap3 menus, no CSS to add
22
+ ```ruby
23
+ gem 'effective_pages'
24
+ ```
23
25
 
24
- if you want deep menus, you can add
26
+ Run the bundle command to install it:
25
27
 
26
- @import 'effective_pages'; for unlimitted depth bootstrap3 menus addon
28
+ ```console
29
+ bundle install
30
+ ```
27
31
 
28
- then call = render_menu('main menu', :maxdepth => 3)
32
+ Then run the generator:
33
+
34
+ ```ruby
35
+ rails generate effective_pages:install
36
+ ```
37
+
38
+ The generator will install an initializer which describes all configuration options and creates a database migration.
39
+
40
+ If you want to tweak the table name (to use something other than the default 'pages', 'menus', 'menu_items'), manually adjust both the configuration file and the migration now.
41
+
42
+ Then migrate the database:
43
+
44
+ ```ruby
45
+ rake db:migrate
46
+ ```
47
+
48
+ There are no required javascript or stylesheet includes.
49
+
50
+
51
+ ### Post Installation
52
+
53
+ Once the above Getting Started tasks have been completed, there are still a few small things that need to be initialized and configured.
54
+
55
+ The documentation for these post-installation tasks is split up into the following Pages and Menus sections.
56
+
57
+
58
+ ## Pages
59
+
60
+ To create your first content page, visit `/admin/pages` and click `New Page`.
61
+
62
+ This first page will be created with the provided `example` page view template and allow you to immediately jump into the effective_regions editor when you click `Save and Edit Content`.
63
+
64
+ This page will be available on your website at a route matching the slugified title.
65
+
66
+ ### View Template and Layout
67
+
68
+ Every Effective::Page is rendered by a regular Rails view file and layout. The same as any standard Rails #show action.
69
+
70
+ When creating a Page, if the `app/views/layouts/` directory contains more than one layout file, you will be able to choose which layout to use when displaying this Page. If your Rails app contains only the default `application` layout then this layout will be used.
71
+
72
+ As well, when creating your Effective::Page object, if the `app/views/effective/pages/` directory contains more than one view file, you will be able to choose which view is used to display this Page.
73
+
74
+ When this gem's installation generator is run, the `app/views/effective/pages/example.html.haml` page view template is created. To add additional page view templates, just create more views in this directory.
75
+
76
+ An example of a two-column layout I like to create is as follows:
77
+
78
+ ```haml
79
+ %h1
80
+ = simple_effective_region page, :header do
81
+ = page.title
82
+
83
+ .row
84
+ .col-sm-6
85
+ = effective_region page, :left do
86
+ %p this is default left column content
87
+ .col-sm-6
88
+ = effective_region page, :right do
89
+ %p this is default right column content
90
+ ```
91
+
92
+ You can add anything to these page views. The views are not required to contain any effective_regions, but then they wouldn't be user-editable.
93
+
94
+ ### Routes
95
+
96
+ All Effective::Page pages are immediately available to your application at a url matching the slugified title.
97
+
98
+ This gem's page routes are evaluated last, after all your existing routes. This may cause an issue if you create an Effective::Page titled `Events` but you already have a route matching `/events` such as `resources :events`. You can edit the Effective::Page object and set the slug to a value that does not conflict.
99
+
100
+ To find the path for an Effective::Page object:
101
+
102
+ ```ruby
103
+ page = Effective::Page.find_by_title('My Page')
104
+
105
+ effective_pages.page_path(page)
106
+ effective_pages.page_url(page)
107
+ ```
108
+
109
+ If you would like to use an Effective::Page for your home/root page, add the following to your routes.rb:
110
+
111
+ ```ruby
112
+ root :to => 'Effective::Pages#show', :id => 'home'
113
+ ```
114
+
115
+ and make sure a page with slug 'home' exists.
116
+
117
+
118
+ ### Header Tags
119
+
120
+ Your layout needs to be configured to set the appropriate html `<title>` and `<meta>` tags.
121
+
122
+ In your application layout and any additional layouts files, add the following to the `<head>` section:
123
+
124
+ ```ruby
125
+ = effective_pages_header_tags
126
+ ```
127
+
128
+ This helper inserts a `<title>...</title>` html tag based on the `@page_title` instance variable, which you can set anywhere on your non-effective controllers, and whose value is set to the `@page.title` value when displaying an `Effective::Page`.
129
+
130
+ This helper also inserts a `<meta name='description' value='...' />` html tag based on the Effective::Page's meta description value. This tag provides the content that search engines use to display their search results.
131
+
132
+ This helper is entirely optional and in no way required for effective_pages to work.
133
+
134
+ ### Body Tag Classes
135
+
136
+ Another optional helper. Add the following to your `<body>` tag:
137
+
138
+ ```haml
139
+ %body{:class => effective_pages_body_classes}
140
+ ```
141
+
142
+ to apply the following html classes: `params[:controller]`, `params[:action]`, `signed-in` / `not-signed-in`, `@page.template` and any thing set in the `@body_classes` instance variable.
143
+
144
+ This provides a mechanism to easily target CSS styles for specific pages.
145
+
146
+ This helper is entirely optional and in no way required for effective_pages to work.
147
+
148
+ ### Permissions
149
+
150
+ When creating a Page, if you've also installed the [effective_roles](https://github.com/code-and-effect/effective_roles) gem, you will be able to configure user access on a per-page basis.
151
+
152
+ Use this functionality to create member-only type pages.
153
+
154
+
155
+ ## Menus
156
+
157
+ The menus rendered by this gem output strict bootstrap3 (v3.3.2) html. It is intended for bootstrap3 navbars as well as footer menus, sidebar menus and more. It outputs the ul tag and all contained li items:
158
+
159
+ ```html
160
+ <ul class="nav navbar-nav">
161
+ ...
162
+ </ul>
163
+ ```
164
+
165
+ The bootstrap3 `.active` class will be added to the appropriate li item based on the current page.
166
+
167
+
168
+ ### Create a menu
169
+
170
+ Each Effective::Menu object is referred to by its title. The title is unique, so only one `'main menu'` can exist.
171
+
172
+ To display our first menu, we must create an Effective::Menu object and then render it in the Rails application layout or appropriate view.
173
+
174
+ To create your first menu, either:
175
+
176
+ - Visit `/admin/menus` and click `New Menu`. Give it a title: `'main menu'`.
177
+
178
+ or
179
+
180
+ - Run `bundle exec rake effective_pages:seed` to create a menu called `'main menu'` with some placeholder menu items.
181
+
182
+ then add it to your application layout where you would normally display your site's menu:
183
+
184
+ ```html
185
+ = render_menu('main menu')
186
+ ```
187
+
188
+ or with some additional custom classes rendered on the opening `<ul>` tag
189
+
190
+ ```html
191
+ = render_menu('main menu', :class => 'menu-right')
192
+ ```
193
+
194
+
195
+ ### Editing menu items
196
+
197
+ Once created and displayed by your application layout, the menu items will be drag-and-drop editable on any page where the menu is present. This menu editting functionality requires the [effective_regions](https://github.com/code-and-effect/effective_regions) gem.
198
+
199
+ So to edit the menu, visit any page on your website prefixed with `/edit/`. This will load the effective_regions editor, and all displayed Effective::Menu menus will have a dotted blue border which indicates it to be an editable region.
200
+
201
+ NOTE: Right now, the page you visit to edit the menu must contain an effective_region somewhere in a view. This requirement may be removed in the future. The menu editor will not work unless at least one effective_region is used somewhere on the page.
202
+
203
+ Once you're on the edit page and see the dotted blue bordered menus:
204
+
205
+ - Hover over the menu to click the Add button.
206
+ - Drag-and-drop items around to set their position in the menu.
207
+ - Drag-and-drop a menu item onto the trashcan icon to delete it.
208
+ - Double-click a menu item to bring up a dialog and configure its properties.
209
+
210
+ The menu item dialog provides all configurable options for each menu item.
211
+
212
+ A menu item's link can be configured in four different ways:
213
+
214
+ - Page, links to an Effective::Page object
215
+ - URL, any url you type
216
+ - Route, any rails route, such as destroy_user_session_path, root_path, or events_path
217
+ - Divider, an li with class='divider'
218
+
219
+ From this dialog, you can also configure permissions and add raw html classes.
220
+
221
+ Clicking 'Save' from the toolbar will persist the changes you've made to any menus.
222
+
223
+
224
+ ### Menu building DSL
225
+
226
+ Menus may also be created programatically.
227
+
228
+ As an Aside:
229
+
230
+ - To store the Effective::Menu tree structure, this gem implements the Modified Preorder Tree Traversal algorithm.
231
+ - Check out the [Storing Hierarchial Data in a Database](http://www.sitepoint.com/hierarchical-data-database-2/) guide for background information on this algorithm.
232
+ - You don't have to worry about any lft and rgt values when building menus with this gem.
233
+
234
+ To create the same tree structure used in the above article:
235
+
236
+ ```ruby
237
+ Effective::Menu.new(:title => 'some menu').build do
238
+ dropdown 'Fruit' do
239
+ dropdown 'Red' do
240
+ item 'Cherry'
241
+ end
242
+
243
+ dropdown 'Yellow' do
244
+ item 'Banana'
245
+ end
246
+ end
247
+
248
+ dropdown 'Meat' do
249
+ item 'Beef'
250
+ item 'Pork'
251
+ end
252
+ end.save
253
+ ```
254
+
255
+ and another more advanced example:
256
+
257
+ ```ruby
258
+ Effective::Menu.new(:title => 'main menu').build do
259
+ dropdown 'About' do
260
+ item Effective::Page.find_by_title('Who Are We?')
261
+ divider
262
+ item Effective::Page.find_by_title('Code of Ethics'), '#', :class => 'nav-indent'
263
+ item Effective::Page.find_by_title('Entrance Requirements'), '#', :class => 'nav-indent'
264
+ item Effective::Page.find_by_title('Board and Staff')
265
+ end
266
+
267
+ item 'Portal', :user_portal_path
268
+ item 'Pay Fees', '/fee_payments/new'
269
+ item 'Events', :events_path
270
+
271
+ dropdown 'Current Members', :roles_mask => 1 do # effective_roles. Only members see this dropdown
272
+ item Effective::Page.find_by_title('Volunteer Opportunities')
273
+ item Effective::Page.find_by_title('Mentoring')
274
+ end
275
+
276
+ dropdown 'Account', :signed_in => true do # Only current_user.present? users see this dropdown
277
+ item 'Site Admin', '/admin', :roles_mask => 3 # effective_roles. Only admins see this item
278
+ item 'Account Settings', :user_settings_path
279
+ divider
280
+ item 'Downloads', '#'
281
+ item 'Mentoring Resources', '#'
282
+ divider
283
+ item 'Sign Out', :destroy_user_session_path
284
+ end
285
+
286
+ item 'Sign In', :new_user_session_path, :signed_out => true # Only current_user.blank? users see this item
287
+ end.save
288
+ ```
289
+
290
+ The entire DSL consists of just 3 commands: dropdown, item and divider
291
+
292
+ with the following valid options:
293
+
294
+ ```ruby
295
+ :signed_in => true|false # Only signed in (current_user.present?) users see this item
296
+ :signed_out => true|false # Only signed out (current_user.blank?) users see this item
297
+ :roles_mask => 1 # See effective_roles Bitmask Implementation
298
+ :class => 'custom classes' # Custom HTML classes
299
+ :new_window => true # Open link in a new window
300
+ ```
301
+
302
+ ### Max Depth
303
+
304
+ The default max-depth for bootstrap3 menus is 2. As per the bootstrap3 navbar component, there exist only top level items and top level dropdowns that may contain only li items. No dropdowns in dropdowns.
305
+
306
+ This gem has the ability to extend the bootstrap3 functionality and provides support for dropdowns inside dropdowns to any nested depth.
307
+
308
+ To enable this functionality, require the following stylesheet on the asset pipeline by adding to your application.css:
309
+
310
+ ```ruby
311
+ *= require effective_pages
312
+ ```
313
+
314
+ and change the `config.menu[:maxdepth]` value in the `app/config/initializers/effective_pages.rb` initializer to 3, 4, or even 9999.
315
+
316
+
317
+ ## Authorization
318
+
319
+ All authorization checks are handled via the config.authorization_method found in the `config/initializers/effective_pages.rb` file.
320
+
321
+ It is intended for flow through to CanCan or Pundit, but neither of those gems are required.
322
+
323
+ This method is called by all controller actions with the appropriate action and resource
324
+
325
+ Action will be one of [:index, :show, :new, :create, :edit, :update, :destroy]
326
+
327
+ Resource will the appropriate Effective::Page object or class
328
+
329
+ The authorization method is defined in the initializer file:
330
+
331
+ ```ruby
332
+ # As a Proc (with CanCan)
333
+ config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) }
334
+ ```
335
+
336
+ ```ruby
337
+ # As a Custom Method
338
+ config.authorization_method = :my_authorization_method
339
+ ```
340
+
341
+ and then in your application_controller.rb:
342
+
343
+ ```ruby
344
+ def my_authorization_method(action, resource)
345
+ current_user.is?(:admin) || EffectivePunditPolicy.new(current_user, resource).send('#{action}?')
346
+ end
347
+ ```
348
+
349
+ or disabled entirely:
350
+
351
+ ```ruby
352
+ config.authorization_method = false
353
+ ```
354
+
355
+ If the method or proc returns false (user is not authorized) an Effective::AccessDenied exception will be raised
356
+
357
+ You can rescue from this exception by adding the following to your application_controller.rb:
358
+
359
+ ```ruby
360
+ rescue_from Effective::AccessDenied do |exception|
361
+ respond_to do |format|
362
+ format.html { render 'static_pages/access_denied', :status => 403 }
363
+ format.any { render :text => 'Access Denied', :status => 403 }
364
+ end
365
+ end
366
+ ```
367
+
368
+ ### Permissions
369
+
370
+ The permissions you actually want to define are as follows (using CanCan):
371
+
372
+ ```ruby
373
+ can [:show], Effective::Page
374
+ can [:manage], Effective::Page if user.is?(:admin)
375
+ ```
376
+
377
+
378
+ ## License
379
+
380
+ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
381
+
382
+ Code and Effect is the product arm of [AgileStyle](http://www.agilestyle.com/), an Edmonton-based shop that specializes in building custom web applications with Ruby on Rails.
383
+
384
+
385
+ ## Testing
386
+
387
+ Run tests by:
388
+
389
+ ```ruby
390
+ guard
391
+ ```
392
+
393
+ ## Contributing
394
+
395
+ 1. Fork it
396
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
397
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
398
+ 4. Push to the branch (`git push origin my-new-feature`)
399
+ 5. Bonus points for test coverage
400
+ 6. Create new Pull Request
29
401
 
30
402
 
@@ -1,10 +1,30 @@
1
1
  module EffectivePagesHelper
2
- def effective_page_header_tags(options = {})
3
- @page ||= nil
4
2
 
5
- [ content_tag(:title, (@page_title || options[:title] || @page.try(:title))),
6
- "<meta content='#{options[:meta_description] || @page.try(:meta_description)}' name='description' />",
7
- ].join("\n").html_safe
3
+ def effective_pages_body_classes
4
+ [
5
+ params[:controller].parameterize,
6
+ params[:action],
7
+ ((user_signed_in? ? 'signed-in' : 'not-signed-in') rescue nil),
8
+ (@page.template rescue nil),
9
+ @body_classes
10
+ ].compact.join(' ')
11
+ end
12
+
13
+ def effective_pages_header_tags
14
+ [
15
+ content_tag(:title, effective_pages_site_title),
16
+ effective_pages_meta_description_tag
17
+ ].compact.join("\n").html_safe
18
+ end
19
+
20
+ def effective_pages_site_title
21
+ (@page_title ? @page_title.to_s : "#{params[:controller].try(:titleize)} #{params[:action].try(:titleize)}") + EffectivePages.site_title_suffix.to_s
22
+ end
23
+
24
+ def effective_pages_meta_description_tag
25
+ if @page.try(:meta_description).present?
26
+ "<meta content='#{@page.try(:meta_description)}' name='description' />"
27
+ end
8
28
  end
9
29
 
10
30
  def application_root_to_effective_pages_slug
@@ -1,3 +1,3 @@
1
1
  module EffectivePages
2
- VERSION = "0.8.1"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -9,6 +9,7 @@ module EffectivePages
9
9
  mattr_accessor :pages_path
10
10
  mattr_accessor :excluded_pages
11
11
  mattr_accessor :excluded_layouts
12
+ mattr_accessor :site_title_suffix
12
13
 
13
14
  mattr_accessor :authorization_method
14
15
  mattr_accessor :simple_form_options
@@ -5,13 +5,18 @@ EffectivePages.setup do |config|
5
5
  config.menus_table_name = :menus
6
6
  config.menu_items_table_name = :menu_items
7
7
 
8
+ # The directory where your page templates live
9
+ # Any files in this directory will be automatically available when
10
+ # creating/editting an Effective::Page from the Admin screens
8
11
  # Relative to app/views/
9
12
  config.pages_path = '/effective/pages/'
10
13
 
11
14
  # Excluded Pages
15
+ # Any page templates from the above directory that should be excluded
12
16
  config.excluded_pages = []
13
17
 
14
18
  # Excluded Layouts
19
+ # Any app/views/layouts/ layout files that should be excluded
15
20
  config.excluded_layouts = [:admin]
16
21
 
17
22
  # Use CanCan: can?(action, resource)
@@ -21,11 +26,14 @@ EffectivePages.setup do |config|
21
26
  # Layout Settings
22
27
  # Configure the Layout per controller, or all at once
23
28
 
24
- # config.layout = 'application' # The layout for the EffectivePages admin screen
29
+ # The layout for the EffectivePages admin screen
25
30
  config.layout = {
26
31
  :admin => 'application'
27
32
  }
28
33
 
34
+ # This string will be appended to the effective_pages_header_tags title tag
35
+ config.site_title_suffix = " | #{Rails.application.class.name.split('::').first.titleize}"
36
+
29
37
  # SimpleForm Options
30
38
  # This Hash of options will be passed into any simple_form_for() calls
31
39
  config.simple_form_options = {}
@@ -42,8 +50,8 @@ EffectivePages.setup do |config|
42
50
 
43
51
  # All effective_page menu options
44
52
  config.menu = {
45
- :apply_active_class => true,
46
- :maxdepth => 2
53
+ :apply_active_class => true, # Add an .active class to the appropriate li item based on current page url
54
+ :maxdepth => 2 # 2 by default, strict bootstrap3 doesnt support dropdowns in your dropdowns
47
55
  }
48
56
 
49
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-20 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -122,7 +122,8 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 1.2.0
125
- description: CRUD Pages with intention to work with EffectiveRegions. WIP.
125
+ description: Content pages, bootstrap3 menu builder and page-specific header tag helpers
126
+ for your Rails app.
126
127
  email:
127
128
  - info@codeandeffect.com
128
129
  executables: []
@@ -232,7 +233,8 @@ rubyforge_project:
232
233
  rubygems_version: 2.4.3
233
234
  signing_key:
234
235
  specification_version: 4
235
- summary: CRUD Pages with intention to work with EffectiveRegions. WIP.
236
+ summary: Content pages, bootstrap3 menu builder and page-specific header tag helpers
237
+ for your Rails app.
236
238
  test_files:
237
239
  - spec/controllers/effective/pages_controller_spec.rb
238
240
  - spec/dummy/app/assets/javascripts/application.js