Blocks are rendered using the render_block or render_block_slot helpers
which control all the logic related with rendering a block, including fragment
cache control.
The render_block_slot helper is a wrapper of the render_block helper that
includes the block slot information in the cache key and the block slot as a
local variable (slot) for the partial.
In the end a partial is rendered using the block as a local variable to obtain the information.
This partial must be found at the partials folder configured in the engine's
initializer using the front_partials_folder option. By default this folder will
be no_cms/blocks/blocks inside the views folder of yout application.
The partials name will also be configured in the template setting of the
block.
This way, rendering a 'title-3_columns' would render the partial
/no_cms/blocks/blocks/title_3_columns. If we configure
NoCms::blocks.front_partials_folder to be my_skin/blocks then it would
render the partial my_skin/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/blocks/blocks/title_3_columns.html.erb partial:
<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.
Other local variables can be declared and sent using a locals option when
calling the render_block method:
render_block block, locals: { user: current_user }And, as with any other partial, you can use them inside.
<div class='columns_block'>
<h1>This is just for you <%= user.name %>!!</h2>
<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>Since this is plain old rails you can do everything you can do with a partial
(e.g. having a /no_cms/blocks/blocks/title_3_columns.en.html.erb for the
english version and a /no_cms/blocks/blocks/title_3_columns.es.html.erb for
the spanish one).
As seen before you can nest some blocks inside others.
However, displaying the nested blocks is your responsability. You should use the
render_block or render_block_slot helpers depending on whether you're using
slots.
A rather typical template would be:
<h2 class="title"><%= block.title %></h2>
<div class='nested_block'>
<% if local_assigns.has_key? :slot %>
<% slot.children.each do |c| %>
<%= render_block_slot c %>
<% end -%>
<% else %>
<% block.children.each do |c| %>
<%= render_block c %>
<% end -%>
<% end -%>
</div>As seen when we defined templates and zones some blocks must be loaded not directly in the view but through some lazy loading technique, such as an ajax request and some front-end framework.
That's why we must configure a different view for the lazy loading the block where we show an skeleton of the block or whatever conde is required to load it after the page is ready.
The partial will be configured as the skeleton_template setting of the block
configuration. This is not a mandatory attribute and if it's not defined it will
take the value default.
The folder for skeletons partials will ve configured also separately in the
variable NoCms::Blocks.front_skeletons_folder. This way, you can completely
separate your regular and your skeleton templates.
The render_block_slot helper will check the block and template configurations
to decide wether it must use the regular templates or the skeleton ones.
You could also force it through the render_block_slot or the render_block
helpers sending the lazy_block option as true.
Once the skeleton is rendered, it's up to you how to manage it!
A block can have its own CSS files so the application.css doesn't get too big. You can configure a block to have multiple css files suitable for differente devices or mediaqueries.
This configuration comes from the css_templates setting in a block
configuration where you can set an array of css file names, such as:
NoCms::Blocks.configure do |config|
config.block_layouts = {
'title-long_text' => {
template: 'title-long_text',
fields: {
title: :string,
body: :text
},
css_templates: [
'title-long_text_desktop',
'title-long_text_mobile',
'title-long_text_tablet',
'title-long_text_all'
]
}
}
end
In this configuration the title-long_text has four different css files. This
CSS files will not be automatically created and they must be created and
included in the asset pipeline by hand.
The name of the css_template uses the final suffix as an indicator of the
mediaquery that should apply to the file. In the example, for
title-long_text_desktop will apply the desktop mediaquery, for
title-long_text_mobile the mobile one and so on.
These mediaqueries are configured by the css_mediaqueries of the
NoCms::Blocks engine by default the value is
css_mediaqueries = {
mobile: 'only screen and (max-width: 767px)',
tablet: 'only screen and (min-width: 768px) and (max-width: 1024px)',
desktop: 'only screen and (min-width: 1025px)',
all: 'All'
}
The helper stylesheet_link_tags_for_block will return and string with all the
stylesheet_link_tag for the css files. In the example:
<link href="/stylesheets/no_cms/blocks/title-long_text/title-long_text_desktop.css" media="only screen and (min-width: 1025px)" rel="stylesheet" />
<link href="/stylesheets/no_cms/blocks/title-long_text/title-long_text_mobile.css" media="only screen and (max-width: 767px)" rel="stylesheet" />
<link href="/stylesheets/no_cms/blocks/title-long_text/title-long_text_tablet.css" media="only screen and (min-width: 768px) and (max-width: 1024px)" rel="stylesheet" />
<link href="/stylesheets/no_cms/blocks/title-long_text/title-long_text_all.css" media="All" rel="stylesheet" />