Module: Alchemy::PagesHelper

Includes:
BaseHelper, ElementsHelper
Defined in:
app/helpers/alchemy/pages_helper.rb

Instance Method Summary collapse

Methods included from ElementsHelper

#element_dom_id, #element_preview_code, #element_preview_code_attributes, #element_tags, #element_tags_attributes, #render_element, #render_elements, #sort_elements_by_content

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

Methods included from BaseHelper

#message_icon_class, #page_or_find, #render_flash_notice, #render_icon, #render_message, #shorten, #warning

Instance Method Details

#cell_empty?(name) ⇒ Boolean

Returns true or false if no elements are in the cell found by name.

Returns:

  • (Boolean)


317
318
319
320
321
# File 'app/helpers/alchemy/pages_helper.rb', line 317

def cell_empty?(name)
  cell = @page.cells.find_by_name(name)
  return true if cell.blank?
  cell.elements.not_trashed.empty?
end

#external_page_css_class(page) ⇒ Object

Returns ‘active’ if the given external page is in the current url path or nil.



217
218
219
220
# File 'app/helpers/alchemy/pages_helper.rb', line 217

def external_page_css_class(page)
  return nil if !page.redirects_to_external?
  request.path.split('/').delete_if(&:blank?).first == page.urlname.gsub(/^\//, '') ? 'active' : nil
end

Renders links to language root pages of all published languages.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • linkname (String) — default: 'name'

    Renders name/code of language, or I18n translation for code.

  • show_title (Boolean) — default: true

    Renders title attributes for the links.

  • spacer (String) — default: ''

    Renders the passed spacer string. You can also overwrite the spacer partial: “alchemy/language_links/_spacer”.

  • reverse (Boolean) — default: false

    Reverses the ordering of the links.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/helpers/alchemy/pages_helper.rb', line 26

def language_links(options = {})
  options = {
    linkname: 'name',
    show_title: true,
    spacer: '',
    reverse: false
  }.merge(options)
  languages = Language.on_current_site.published.with_root_page.order("name #{options[:reverse] ? 'DESC' : 'ASC'}")
  return nil if languages.count < 2
  render(
    partial: "alchemy/language_links/language",
    collection: languages,
    spacer_template: "alchemy/language_links/spacer",
    locals: {languages: languages, options: options}
  )
end

#meta_descriptionObject



285
286
287
# File 'app/helpers/alchemy/pages_helper.rb', line 285

def meta_description
  @page.meta_description.presence || Language.current_root_page.try(:meta_description)
end

#meta_keywordsObject



289
290
291
# File 'app/helpers/alchemy/pages_helper.rb', line 289

def meta_keywords
  @page.meta_keywords.presence || Language.current_root_page.try(:meta_keywords)
end

#meta_robotsObject



293
294
295
# File 'app/helpers/alchemy/pages_helper.rb', line 293

def meta_robots
  "#{@page.robot_index? ? '' : 'no'}index, #{@page.robot_follow? ? '' : 'no'}follow"
end

#page_active?(page) ⇒ Boolean

Returns true if page is in the active branch

Returns:

  • (Boolean)


211
212
213
214
# File 'app/helpers/alchemy/pages_helper.rb', line 211

def page_active?(page)
  @_page_ancestors ||= Page.ancestors_for(@page)
  @_page_ancestors.include?(page)
end

#page_title(options = {}) ⇒ Object

Returns current page title

Options:

prefix: ""                 # Prefix
separator: ""              # Separating prefix and title


268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'app/helpers/alchemy/pages_helper.rb', line 268

def page_title(options = {})
  return "" if @page.title.blank?
  options = {
    prefix: "",
    suffix: "",
    separator: ""
  }.update(options)
  title_parts = [options[:prefix]]
  if response.status == 200
    title_parts << @page.title
  else
    title_parts << response.status
  end
  title_parts << options[:suffix]
  title_parts.reject(&:blank?).join(options[:separator]).html_safe
end

#picture_essence_caption(content) ⇒ Object



8
9
10
# File 'app/helpers/alchemy/pages_helper.rb', line 8

def picture_essence_caption(content)
  content.try(:essence).try(:caption)
end

#render_breadcrumb(options = {}) ⇒ Object

Returns page links in a breadcrumb beginning from root to current page.

Options:

separator: %(<span class="separator">></span>)      # Maybe you don't want this separator. Pass another one.
page: @page                                         # Pass a different Page instead of the default (@page).
without: nil                                        # Pass Page object or array of Pages that must not be displayed.
restricted_only: false                              # Pass boolean for displaying restricted pages only.
reverse: false                                      # Pass boolean for displaying breadcrumb in reversed reversed.


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'app/helpers/alchemy/pages_helper.rb', line 232

def render_breadcrumb(options = {})
  options = {
    separator: ">",
    page: @page,
    restricted_only: false,
    reverse: false,
    link_active_page: false
  }.merge(options)

  pages = Page.
    ancestors_for(options[:page]).
    accessible_by(current_ability, :see)

  if options.delete(:restricted_only)
    pages = pages.restricted
  end

  if options.delete(:reverse)
    pages = pages.reorder('lft DESC')
  end

  if options[:without].present?
    without = options.delete(:without)
    pages = pages.where.not(id: without.try(:collect, &:id) || without.id)
  end

  render 'alchemy/breadcrumb/wrapper', pages: pages, options: options
end

#render_cell(name, options = {}) ⇒ Object

Renders the partial for the cell with the given name of the current page. Cell partials are located in app/views/cells/ of your project.

Options are:

from_page: Alchemy::Page     # Alchemy::Page object from which the elements are rendered from.
locals: Hash                 # Hash of variables that will be available in the partial. Example: {user: var1, product: var2}


305
306
307
308
309
310
311
312
313
314
# File 'app/helpers/alchemy/pages_helper.rb', line 305

def render_cell(name, options = {})
  default_options = {
    from_page: @page,
    locals: {}
  }
  options = default_options.merge(options)
  cell = options[:from_page].cells.find_by_name(name)
  return "" if cell.blank?
  render partial: "alchemy/cells/#{name}", locals: {cell: cell}.merge(options[:locals])
end

#render_navigation(options = {}, html_options = {}) ⇒ Object

Renders the navigation.

It produces a html <ul><li></li></ul> structure with all necessary classes so you can produce every navigation the web uses today. I.E. dropdown-navigations, simple mainnavigations or even complex nested ones.

HTML output:

<ul class="navigation level_1">
  <li class="first home"><a href="/home" class="active" title="Homepage" lang="en" data-page-id="1">Homepage</a></li>
  <li class="contact"><a href="/contact" title="Contact" lang="en" data-page-id="2">Contact</a></li>
  <li class="last imprint"><a href="/imprint" title="Imprint" lang="en" data-page-id="3">Imprint</a></li>
</ul>

As you can see: Everything you need.

Not pleased with the way Alchemy produces the navigation structure?

Then feel free to overwrite the partials (_renderer.html.erb and _link.html.erb) found in views/navigation/ or pass different partials via the options :navigation_partial and :navigation_link_partial.

Passing HTML classes and ids to the renderer

A second hash can be passed as html_options to the navigation renderer partial.

Example:

<%= render_navigation({from_page: 'subnavi'}, {class: 'navigation', id: 'subnavigation'}) %>

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • submenu (Boolean) — default: false

    Do you want a nested <ul> <li> structure for the deeper levels of your navigation, or not? Used to display the subnavigation within the mainnaviagtion. I.e. for dropdown menues.

  • all_sub_menues (Boolean) — default: false

    Renders the whole page tree.

  • from_page (Alchemy::Page) — default: @root_page

    Do you want to render a navigation from a different page then the current page? Then pass an Page instance or a Alchemy::PageLayout name as string.

  • spacer (String) — default: nil

    A spacer for the entries can be passed. Simple string, or even a complex html structure. I.e: “<span class=‘spacer’>|</spacer>”.

  • navigation_partial (String) — default: "navigation/renderer"

    Pass a different partial to be taken for the navigation rendering. Alternatively you could override the app/views/alchemy/navigation/renderer partial in your app.

  • navigation_link_partial (String) — default: "navigation/link"

    Alchemy places an <a> html link in <li> tags. The tag automatically has an active css class if necessary. So styling is everything. But maybe you don’t want this. So feel free to make you own partial and pass the filename here. Alternatively you could override the app/views/alchemy/navigation/link partial in your app.

  • show_nonactive (Boolean) — default: false

    Commonly Alchemy only displays the submenu of the active page (if submenu: true). If you want to display all child pages then pass true (together with submenu: true of course). I.e. for css-driven drop down menues.

  • show_title (Boolean) — default: true

    For our beloved SEOs :) Appends a title attribute to all links and places the page.title content into it.

  • restricted_only (Boolean) — default: false

    Render only restricted pages. I.E for members only navigations.

  • reverse (Boolean) — default: false

    Reverse the output of the pages

  • reverse_children (Boolean) — default: false

    Like reverse option, but only reverse the children of the first level

  • deepness (Fixnum) — default: nil

    Show only pages up to this depth.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/helpers/alchemy/pages_helper.rb', line 151

