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_alchemy_picture_path, #show_alchemy_picture_url, #show_page_path_params, #show_picture_path_params

Methods included from EssencesHelper

#render_essence, #render_essence_view, #render_essence_view_by_name

Methods included from BaseHelper

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

Instance Method Details

#alchemy_preview_mode_codeObject

Include this in your layout file to have element selection magic in the page edit preview window.



417
418
419
420
421
422
# File 'app/helpers/alchemy/pages_helper.rb', line 417

def alchemy_preview_mode_code
  if @preview_mode
    javascript_tag("Alchemy = { locale: '#{session[:alchemy_locale]}' };") +
      javascript_include_tag("alchemy/preview")
  end
end

#cell_empty?(name) ⇒ Boolean

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

Returns:

  • (Boolean)


410
411
412
413
414
# File 'app/helpers/alchemy/pages_helper.rb', line 410

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.



215
216
217
218
# File 'app/helpers/alchemy/pages_helper.rb', line 215

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.



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

def language_links(options = {})
  options = {
    linkname: 'name',
    show_title: true,
    spacer: '',
    reverse: false
  }.merge(options)
  languages = Language.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

#page_active?(page) ⇒ Boolean

Returns true if page is in the active branch

Returns:

  • (Boolean)


209
210
211
212
# File 'app/helpers/alchemy/pages_helper.rb', line 209

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

#picture_essence_caption(content) ⇒ Object



6
7
8
# File 'app/helpers/alchemy/pages_helper.rb', line 6

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.


230
231
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
260
# File 'app/helpers/alchemy/pages_helper.rb', line 230

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.to_a.reverse!
  end

  if options[:without].present?
    if options[:without].class == Array
      pages = pages.to_a - options[:without]
    else
      pages.to_a.delete(options[:without])
    end
  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}


398
399
400
401
402
403
404
405
406
407
# File 'app/helpers/alchemy/pages_helper.rb', line 398

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_meta_data(options = {}) ⇒ Object

This helper takes care of all important meta tags for your page.

The meta data is been taken from the @page.title, @page.meta_description, @page.meta_keywords, @page.updated_at and @page.language database entries managed by the Alchemy user via the Alchemy cockpit.

Assume that the user has entered following data into the Alchemy cockpit of the Page “home” and that the user wants that the searchengine (aka. google) robot should index the page and should follow all links on this page:

Title = Homepage Description = Your page description Keywords: cms, ruby, rubyonrails, rails, software, development, html, javascript, ajax

Then placing render_meta_data(title_prefix: “Company”, title_separator: “-”) into the <head> part of the pages.html.erb layout produces:

<meta charset="utf-8">
<title>Company - #{@page.title}</title>
<meta name="description" content="Your page description">
<meta name="keywords" content="cms, ruby, rubyonrails, rails, software, development, html, javascript, ajax">
<meta name="created" content="Tue Dec 16 10:21:26 +0100 2008">
<meta name="robots" content="index, follow">


342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'app/helpers/alchemy/pages_helper.rb', line 342

def (options = {})
  if @page.blank?
    warning("No Page found!")
    return nil
  end
  default_options = {
    title_prefix: "",
    title_separator: "",
    default_lang: "de"
  }
  options = default_options.merge(options)
  # render meta description of the root page from language if the current meta description is empty
  if @page.meta_description.blank?
    description = Language.current_root_page.try(:meta_description)
  else
    description = @page.meta_description
  end
  # render meta keywords of the root page from language if the current meta keywords is empty
  if @page.meta_keywords.blank?
    keywords = Language.current_root_page.try(:meta_keywords)
  else
    keywords = @page.meta_keywords
  end
  robot = "#{@page.robot_index? ? '' : 'no'}index, #{@page.robot_follow? ? '' : 'no'}follow"
  meta_string = %(
    #{tag(:meta, charset: 'utf-8')}
    #{render_title_tag(prefix: options[:title_prefix], separator: options[:title_separator])}
    #{render_meta_tag(name: 'created', content: @page.updated_at)}
    #{render_meta_tag(name: 'robots', content: robot)}
  )
  if description.present?
    meta_string += %(
      #{render_meta_tag(name: 'description', content: description.html_safe)}
    )
  end
  if keywords.present?
    meta_string += %(
      #{render_meta_tag(name: 'keywords', content: keywords.html_safe)}
    )
  end
  if @page.contains_feed?
    meta_string += %(
      #{auto_discovery_link_tag(:rss, show_alchemy_page_url(@page, format: :rss))}
    )
  end
  meta_string.html_safe
end

#render_meta_tag(options = {}) ⇒ Object

Renders a html <meta> tag for name: “” and content: “”

Webdevelopers:

Please use the render_meta_data() helper. There all important meta information gets rendered in one helper. So you dont have to worry about anything.



312
313
314
315
316
317
318
319
320
321
# File 'app/helpers/alchemy/pages_helper.rb', line 312

def render_meta_tag(options = {})
  default_options = {
    name: "",
    default_language: "de",
    content: ""
  }
  options = default_options.merge(options)
  lang = (@page.language.blank? ? options[:default_language] : @page.language.code)
  tag(:meta, name: options[:name], content: options[:content], lang: lang)
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.



149
150
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
# File 'app/helpers/alchemy/pages_helper.rb', line 149

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("#{Page.table_name}.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.



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

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_page_title(options = {}) ⇒ Object

Returns current page title

Options:

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

Webdevelopers

Please use the render_meta_data() helper instead. There all important meta information gets rendered in one helper. So you dont have to worry about anything.



274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'app/helpers/alchemy/pages_helper.rb', line 274

def render_page_title(options = {})
  return "" if @page.title.blank?
  options = {
    prefix: "",
    separator: ""
  }.update(options)
  title_parts = [options[:prefix]]
  if response.status == 200
    title_parts << @page.title
  else
    title_parts << response.status
  end
  title_parts.join(options[:separator]).html_safe
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”.



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

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`")
  return ""
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


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

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

#render_title_tag(options = {}) ⇒ Object

Returns a complete html <title> tag for the <head> part of the html document.

Webdevelopers:

Please use the render_meta_data() helper. There all important meta information gets rendered in one helper. So you dont have to worry about anything.



296
297
298
299
300
301
302
303
# File 'app/helpers/alchemy/pages_helper.rb', line 296

def render_title_tag(options = {})
  default_options = {
    prefix: "",
    separator: ""
  }
  options = default_options.merge(options)
  (:title, render_page_title(options))
end