Skip to content

Commit

Permalink
Merge branch 'edge'
Browse files Browse the repository at this point in the history
  • Loading branch information
Luis Mendo committed Nov 4, 2015
2 parents 4adb8c8 + 1e5d17b commit dcab43c
Show file tree
Hide file tree
Showing 60 changed files with 931 additions and 774 deletions.
11 changes: 11 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
appraise "rails-4-0" do
gem "rails", "4.0.13"
end

appraise "rails-4-1" do
gem "rails", "4.1.13"
end

appraise "rails-4-2" do
gem "rails", "4.2.3"
end
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ group :test do
gem 'factory_girl'
gem 'capybara'
gem 'database_cleaner'
gem 'appraisal'
end
24 changes: 17 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
PATH
remote: .
specs:
nocms-pages (0.0.1)
nocms-pages (1.0.0)
awesome_nested_set (>= 3.0.0.rc.6)
globalize (~> 4.0, >= 4.0.0)
globalize (>= 4.0.0, < 5.1)
nocms-blocks (~> 1.1.1)
rails (~> 4.0, >= 4.0.3)

GEM
Expand All @@ -26,15 +27,19 @@ GEM
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.3)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activerecord-deprecated_finders (1.0.4)
activesupport (4.0.3)
i18n (~> 0.6, >= 0.6.4)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
appraisal (2.1.0)
bundler
rake
thor (>= 0.14.0)
arel (4.0.2)
awesome_nested_set (3.0.0)
awesome_nested_set (3.0.2)
activerecord (>= 4.0.0, < 5)
builder (3.1.4)
capybara (2.2.1)
Expand All @@ -55,7 +60,7 @@ GEM
activesupport (>= 3.0.0)
faker (1.2.0)
i18n (~> 0.5)
globalize (4.0.0)
globalize (4.0.3)
activemodel (>= 4.0.0, < 5)
activerecord (>= 4.0.0, < 5)
hike (1.2.3)
Expand All @@ -68,9 +73,13 @@ GEM
mini_portile (0.5.2)
minitest (4.7.5)
multi_json (1.10.1)
nocms-blocks (1.1.1)
awesome_nested_set (~> 3.0.0)
globalize (>= 4.0.0, < 5.1)
rails (~> 4.0, <= 4.2.3)
nokogiri (1.6.1)
mini_portile (~> 0.5.0)
polyglot (0.3.4)
polyglot (0.3.5)
rack (1.5.2)
rack-test (0.6.2)
rack (>= 1.0)
Expand Down Expand Up @@ -108,7 +117,7 @@ GEM
rspec-mocks (= 3.0.0.beta2)
rspec-support (= 3.0.0.beta2)
rspec-support (3.0.0.beta2)
sprockets (2.11.0)
sprockets (2.12.4)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
Expand All @@ -132,6 +141,7 @@ PLATFORMS
ruby

DEPENDENCIES
appraisal
capybara
carrierwave
database_cleaner
Expand Down
141 changes: 17 additions & 124 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ bundle install
And then import all the migrations:

```
rake no_cms_blocks:install:migrations
rake no_cms_pages:install:migrations
```

Expand Down Expand Up @@ -68,133 +69,23 @@ This `template` is set from the template attribute, being `show` the default val

### Blocks

