Class: Refinery::Page

Inherits:
Core::BaseModel show all
Extended by:
FriendlyId
Defined in:
pages/app/models/refinery/page.rb

Defined Under Namespace

Classes: Translation

Constant Summary

PATH_SEPARATOR =

when collecting the pages path how is each of the pages seperated?

" - "

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (Object) locale

to hold temporarily



31
32
33
# File 'pages/app/models/refinery/page.rb', line 31

def locale
  @locale
end

Class Method Details

+ (Object) by_slug(slug, conditions = {})

Finds a page using its slug. See by_title



108
109
110
111
# File 'pages/app/models/refinery/page.rb', line 108

def by_slug(slug, conditions={})
  locales = Refinery.i18n_enabled? ? Refinery::I18n.frontend_locales : ::I18n.locale
  with_globalize({ :locale => locales, :slug => slug }.merge(conditions))
end

+ (Object) by_title(title)

Finds a page using its title. This method is necessary because pages are translated which means the title attribute does not exist on the pages table thus requiring us to find the attribute on the translations table and then join to the pages table again to return the associated record.



103
104
105
# File 'pages/app/models/refinery/page.rb', line 103

def by_title(title)
  with_globalize(:title => title)
end

+ (Boolean) different_frontend_locale?

Wraps up all the checks that we need to do to figure out whether the current frontend locale is different to the current one set by ::I18n.locale. This terminates in a false if i18n extension is not defined or enabled.

Returns:

  • (Boolean)


141
142
143
# File 'pages/app/models/refinery/page.rb', line 141

def different_frontend_locale?
  ::Refinery.i18n_enabled? && ::Refinery::I18n.current_frontend_locale != ::I18n.locale
end

+ (Object) expire_page_caching



150
151
152
153
154
155
156
157
158
159
# File 'pages/app/models/refinery/page.rb', line 150

def expire_page_caching
  begin
    Rails.cache.delete_matched(/.*pages.*/)
  rescue NotImplementedError
    Rails.cache.clear
    warn "**** [REFINERY] The cache store you are using is not compatible with Rails.cache#delete_matched - clearing entire cache instead ***"
  ensure
    return true # so that other callbacks process.
  end
end

+ (Object) fast_menu



121
122
123
# File 'pages/app/models/refinery/page.rb', line 121

def fast_menu
  live.in_menu.order('lft ASC').includes(:translations)
end

+ (Object) find_by_path(path)

With slugs scoped to the parent page we need to find a page by its full path. For example with about/example we would need to find 'about' and then its child called 'example' otherwise it may clash with another page called /example.



76
77
78
79
80
81
82
# File 'pages/app/models/refinery/page.rb', line 76

def find_by_path(path)
  split_path = path.to_s.split('/').reject(&:blank?)
  page = ::Refinery::Page.by_slug(split_path.shift, :parent_id => nil).first
  page = page.children.by_slug(split_path.shift).first until page.nil? || split_path.empty?

  page
end

+ (Object) find_by_path_or_id(path, id)

Helps to resolve the situation where you have a path and an id and if the path is unfriendly then a different finder method is required than find_by_path.



87
88
89
90
91
92
93
94
95
96
97
# File 'pages/app/models/refinery/page.rb', line 87

def find_by_path_or_id(path, id)
  if Refinery::Pages.marketable_urls && path.present?
    if path.friendly_id?
      find_by_path(path)
    else
      find(path)
    end
  elsif id.present?
    find(id)
  end
end

+ (Object) in_menu

Shows all pages with :show_in_menu set to true, but it also rejects any page that has not been translated to the current locale. This works using a query against the translated content first and then using all of the page_ids we further filter against this model's table.



117
118
119
# File 'pages/app/models/refinery/page.rb', line 117

def in_menu
  where(:show_in_menu => true).with_globalize
end

+ (Object) live

Live pages are 'allowed' to be shown in the frontend of your website. By default, this is all pages that are not set as 'draft'.



69
70
71
# File 'pages/app/models/refinery/page.rb', line 69

def live
  where(:draft => false)
end

+ (Object) per_page(dialog = false)

