Class: Alchemy::Page
- Inherits:
-
BaseRecord
- Object
- ActiveRecord::Base
- BaseRecord
- Alchemy::Page
- Includes:
- Hints, Logger, PageElements, PageNaming, PageNatures, PageScopes, Taggable
- Defined in:
- app/models/alchemy/page.rb,
app/models/alchemy/page/url_path.rb
Defined Under Namespace
Modules: PageElements, PageNaming, PageNatures, PageScopes Classes: FixedAttributes, UrlPath
Constant Summary collapse
- DEFAULT_ATTRIBUTES_FOR_COPY =
{ autogenerate_elements: false, visible: false, public_on: nil, public_until: nil, locked_at: nil, locked_by: nil }
- SKIPPED_ATTRIBUTES_ON_COPY =
%w( id updated_at created_at creator_id updater_id lft rgt depth urlname cached_tag_list )
- PERMITTED_ATTRIBUTES =
[ :meta_description, :meta_keywords, :name, :page_layout, :public_on, :public_until, :restricted, :robot_index, :robot_follow, :sitemap, :tag_list, :title, :urlname, :visible, :layoutpage, :menu_id ]
Constants included from PageNaming
Instance Attribute Summary collapse
-
#menu_id ⇒ Object
Returns the value of attribute menu_id.
Class Method Summary collapse
- .all_from_clipboard(clipboard) ⇒ Object
- .all_from_clipboard_for_select(clipboard, language_id, layoutpage = false) ⇒ Object
-
.ancestors_for(current) ⇒ Object
Returns an array of all pages in the same branch from current.
-
.copy(source, differences = {}) ⇒ Alchemy::Page
Creates a copy of given source.
- .copy_and_paste(source, new_parent, new_name) ⇒ Object
-
.current_preview ⇒ Object
Returns the current page previewed in the edit page template.
-
.current_preview=(page) ⇒ Object
Used to store the current page previewed in the edit page template.
- .find_or_create_layout_root_for(language_id) ⇒ Object
-
.language_root_for(language_id) ⇒ Object
The language root page for given language id.
- .layout_root_for(language_id) ⇒ Object
- .link_target_options ⇒ Object
-
.root ⇒ Object
(also: rootpage)
The root page of the page tree.
Instance Method Summary collapse
-
#attribute_fixed?(name) ⇒ Boolean
True if given attribute name is defined as fixed.
- #copy_children_to(new_parent) ⇒ Object
-
#creator_name ⇒ Object
Returns the name of the creator of this page.
-
#editable_by?(user) ⇒ Boolean
Checks the current page’s list of editors, if defined.
-
#find_elements(options = {}, show_non_public = false) ⇒ ActiveRecord::Relation
Returns elements from page.
-
#first_public_child ⇒ Object
Returns the first published child.
-
#fixed_attributes ⇒ Object
Holds an instance of
FixedAttributes
. - #fold!(user_id, status) ⇒ Object
-
#get_language_root ⇒ Object
Gets the language_root page for page.
- #inherit_restricted_status ⇒ Object
-
#lock_to!(user) ⇒ Object
Locks the page to given user.
-
#locker_name ⇒ Object
Returns the name of the user currently editing this page.
-
#menus ⇒ Object
Menus (aka. root nodes) this page is attached to.
-
#next(options = {}) ⇒ Object
(also: #next_page)
Returns the next page on the same level or nil.
-
#previous(options = {}) ⇒ Object
(also: #previous_page)
Returns the previous page on the same level or nil.
-
#public_on ⇒ Object
Returns the value of
public_on
attribute. -
#public_until ⇒ Object
Returns the value of
public_until
attribute. -
#publish! ⇒ Object
Publishes the page.
- #set_restrictions_to_child_pages ⇒ Object
-
#to_partial_path ⇒ Object
The page’s view partial is dependent from its page layout.
-
#unlock! ⇒ Object
Unlocks the page without updating the timestamps.
-
#update_node!(node) ⇒ Object
Updates an Alchemy::Page based on a new ordering to be applied to it.
-
#updater_name ⇒ Object
Returns the name of the last updater of this page.
-
#url_path ⇒ Object
The url_path for this page.
Methods included from PageElements
#available_element_definitions, #available_element_names, #available_elements_within_current_scope, #descendent_element_definitions, #element_definition_names, #element_definitions, #element_definitions_by_name, #feed_elements, #richtext_contents_ids
Methods included from PageNaming
#external_urlname, #renamed?, #slug, #update_urlname!, #visible_ancestors
Methods included from NameConversions
#convert_to_humanized_name, #convert_to_urlname
Methods included from PageNatures
#cache_key, #cache_page?, #contains_feed?, #controller_and_action, #definition, #editor_roles, #expiration_time, #folded?, #has_controller?, #has_limited_editors?, #layout_display_name, #layout_partial_name, #locked?, #public?, #published_at, #redirects_to_external?, #rootpage?, #status, #status_title, #systempage?, #taggable?
Methods included from Taggable
Methods included from Logger
Methods included from Hints
Methods inherited from BaseRecord
Instance Attribute Details
#menu_id ⇒ Object
Returns the value of attribute menu_id.
162 163 164 |
# File 'app/models/alchemy/page.rb', line 162 def @menu_id end |
Class Method Details
.all_from_clipboard(clipboard) ⇒ Object
255 256 257 258 |
# File 'app/models/alchemy/page.rb', line 255 def all_from_clipboard(clipboard) return [] if clipboard.blank? where(id: clipboard.collect { |p| p['id'] }) end |
.all_from_clipboard_for_select(clipboard, language_id, layoutpage = false) ⇒ Object
260 261 262 263 264 265 266 |
# File 'app/models/alchemy/page.rb', line 260 def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false) return [] if clipboard.blank? clipboard_pages = all_from_clipboard(clipboard) allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage) allowed_page_layout_names = allowed_page_layouts.collect { |p| p['name'] } clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) } end |
.ancestors_for(current) ⇒ Object
Returns an array of all pages in the same branch from current. I.e. used to find the active page in navigation.
280 281 282 283 |
# File 'app/models/alchemy/page.rb', line 280 def ancestors_for(current) return [] if current.nil? current.self_and_ancestors.contentpages end |
.copy(source, differences = {}) ⇒ Alchemy::Page
Creates a copy of given source.
Also copies all elements included in source.
Note:
It prevents the element auto generator from running.
216 217 218 219 220 221 222 223 |
# File 'app/models/alchemy/page.rb', line 216 def copy(source, differences = {}) page = Alchemy::Page.new(attributes_from_source_for_copy(source, differences)) page.tag_list = source.tag_list if page.save! copy_elements(source, page) page end end |
.copy_and_paste(source, new_parent, new_name) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'app/models/alchemy/page.rb', line 242 def copy_and_paste(source, new_parent, new_name) page = copy(source, { parent_id: new_parent.id, language: new_parent.language, name: new_name, title: new_name }) if source.children.any? source.copy_children_to(page) end page end |
.current_preview ⇒ Object
Returns the current page previewed in the edit page template.
190 191 192 |
# File 'app/models/alchemy/page.rb', line 190 def current_preview RequestStore.store[:alchemy_current_preview] end |
.current_preview=(page) ⇒ Object
Used to store the current page previewed in the edit page template.
184 185 186 |
# File 'app/models/alchemy/page.rb', line 184 def current_preview=(page) RequestStore.store[:alchemy_current_preview] = page end |
.find_or_create_layout_root_for(language_id) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'app/models/alchemy/page.rb', line 229 def find_or_create_layout_root_for(language_id) layoutroot = layout_root_for(language_id) return layoutroot if layoutroot language = Language.find(language_id) Page.create!( name: "Layoutroot for #{language.name}", layoutpage: true, language: language, autogenerate_elements: false, parent_id: Page.root.id ) end |
.language_root_for(language_id) ⇒ Object
Returns the language root page for given language id.
197 198 199 |
# File 'app/models/alchemy/page.rb', line 197 def language_root_for(language_id) language_roots.find_by_language_id(language_id) end |
.layout_root_for(language_id) ⇒ Object
225 226 227 |
# File 'app/models/alchemy/page.rb', line 225 def layout_root_for(language_id) where({parent_id: Page.root.id, layoutpage: true, language_id: language_id}).limit(1).first end |
.link_target_options ⇒ Object
268 269 270 271 272 273 274 275 276 |
# File 'app/models/alchemy/page.rb', line 268 def = [[Alchemy.t(:default, scope: 'link_target_options'), '']] = Config.get(:link_target_options) .each do |option| << [Alchemy.t(option, scope: 'link_target_options', default: option.to_s.humanize), option] end end |
.root ⇒ Object Also known as: rootpage
The root page of the page tree
Internal use only. You wouldn’t use this page ever.
Automatically created when accessed the first time.
177 178 179 |
# File 'app/models/alchemy/page.rb', line 177 def root super || create!(name: 'Root') end |
Instance Method Details
#attribute_fixed?(name) ⇒ Boolean
True if given attribute name is defined as fixed
498 499 500 |
# File 'app/models/alchemy/page.rb', line 498 def attribute_fixed?(name) fixed_attributes.fixed?(name) end |
#copy_children_to(new_parent) ⇒ Object
445 446 447 448 449 450 451 452 453 454 455 |
# File 'app/models/alchemy/page.rb', line 445 def copy_children_to(new_parent) children.each do |child| next if child == new_parent new_child = Page.copy(child, { language_id: new_parent.language_id, language_code: new_parent.language_code }) new_child.move_to_child_of(new_parent) child.copy_children_to(new_child) unless child.children.blank? end end |
#creator_name ⇒ Object
Returns the name of the creator of this page.
If no creator could be found or associated user model does not respond to #name
it returns ‘unknown’
533 534 535 |
# File 'app/models/alchemy/page.rb', line 533 def creator_name creator.try(:name) || Alchemy.t('unknown') end |
#editable_by?(user) ⇒ Boolean
Checks the current page’s list of editors, if defined.
This allows us to pass in a user and see if any of their roles are enable them to make edits
507 508 509 510 |
# File 'app/models/alchemy/page.rb', line 507 def editable_by?(user) return true unless has_limited_editors? (editor_roles & user.alchemy_roles).any? end |
#find_elements(options = {}, show_non_public = false) ⇒ ActiveRecord::Relation
Returns elements from page.
343 344 345 346 347 348 349 350 351 352 |
# File 'app/models/alchemy/page.rb', line 343 def find_elements( = {}, show_non_public = false) if show_non_public Alchemy::Deprecation.warn "Passing true as second argument to page#find_elements to include" \ " invisible elements has been removed. Please implement your own ElementsFinder" \ " and pass it with options[:finder]." end finder = [:finder] || Alchemy::ElementsFinder.new() finder.elements(page: self) end |
#first_public_child ⇒ Object
Returns the first published child
436 437 438 |
# File 'app/models/alchemy/page.rb', line 436 def first_public_child children.published.first end |
#fixed_attributes ⇒ Object
Holds an instance of FixedAttributes
493 494 495 |
# File 'app/models/alchemy/page.rb', line 493 def fixed_attributes @_fixed_attributes ||= Alchemy::Page::FixedAttributes.new(self) end |
#fold!(user_id, status) ⇒ Object
419 420 421 422 423 |
# File 'app/models/alchemy/page.rb', line 419 def fold!(user_id, status) folded_page = folded_pages.find_or_create_by(user_id: user_id) folded_page.folded = status folded_page.save! end |
#get_language_root ⇒ Object
Gets the language_root page for page
441 442 443 |
# File 'app/models/alchemy/page.rb', line 441 def get_language_root self_and_ancestors.find_by(language_root: true) end |
#inherit_restricted_status ⇒ Object
431 432 433 |
# File 'app/models/alchemy/page.rb', line 431 def inherit_restricted_status self.restricted = parent.restricted? end |
#lock_to!(user) ⇒ Object
Locks the page to given user
407 408 409 |
# File 'app/models/alchemy/page.rb', line 407 def lock_to!(user) update_columns(locked_at: Time.current, locked_by: user.id) end |
#locker_name ⇒ Object
Returns the name of the user currently editing this page.
If no locker could be found or associated user model does not respond to #name
it returns ‘unknown’
551 552 553 |
# File 'app/models/alchemy/page.rb', line 551 def locker_name locker.try(:name) || Alchemy.t('unknown') end |
#menus ⇒ Object
Menus (aka. root nodes) this page is attached to
557 558 559 |
# File 'app/models/alchemy/page.rb', line 557 def @_menus ||= nodes.map(&:root) end |
#next(options = {}) ⇒ Object Also known as: next_page
Returns the next page on the same level or nil.
399 400 401 402 |
# File 'app/models/alchemy/page.rb', line 399 def next( = {}) pages = self_and_siblings.where('lft > ?', lft) select_page(pages, .merge(order: :asc)) end |
#previous(options = {}) ⇒ Object Also known as: previous_page
Returns the previous page on the same level or nil.
386 387 388 389 |
# File 'app/models/alchemy/page.rb', line 386 def previous( = {}) pages = self_and_siblings.where('lft < ?', lft) select_page(pages, .merge(order: :desc)) end |
#public_on ⇒ Object
Returns the value of public_on
attribute
If it’s a fixed attribute then the fixed value is returned instead
516 517 518 |
# File 'app/models/alchemy/page.rb', line 516 def public_on attribute_fixed?(:public_on) ? fixed_attributes[:public_on] : self[:public_on] end |
#public_until ⇒ Object
Returns the value of public_until
attribute
If it’s a fixed attribute then the fixed value is returned instead
524 525 526 |
# File 'app/models/alchemy/page.rb', line 524 def public_until attribute_fixed?(:public_until) ? fixed_attributes[:public_until] : self[:public_until] end |
#publish! ⇒ Object
Publishes the page.
Sets public_on
and the published_at
value to current time and resets public_until
to nil
The published_at
attribute is used as cache_key
.
464 465 466 467 468 469 470 471 |
# File 'app/models/alchemy/page.rb', line 464 def publish! current_time = Time.current update_columns( published_at: current_time, public_on: already_public_for?(current_time) ? public_on : current_time, public_until: still_public_for?(current_time) ? public_until : nil ) end |
#set_restrictions_to_child_pages ⇒ Object
425 426 427 428 429 |
# File 'app/models/alchemy/page.rb', line 425 def set_restrictions_to_child_pages descendants.each do |child| child.update(restricted: restricted?) end end |
#to_partial_path ⇒ Object
The page’s view partial is dependent from its page layout
Define page layouts
Page layouts are defined in the config/alchemy/page_layouts.yml
file
- name: contact
elements: [contactform]
...
Override the view
Page layout partials live in app/views/alchemy/page_layouts
375 376 377 |
# File 'app/models/alchemy/page.rb', line 375 def to_partial_path "alchemy/page_layouts/#{layout_partial_name}" end |
#unlock! ⇒ Object
Unlocks the page without updating the timestamps
413 414 415 416 417 |
# File 'app/models/alchemy/page.rb', line 413 def unlock! if update_columns(locked_at: nil, locked_by: nil) Page.current_preview = nil end end |
#update_node!(node) ⇒ Object
Updates an Alchemy::Page based on a new ordering to be applied to it
Note: Page’s urls should not be updated (and a legacy URL created) if nesting is OFF or if a page is external or if the URL is the same
481 482 483 484 485 486 487 488 489 490 |
# File 'app/models/alchemy/page.rb', line 481 def update_node!(node) hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted} if Config.get(:url_nesting) && !definition['redirects_to_external'] && urlname != node.url LegacyPageUrl.create(page_id: id, urlname: urlname) hash[:urlname] = node.url end update_columns(hash) end |