Blocks are the unit of contents the pages are made of. They are thought to be independent and customizable modules that can be created, edited or removed on their own, without dependency of any other module.
In a previous gem version blocks were a model within the NoCms::Pages namespace, but now everything was moved to the [nocms-blocks](https://github.com/simplelogica/nocms-blocks) and in this repo there's only left a rake task for the migration.

#### Block layouts

In NoCMS Pages, block layouts define two main things:

1. What kind of information a block contains and other settings (i.e. cache settings).
2. How this information is displayed within the page.

Block settings are configured in the file `config/initializers/nocms/pages.rb`. Here we declare all the available layouts for a block.

The following code

```ruby
NoCms::Pages.configure do |config|

config.block_layouts = {
'default' => {
template: 'default',
fields: {
title: :string,
body: :text
}
},
'title-3_columns' => {
template: 'title_3_columns',
fields: {
title: :string,
column_1: :text,
column_2: :text,
column_3: :text
},
},
'logo-caption' => {
template: 'logo_caption',
fields: {
caption: :string,
logo: TestImage
}
}
}

end
```

declares 3 layouts ('default', 'title-3_columns' and 'logo-caption'). Each layout has a template and some declared fields. These fields will be available in the ruby object for that block. As an example, if `@block` is an instance of the NoCms::Pages::Block model which layout attribute is set to 'default' you will be able to do `@block.title`

```ruby
block = NoCms::Pages::Block.new
block.layout = 'default'

block.title = 'a title'
block.title # => 'a title'

block.column_1 = 'a column' # => NoMethodError
block.column_1 # => NoMethodError


block.layout = 'title-3_columns'

block.title # => 'a title'
block.column_1 = 'a column'
block.column_1 # => 'a column'
block.body # => NoMethodError

block.layout = 'logo_caption'
block.title # => NoMethodError
block.logo = { name: 'testing logo' } # Currently this is the way to assign objects
block.logo.name # => 'testing logo'
block.logo.class # => TestImage
block.logo = TestImage.new name: 'testing logo' # Error! Currently assigning the object is not allowed :(
```

#### Block templates

Blocks are rendered using the `render_block` helper which controls all the logic related with renderinf a block, including fragment cache control.

In the end a partial is rendered using the block as a local variable to obtain the information. This partial must be found at `no_cms/pages/blocks` views folder and have the name configured in the `template` setting of the block. This way, rendering a 'title-3_columns' would render the partial `/no_cms/pages/blocks/title_3_columns`.

This partial is a regular Rails partial (nothing special here). AS an example, this could be the content of our `/no_cms/pages/blocks/title_3_columns.html.erb` partial:

```html
<div class='columns_block'>
<h2 class="title"><%= block.title %></h2>
<p class="column_1"><%= block.column_1 %></p>
<p class="column_2"><%= block.column_2 %></p>
<p class="column_3"><%= block.column_3 %></p>
</div>
```

As you can see, the partial has a block variable containing the block object you are rendering.

Since this is plain old rails you can do everything you can do with a partial (i.e. having a `/no_cms/pages/blocks/title_3_columns.en.html.erb` for the english version and a `/no_cms/pages/blocks/title_3_columns.es.html.erb` for the spanish one).
You can read the steps for a sucessful block migration in its own [migration documentation](doc/migration-blocks-steps.md)

### Block Cache

Since blocks are independent units of content within a page, the standard Rails fragment cache seemed to fit well with them. That's why the `render_block` helper decides wether Rails cache should be used for rendering an individual block.

Cache for the blocks are configured at 3 levels:
Blocks are rendered through the `render_page_block` helper instead of the `render_block` helper from `nocms-blocks`. This helper uses the `render_block` helper but add some extra cache levels:

1. The page may have its `cache_enabled` attribute set to false. If this is the case then the cache will be disabled without any further check. This way, a page can be marked as "not cacheable" (e.g. in an admin interface) and no other setting can overwrite it.

2. The `render_block` helper may be called with a `cache_enabled` option set to true or false. This option will enable/disable the cache. This allow us to render a block without using the cache (maybe on a preview action).
2. The `render_page_block` helper may be called with a `cache_enabled` option set to true or false. This option will enable/disable the cache. This allow us to render a block without using the cache (maybe on a preview action).

```ruby
render_block block, cache: false
```

3. In the blocks configuration we can enable/disable the cache for all the blocks of a kind. We just have to add the cache_enabled setting.

```ruby
NoCms::Pages.configure do |config|

config.block_layouts = {
'default' => {
template: 'default',
fields: {
title: :string,
body: :text
},
cache_enabled: false
}
}
end
```

4. In the blocks configuration file we can enable/disable cache for all the blocks that doesn't have a cache_enabled setting. This configuration will be stored at `NoCms::Pages.cache_enabled`
3. In the page configuration file we can enable/disable cache for all the blocks that doesn't have a cache_enabled setting. This configuration will be stored at `NoCms::Pages.cache_enabled`

```ruby
NoCms::Pages.configure do |config|
Expand All @@ -208,23 +99,25 @@ As a summary:

```ruby

b = NoCms::Pages::Block.new layout: 'default', title: 'Foo', description: 'Bar', page: page
b.page.cache_enabled # => true
b = NoCms::Blocks::Block.new layout: 'default', title: 'Foo', description: 'Bar'
page.blocks << b
page.cache_enabled # => true
NoCms::Pages.cache_enabled # => true
b.cache_enabled # => false, since the block configuration sets it to false
render_block b # => This won't use fragment cache since this block layout have cache disabled
render_page_block b # => This won't use fragment cache since this block layout have cache disabled

b = NoCms::Pages::Block.new layout: 'title-3_columns', title: 'Foo', description: 'Bar', page: page
b.page.cache_enabled # => true
b = NoCms::Blocks::Block.new layout: 'title-3_columns', title: 'Foo', description: 'Bar'
page.blocks << b
page.cache_enabled # => true
NoCms::Pages.cache_enabled # => true
b.cache_enabled # => true, since this block configuration doesn't override NoCms::Pages.cache_enabled
render_block b # => This will use fragment cache since, by default, it's enabled for all blocks
render_page_block b # => This will use fragment cache since, by default, it's enabled for all blocks

render_block b, cache_enabled: false # => This won't use fragment cache as the option in the helper overrides the block configuration
render_page_block b, cache_enabled: false # => This won't use fragment cache as the option in the helper overrides the block configuration

page.cache_enabled = false
render_block b # => This won't use fragment cache sincs it's been disabled for the page and blocks configuration has been override
render_block b, cache_enabled: true # => This won't use fragment cache even when saying the helper to do it. Power for the users!
render_page_block b # => This won't use fragment cache sincs it's been disabled for the page and blocks configuration has been override
render_page_block b, cache_enabled: true # => This won't use fragment cache even when saying the helper to do it. Power for the users!

```

Expand Down
5 changes: 4 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_files.include('lib/**/*.rb')
end

Bundler::GemHelper.install_tasks


APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'

Bundler::GemHelper.install_tasks

task :default => [:"app:spec"]
1 change: 1 addition & 0 deletions app/controllers/no_cms/pages/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module NoCms
module Pages
class ApplicationController < ::ApplicationController
helper NoCms::Blocks::BlocksHelper
end
end
end
12 changes: 12 additions & 0 deletions app/decorators/no_cms/blocks/block_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NoCms::Blocks::Block.class_eval do

after_create :set_default_position

has_and_belongs_to_many :pages, class_name: 'NoCms::Pages::Page'

def set_default_position
self.update_attribute :position, (((pages.map{|p| p.blocks.pluck(:position)}).flatten.compact.max || 0) + 1) if self[:position].blank? && self.pages.exists?
end

end

24 changes: 7 additions & 17 deletions app/helpers/no_cms/pages/pages_helper.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
module NoCms
module Pages
module PagesHelper
def render_block block, options = {}
# If cache is disabled for this block then we disable no matter what the block or the options passed have to say about it. This way, the user in the back has the last word about disabling cache
options[:cache_enabled] = false unless block.page.cache_enabled
# If we don't have any option about cache enabled then we ask the block
options[:cache_enabled] = block.cache_enabled unless options.has_key? :cache_enabled

block_template = "no_cms/pages/blocks/#{block.template}"

# And now decide if we use cache or not
if options[:cache_enabled]
Rails.cache.fetch "#{block_template}/#{block.id}/#{block.updated_at.to_i}" do
render block_template, block: block
end
else
render block_template, block: block
end

def render_page_block page, block, options = {}
# If cache is disabled for all pages or is disabled for this block
# then we disable no matter what the block or the options passed have to say about it.
# This way, the user in the back has the last word about disabling cache and the NoCms::Pages engine
# control the cache over the NoCms::Block engine
options[:cache_enabled] = false if !NoCms::Pages.cache_enabled || !page.cache_enabled
render_block block, options
end
end
end
Expand Down
Loading

0 comments on commit dcab43c

Please sign in to comment.