Module: Alchemy::ElementsHelper
- Includes:
- ElementsBlockHelper, EssencesHelper, UrlHelper
- Included in:
- PagesHelper
- Defined in:
- app/helpers/alchemy/elements_helper.rb
Overview
This helpers are useful to render elements from pages.
The most important helper for frontend developers is the #render_elements helper.
Instance Method Summary collapse
-
#element_dom_id(element) ⇒ Object
Returns a string for the id attribute of a html element for the given element.
-
#element_preview_code(element) ⇒ Object
Renders the HTML tag attributes required for preview mode.
-
#element_preview_code_attributes(element) ⇒ Object
Returns a hash containing the HTML tag attributes required for preview mode.
-
#element_tags(element, options = {}) ⇒ String
Returns the element’s tags information as a string.
-
#element_tags_attributes(element, options = {}) ⇒ Hash
Returns the element’s tags information as an attribute hash.
-
#render_element(*args) ⇒ Object
This helper renders a Element view partial.
-
#render_elements(options = {}) ⇒ Object
Renders elements from given page.
- #sort_elements_by_content(elements, content_name, reverse = false) ⇒ Array deprecated Deprecated.
Methods included from ElementsBlockHelper
#element_editor_for, #element_view_for
Methods included from UrlHelper
#download_alchemy_attachment_path, #download_alchemy_attachment_url, #full_url_for_element, #show_alchemy_page_path, #show_alchemy_page_url, #show_page_path_params
Methods included from EssencesHelper
#render_essence, #render_essence_view, #render_essence_view_by_name
Instance Method Details
#element_dom_id(element) ⇒ Object
Returns a string for the id attribute of a html element for the given element
196 197 198 199 |
# File 'app/helpers/alchemy/elements_helper.rb', line 196 def element_dom_id(element) return "" if element.nil? "#{element.name}_#{element.id}".html_safe end |
#element_preview_code(element) ⇒ Object
Renders the HTML tag attributes required for preview mode.
202 203 204 205 206 207 208 209 |
# File 'app/helpers/alchemy/elements_helper.rb', line 202 def element_preview_code(element) if respond_to?(:tag_options) (element_preview_code_attributes(element)) else # Rails 5.1 uses TagBuilder tag_builder.(element_preview_code_attributes(element)) end end |
#element_preview_code_attributes(element) ⇒ Object
Returns a hash containing the HTML tag attributes required for preview mode.
212 213 214 215 |
# File 'app/helpers/alchemy/elements_helper.rb', line 212 def element_preview_code_attributes(element) return {} unless element.present? && @preview_mode && element.page == @page { 'data-alchemy-element' => element.id } end |
#element_tags(element, options = {}) ⇒ String
Returns the element’s tags information as a string. Parameters and options are equivalent to #element_tags_attributes.
225 226 227 228 229 230 231 232 |
# File 'app/helpers/alchemy/elements_helper.rb', line 225 def (element, = {}) if respond_to?(:tag_options) ((element, )) else # Rails 5.1 uses TagBuilder tag_builder.((element, )) end end |
#element_tags_attributes(element, options = {}) ⇒ Hash
Returns the element’s tags information as an attribute hash.
245 246 247 248 249 250 251 252 |
# File 'app/helpers/alchemy/elements_helper.rb', line 245 def (element, = {}) = { formatter: lambda { || .join(' ') } }.merge() return {} if !element.taggable? || element.tag_list.blank? { 'data-element-tags' => [:formatter].call(element.tag_list) } end |
#render_element(*args) ⇒ Object
If the view partial is not found alchemy/elements/_view_not_found.html.erb
gets rendered.
This helper renders a Alchemy::Element view partial.
A element view partial is the html snippet presented to the website visitor.
The partial is located in app/views/alchemy/elements
.
View partial naming
The partial has to be named after the name of the element as defined in the elements.yml
file.
Example
Given a headline element
# elements.yml
- name: headline
contents:
- name: text
type: EssenceText
Then your element view partial has to be named like:
app/views/alchemy/elements/_headline.html.{erb|haml|slim}
Element partials generator
You can use this handy generator to let Alchemy generate the partials for you:
$ rails generate alchemy:elements --skip
Usage
<%= render_element(Alchemy::Element.available.named(:headline).first) %>
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'app/helpers/alchemy/elements_helper.rb', line 162 def render_element(*args) if args.length == 4 element, _part, , counter = *args Alchemy::Deprecation.warn "passing a `part` parameter as second argument to `render_element` has been removed without replacement. " \ "You can safely remove it." else element, , counter = *args end ||= {} counter ||= 1 if element.nil? warning('Element is nil') render "alchemy/elements/view_not_found", {name: 'nil'} return end element.store_page(@page) render element, { element: element, counter: counter, options: }.merge(.delete(:locals) || {}) rescue ActionView::MissingTemplate => e warning(%( Element view partial not found for #{element.name}.\n #{e} )) render "alchemy/elements/view_not_found", name: element.name end |
#render_elements(options = {}) ⇒ Object
Renders elements from given page
Examples:
Render only certain elements:
<header>
<%= render_elements only: ['header', 'claim'] %>
</header>
<section id="content">
<%= render_elements except: ['header', 'claim'] %>
</section>
Render elements from global page:
<footer>
<%= render_elements from_page: 'footer' %>
</footer>
Fallback to elements from global page:
You can use the fallback option as an override for elements that are stored on another page. So you can take elements from a global page and only if the user adds an element on current page the local one gets rendered.
-
You have to pass the the name of the element the fallback is for as
for
key. -
You have to pass a
page_layout
name or Page from where the fallback elements is taken from asfrom
key. -
You can pass the name of element to fallback with as
with
key. This is optional (the element name from thefor
key is taken as default).
<%= render_elements(fallback: {
for: 'contact_teaser',
from: 'sidebar',
with: 'contact_teaser'
}) %>
Custom elements finder:
Having a custom element finder class:
class MyCustomNewsArchive
def elements(page:)
news_page.elements.named('news').order(created_at: :desc)
end
private
def news_page
Alchemy::Page.where(page_layout: 'news-archive')
end
end
In your view:
<div class="news-archive">
<%= render_elements finder: MyCustomNewsArchive.new %>
</div>
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'app/helpers/alchemy/elements_helper.rb', line 92 def render_elements( = {}) = { from_page: @page, render_format: 'html' }.update() if [:sort_by] Alchemy::Deprecation.warn "options[:sort_by] has been removed without replacement. " \ "Please implement your own element sorting by passing a custom finder instance to options[:finder]." end if [:from_cell] Alchemy::Deprecation.warn "options[:from_cell] has been removed without replacement. " \ "Please `render element.nested_elements` instead." end finder = [:finder] || Alchemy::ElementsFinder.new() elements = finder.elements(page: [:from_page]) buff = [] elements.each_with_index do |element, i| buff << render_element(element, , i + 1) end buff.join([:separator]).html_safe end |
#sort_elements_by_content(elements, content_name, reverse = false) ⇒ Array
Sort given elements by content.
261 262 263 264 265 266 267 268 269 |
# File 'app/helpers/alchemy/elements_helper.rb', line 261 def sort_elements_by_content(elements, content_name, reverse = false) Alchemy::Deprecation.warn "options[:sort_by] is deprecated. Please implement your own element sorting." sorted_elements = elements.sort_by do |element| content = element.content_by_name(content_name) content ? content.ingredient.to_s : '' end reverse ? sorted_elements.reverse : sorted_elements end |