Returns how many pages per page should there be when paginating pages



146
147
148
# File 'pages/app/models/refinery/page.rb', line 146

def per_page(dialog = false)
  dialog ? Pages.pages_per_dialog : Pages.config.pages_per_admin_index
end

+ (Object) with_globalize(conditions = {})

Wrap up the logic of finding the pages based on the translations table.



126
127
128
129
130
131
132
133
134
135
136
# File 'pages/app/models/refinery/page.rb', line 126

def with_globalize(conditions = {})
  conditions = {:locale => ::Globalize.locale}.merge(conditions)
  globalized_conditions = {}
  conditions.keys.each do |key|
    if (translated_attribute_names.map(&:to_s) | %w(locale)).include?(key.to_s)
      globalized_conditions["#{self.translation_class.table_name}.#{key}"] = conditions.delete(key)
    end
  end
  # A join implies readonly which we don't really want.
  joins(:translations).where(globalized_conditions).where(conditions).readonly(false)
end

Instance Method Details

- (Object) all_page_part_content

Used to index all the content on this page so it can be easily searched.



410
411
412
# File 'pages/app/models/refinery/page.rb', line 410

def all_page_part_content
  parts.map(&:body).join(" ")
end

- (Object) cache_key(locale)



311
312
313
# File 'pages/app/models/refinery/page.rb', line 311

def cache_key(locale)
  [Refinery::Core.base_cache_key, 'page', locale, id].compact.join('/')
end

- (Object) content_for(part_title)

Accessor method to get a page part from a page. Example:

::Refinery::Page.first.content_for(:body)

Will return the body page part of the first page.



374
375
376
# File 'pages/app/models/refinery/page.rb', line 374

def content_for(part_title)
  part_with_title(part_title).try(:body)
end

- (Boolean) content_for?(part_title)

Accessor method to test whether a page part exists and has content for this page. Example:

::Refinery::Page.first.content_for?(:body)

Will return true if the page has a body page part and it is not blank.

Returns:

  • (Boolean)


364
365
366
# File 'pages/app/models/refinery/page.rb', line 364

def content_for?(part_title)
  content_for(part_title).present?
end

- (Object) custom_slug_or_title

Returns in cascading order: custom_slug or menu_title or title depending on which attribute is first found to be present for this page.



164
165
166
167
168
169
170
171
172
# File 'pages/app/models/refinery/page.rb', line 164

def custom_slug_or_title
  if custom_slug.present?
    custom_slug
  elsif menu_title.present?
    menu_title
  else
    title
  end
end

- (Boolean) deletable?

Am I allowed to delete this page? If a link_url is set we don't want to break the link so we don't allow them to delete If deletable is set to false then we don't allow this page to be deleted. These are often Refinery system pages

Returns:

  • (Boolean)


177
178
179
# File 'pages/app/models/refinery/page.rb', line 177

def deletable?
  deletable && link_url.blank? and menu_match.blank?
end

- (Object) destroy

Before destroying a page we check to see if it's a deletable page or not Refinery system pages are not deletable.



191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'pages/app/models/refinery/page.rb', line 191

def destroy
  return super if deletable?

  unless Rails.env.test?
    # give useful feedback when trying to delete from console
    puts "This page is not deletable. Please use .destroy! if you really want it deleted "
    puts "unset .link_url," if link_url.present?
    puts "unset .menu_match," if menu_match.present?
    puts "set .deletable to true" unless deletable
  end

  false
end

- (Object) destroy!

If you want to destroy a page that is set to be not deletable this is the way to do it.



206
207
208
209
210
211
212
# File 'pages/app/models/refinery/page.rb', line 206

def destroy!
  self.menu_match = nil
  self.link_url = nil
  self.deletable = true

  destroy
end

- (Boolean) home?

Returns true if this page is the home page or links to it.

Returns:

  • (Boolean)


331
332
333
# File 'pages/app/models/refinery/page.rb', line 331

def home?
  link_url == '/'
end

- (Boolean) in_menu?

Return true if this page can be shown in the navigation. If it's a draft or is set to not show in the menu it will return false.

