app/services/locomotive/page_service.rb
module Locomotive
class PageService < Struct.new(:site, :account, :locale)
include Locomotive::Concerns::ActivityService
# Create a page from the attributes passed in parameter.
# It sets the created_by column with the current account.
#
# @param [ Hash ] attributes The attributes of new page.
#
# @return [ Object ] An instance of the page.
#
def create(attributes)
site.pages.build(attributes).tap do |page|
page.created_by = account if account
if page.save
track_activity 'page.created', parameters: { title: page.title, _id: page._id }
end
end
end
def sort(page, children)
page.sort_children!(children).tap do
track_activity 'page.sorted', parameters: { title: page.title, _id: page._id }
end
end
# Update a page from the attributes passed in parameter.
# It sets the updated_by column with the current account.
#
# @param [ Object ] entry The page to update.
# @param [ Hash ] attributes The attributes of new page.
#
# @return [ Object ] The instance of the page.
#
def update(page, attributes)
page.tap do
page.attributes = attributes
page.updated_by = account if account
if page.save
track_activity 'page.updated', locale: locale, parameters: { title: page.title, _id: page._id }
end
end
end
def destroy(page)
page.destroy.tap do
track_activity 'page.destroyed', parameters: { title: page.title }
end
end
# For all the pages of a site, use the slug property from
# the default locale for all the new locales passed as the first argument.
# Do not erase existing values in the new locales.
# This method is called when an user has changed the locales of a site.
#
def localize(locales, previous_default_locale)
parent_fullpaths = {}
default_locale = previous_default_locale || site.default_locale
site.pages.without_sorting.order_by(:depth.asc).each_by(50) do |page|
_localize(page, locales, default_locale, parent_fullpaths)
page.skip_callbacks_on_update = true
page.save if page.changed?
end
end
private
def _localize(page, locales, default_locale, parent_fullpaths)
slug = page.slug_translations[default_locale]
locales.each do |locale|
next if locale == default_locale
::Mongoid::Fields::I18n.with_locale(locale) do
page.slug ||= slug
page.fullpath ||= page.depth > 1 ? parent_fullpaths[page.parent_id][locale] + '/' + slug : slug
page.raw_template ||= page.raw_template_translations[default_locale]
if page.depth == 0 && (slug == 'index' || slug == '404')
page.title ||= ::I18n.t("attributes.defaults.pages.#{slug}.title", locale: locale)
else
page.title ||= "#{page.title_translations[default_locale]} [#{locale.upcase}]"
end
(parent_fullpaths[page._id] ||= {})[locale] = page.fullpath
if page.redirect?
page.redirect_url ||= page.redirect_url_translations[default_locale]
end
# finally, take care of the sections (inside the dropzone and the others)
if page.sections_content.blank?
page.sections_content = page.sections_content_translations[default_locale] || {}
end
if page.sections_dropzone_content.blank?
page.sections_dropzone_content = page.sections_dropzone_content_translations[default_locale] || []
end
end
end
end
end
end