def render_navigation(options = {}, html_options = {})
  options = {
    submenu: false,
    all_sub_menues: false,
    from_page: @root_page || Language.current_root_page,
    spacer: nil,
    navigation_partial: 'alchemy/navigation/renderer',
    navigation_link_partial: 'alchemy/navigation/link',
    show_nonactive: false,
    restricted_only: false,
    show_title: true,
    reverse: false,
    reverse_children: false
  }.merge(options)
  page = page_or_find(options[:from_page])
  return nil if page.blank?
  pages = page.children.accessible_by(current_ability, :see)
  pages = pages.restricted if options.delete(:restricted_only)
  if depth = options[:deepness]
    pages = pages.where('depth <= ?', depth)
  end
  if options[:reverse]
    pages.reverse!
  end
  render options[:navigation_partial],
    options: options,
    pages: pages,
    html_options: html_options
end

#render_page_layoutObject

Renders the layout for current page.

Page layout files belongs in /app/views/alchemy/page_layouts/

Falls back to /app/views/alchemy/page_layouts/standard if the page_layout partial is not found.



49
50
51
52
53
54
# File 'app/helpers/alchemy/pages_helper.rb', line 49

def render_page_layout
  render @page, page: @page
rescue ActionView::MissingTemplate
  warning("PageLayout: '#{@page.page_layout}' not found. Rendering standard page_layout.")
  render 'alchemy/page_layouts/standard', page: @page