Returns:

  • (Boolean)


322
323
324
# File 'pages/app/models/refinery/page.rb', line 322

def in_menu?
  live? && show_in_menu?
end

Adds the locale key into the URI for this page's link_url attribute, unless the current locale is set as the default locale.

Returns:

  • (Boolean)


248
249
250
251
252
253
254
255
256
257
258
# File 'pages/app/models/refinery/page.rb', line 248

def link_url_localised?
  return link_url unless ::Refinery.i18n_enabled?

  current_url = link_url

  if current_url =~ %r{^/} && ::Refinery::I18n.current_frontend_locale != ::Refinery::I18n.default_frontend_locale
    current_url = "/#{::Refinery::I18n.current_frontend_locale}#{current_url}"
  end

  current_url
end

- (Boolean) live?

Returns true if this page is "published"

Returns:

  • (Boolean)


316
317
318
# File 'pages/app/models/refinery/page.rb', line 316

def live?
  not draft?
end

- (Object) nested_path

Returns the string version of nested_url, i.e., the path that should be generated by the router



299
300
301
# File 'pages/app/models/refinery/page.rb', line 299

def nested_path
  Rails.cache.fetch(path_cache_key) { ['', nested_url].join('/') }
end

- (Object) nested_url

Returns an array with all ancestors to_param, allow with its own Ex: with an About page and a Mission underneath, ::Refinery::Page.find('mission').nested_url would return:

['about', 'mission']


289
290
291
# File 'pages/app/models/refinery/page.rb', line 289

def nested_url
  Rails.cache.fetch(url_cache_key) { uncached_nested_url }
end

- (Object) normalize_friendly_id_with_marketable_urls(slug_string)

Protects generated slugs from title if they are in the list of reserved words This applies mostly to plugin-generated pages. This only kicks in when Refinery::Pages.marketable_urls is enabled.

Returns the sluggified string



420
421
422
423
424
425
426
# File 'pages/app/models/refinery/page.rb', line 420

def normalize_friendly_id_with_marketable_urls(slug_string)
  sluggified = slug_string.to_slug.normalize!
  if Refinery::Pages.marketable_urls && self.class.friendly_id_config.reserved_words.include?(sluggified)
    sluggified << "-page"
  end
  sluggified
end

- (Boolean) not_in_menu?

Returns:

  • (Boolean)


326
327
328
# File 'pages/app/models/refinery/page.rb', line 326

def not_in_menu?
  not in_menu?
end

- (Object) part_with_title(part_title)

Accessor method to get a page part object from a page. Example:

::Refinery::Page.first.part_with_title(:body)

Will return the Refinery::PagePart object with that title using the first page.



384
385
386
387
388
389
390
391
392
# File 'pages/app/models/refinery/page.rb', line 384

def part_with_title(part_title)
  # self.parts is usually already eager loaded so we can now just grab
  # the first element matching the title we specified.
  self.parts.detect do |part|
    part.title.present? and # protecting against the problem that occurs when have nil title
    part.title == part_title.to_s or
    part.title.downcase.gsub(" ", "_") == part_title.to_s.downcase.gsub(" ", "_")
  end
end

- (Object) path(options = {})

Used for the browser title to get the full path to this page It automatically prints out this page title and all of it's parent page titles joined by a PATH_SEPARATOR



216
217
218
219
220
221
222
223
224
225
226
227
# File 'pages/app/models/refinery/page.rb', line 216

def path(options = {})
  # Override default options with any supplied.
  options = {:reversed => true}.merge(options)

  unless parent_id.nil?
    parts = [title, parent.path(options)]
    parts.reverse! if options[:reversed]
    parts.join(PATH_SEPARATOR)
  else
    title
  end
end

- (Object) path_cache_key(locale = Globalize.locale)



303
304
305
# File 'pages/app/models/refinery/page.rb', line 303

def path_cache_key(locale = Globalize.locale)
  [cache_key(locale), 'nested_path'].join('#')
end

- (Object) refinery_menu_title



340
341
342
# File 'pages/app/models/refinery/page.rb', line 340

def refinery_menu_title
  [menu_title, title].detect(&:present?)
