Module: Alchemy::Page::PageElements

Extended by:
ActiveSupport::Concern
Included in:
Alchemy::Page
Defined in:
app/models/alchemy/page/page_elements.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#available_element_definitions(only_element_named = nil) ⇒ Object

All available element definitions that can actually be placed on current page.

It extracts all definitions that are unique or limited and already on page.

Example of unique element:

- name: headline
  unique: true
  contents:
  - name: headline
    type: EssenceText

Example of limited element:

- name: article
  amount: 2
  contents:
  - name: text
    type: EssenceRichtext

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/models/alchemy/page/page_elements.rb', line 121

def available_element_definitions(only_element_named = nil)
  @_element_definitions ||= if only_element_named
    definition = Element.definition_by_name(only_element_named)
    element_definitions_by_name(definition['nestable_elements'])
  else
    element_definitions
  end

  return [] if @_element_definitions.blank?

  @_existing_element_names = elements.not_trashed.pluck(:name)
  delete_unique_element_definitions!
  delete_outnumbered_element_definitions!

  @_element_definitions
end

#available_element_namesObject

All names of elements that can actually be placed on current page.


140
141
142
# File 'app/models/alchemy/page/page_elements.rb', line 140

def available_element_names
  @_available_element_names ||= available_element_definitions.map { |e| e['name'] }
end

#available_elements_within_current_scope(parent) ⇒ Object

Available element definitions excluding nested unique elements.


146
147
148
149
150
151
152
153
154
155
# File 'app/models/alchemy/page/page_elements.rb', line 146

def available_elements_within_current_scope(parent)
  @_available_elements = if parent
    parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
    available_element_definitions(parent.name).reject do |e|
      parents_unique_nested_elements.include? e['name']
    end
  else
    available_element_definitions
  end
end

#descendent_element_definitionsObject

All element definitions defined for page's page layout including nestable element definitions


168
169
170
171
172
173
174
# File 'app/models/alchemy/page/page_elements.rb', line 168

def descendent_element_definitions
  definitions = element_definitions_by_name(element_definition_names)
  definitions.select { |d| d.key?('nestable_elements') }.each do |d|
    definitions += element_definitions_by_name(d['nestable_elements'])
  end
  definitions.uniq { |d| d['name'] }
end

#element_definition_namesObject

All names of elements that are defined in the corresponding page and cell definition.

Assign elements to a page in config/alchemy/page_layouts.yml and/or config/alchemy/cells.yml file.

Example of page_layouts.yml:

- name: contact
  cells: [right_column]
  elements: [headline, contactform]

Example of cells.yml:

- name: right_column
  elements: [teaser]

193
194
195
# File 'app/models/alchemy/page/page_elements.rb', line 193

def element_definition_names
  element_names_from_definition | element_names_from_cell_definitions
end

#element_definitionsObject

All element definitions defined for page's page layout

Warning: Since elements can be unique or limited in number, it is more safe to ask for available_element_definitions


162
163
164
# File 'app/models/alchemy/page/page_elements.rb', line 162

def element_definitions
  @_element_definitions ||= element_definitions_by_name(element_definition_names)
end

#element_definitions_by_name(names) ⇒ Array

Element definitions with given name(s)

Parameters:

  • one (Array || String)

    or many Alchemy::Element names. Pass 'all' to get all Element definitions

Returns:

  • (Array)

    An Array of element definitions


204
205
206
207
208
209
210
211
212
# File 'app/models/alchemy/page/page_elements.rb', line 204

def element_definitions_by_name(names)
  return [] if names.blank?

  if names.to_s == "all"
    Element.definitions
  else
    Element.definitions.select { |e| names.include? e['name'] }
  end
end

#element_names_from_definitionObject


235
236
237
# File 'app/models/alchemy/page/page_elements.rb', line 235

def element_names_from_definition
  definition['elements'] || []
end

#feed_elementsObject

Returns all elements that should be feeded via rss.

Define feedable elements in your page_layouts.yml:

- name: news
  feed: true
  feed_elements: [element_name, element_2_name]

222
223
224
# File 'app/models/alchemy/page/page_elements.rb', line 222

def feed_elements
  elements.available.named(definition['feed_elements'])
end

#find_elements(options = {}, show_non_public = false) ⇒ ActiveRecord::Relation Also known as: find_selected_elements

Finds elements of page.

Parameters:

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

    hash

  • (false) (Boolean)

    Pass true, if you want to also have not published elements.

Options Hash (options):

  • only (Array)

    Returns only elements with given names

  • except (Array)

    Returns all elements except the ones with given names

  • count (Fixnum)

    Limit the count of returned elements

  • offset (Fixnum)

    Starts with an offset while returning elements

  • random (Boolean) — default: false

    Return elements randomly shuffled

  • from_cell (Alchemy::Cell || String)

    Return elements from given cell

Returns:

  • (ActiveRecord::Relation)

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/models/alchemy/page/page_elements.rb', line 83

def find_elements(options = {}, show_non_public = false)
  elements = elements_from_cell_or_self(options[:from_cell])
  if options[:only].present?
    elements = elements.named(options[:only])
  elsif options[:except].present?
    elements = elements.excluded(options[:except])
  end
  if options[:reverse_sort] || options[:reverse]
    elements = elements.reverse_order
  end
  elements = elements.offset(options[:offset]).limit(options[:count])
  if options[:random]
    elements = elements.order("RAND()")
  end
  show_non_public ? elements : elements.published
end

#richtext_contents_idsObject

Returns an array of all EssenceRichtext contents ids from not folded elements


228
229
230
231
232
233
# File 'app/models/alchemy/page/page_elements.rb', line 228

def richtext_contents_ids
  descendent_contents
    .where(Element.table_name => {folded: false})
    .select(&:has_tinymce?)
    .collect(&:id)
end