end

#render_site_layoutObject

Renders a partial for current site

Place a rails partial into app/views/alchemy/site_layouts

and name it like your site name.

Example:

<%= render_site_layout %>

renders app/views/alchemy/site_layouts/_default_site.html.erb for the site named “Default Site”.



68
69
70
71
72
73
# File 'app/helpers/alchemy/pages_helper.rb', line 68

def render_site_layout
  render current_alchemy_site
rescue ActionView::MissingTemplate
  warning("Site layout for #{current_alchemy_site.try(:name)} not found. Please run `rails g alchemy:site_layouts`")
  ""
end

#render_subnavigation(options = {}, html_options = {}) ⇒ Object

Renders navigation the children and all siblings of the given page (standard is the current page).

Use this helper if you want to render the subnavigation independent from the mainnavigation. I.E. to place it in a different area on your website.

This helper passes all its options to the the render_navigation helper.

Options:

from_page: @page                              # The page to render the navigation from
submenu: true                                 # Shows the nested children
level: 2                                      # Normally there is no need to change the level parameter, just in a few special cases


193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'app/helpers/alchemy/pages_helper.rb', line 193

def render_subnavigation(options = {}, html_options = {})
  default_options = {
    from_page: @page,
    submenu: true,
    level: 2
  }
  options = default_options.merge(options)
  if !options[:from_page].nil?
    while options[:from_page].level > options[:level]
      options[:from_page] = options[:from_page].parent
    end
    render_navigation(options, html_options)
  else
    return nil
  end
end