end

- (Object) reposition_parts!

Repositions the child page_parts that belong to this page. This ensures that they are in the correct 0,1,2,3,4... etc order.



183
184
185
186
187
# File 'pages/app/models/refinery/page.rb', line 183

def reposition_parts!
  reload.parts.each_with_index do |part, index|
    part.update_attribute(:position, index)
  end
end

- (Object) shown_siblings

Returns all visible sibling pages that can be rendered for the menu



336
337
338
# File 'pages/app/models/refinery/page.rb', line 336

def shown_siblings
  siblings.reject(&:not_in_menu?)
end

- (Object) title_with_meta

In the admin area we use a slightly different title to inform the which pages are draft or hidden pages We show the title from the next available locale if there is no title for the current locale



396
397
398
399
400
401
402
403
404
405
406
407
# File 'pages/app/models/refinery/page.rb', line 396

def title_with_meta
  if self.title.present?
    title = [self.title]
  else
    title = [self.translations.detect {|t| t.title.present?}.title]
  end

  title << "<span class='label'>#{::I18n.t('hidden', :scope => 'refinery.admin.pages.page')}</span>" unless show_in_menu?
  title << "<span class='label notice'>#{::I18n.t('draft', :scope => 'refinery.admin.pages.page')}</span>" if draft?

  title.join(' ')
end

- (Object) to_refinery_menu_item



344
345
346
347
348
349
350
351
352
353
354
355
# File 'pages/app/models/refinery/page.rb', line 344

def to_refinery_menu_item
  {
    :id => id,
    :lft => lft,
    :menu_match => menu_match,
    :parent_id => parent_id,
    :rgt => rgt,
    :title => refinery_menu_title,
    :type => self.class.name,
    :url => url
  }
end

- (Object) uncached_nested_url



293
294
295
# File 'pages/app/models/refinery/page.rb', line 293

def uncached_nested_url
  [parent.try(:nested_url), to_param.to_s].compact.flatten
end

- (Object) url

When this page is rendered in the navigation, where should it link? If a custom "link_url" is set, it uses that otherwise it defaults to a normal page URL. The "link_url" is often used to link to a plugin rather than a page.

For example if I had a "Contact" page I don't want it to just render a contact us page I want it to show the Inquiries form so I can collect inquiries. So I would set the "link_url" to "/contact"



236
237
238
239
240
241
242
243
244
# File 'pages/app/models/refinery/page.rb', line 236

def url
  if link_url.present?
    link_url_localised?
  elsif Refinery::Pages.marketable_urls
    with_locale_param url_marketable
  elsif to_param.present?
    with_locale_param url_normal
  end
end

- (Object) url_cache_key(locale = Globalize.locale)



307
308
309
# File 'pages/app/models/refinery/page.rb', line 307

def url_cache_key(locale = Globalize.locale)
  [cache_key(locale), 'nested_url'].join('#')
end

- (Object) url_marketable

Add 'marketable url' attributes into this page's url. This sets 'path' as the nested_url value and sets 'id' to nil. For example, this might evaluate to /about for the "About" page.



263
264
265
266
# File 'pages/app/models/refinery/page.rb', line 263

def url_marketable
  # :id => nil is important to prevent any other params[:id] from interfering with this route.
  url_normal.merge(:path => nested_url, :id => nil)
end

- (Object) url_normal

Returns a url suitable to be used in url_for in Rails (such as link_to). For example, this might evaluate to /pages/about for the "About" page.



270
271
272
# File 'pages/app/models/refinery/page.rb', line 270

def url_normal
  {:controller => '/refinery/pages', :action => 'show', :path => nil, :id => to_param, :only_path => true}
end

- (Object) with_locale_param(url_hash)

If the current locale is set to something other than the default locale then the :locale attribute will be set on the url hash, otherwise it won't be.



276
277
278
279
280
281
# File 'pages/app/models/refinery/page.rb', line 276

def with_locale_param(url_hash)
  if self.class.different_frontend_locale?
    url_hash.update(:locale => ::Refinery::I18n.current_frontend_locale)
  end
  url_hash
end