module Metaslug::ActionControllerExtension

Public Class Methods

metaslug_vars(*args) click to toggle source
# File lib/metaslug/controllers/action_controller_extension.rb, line 146
def self.metaslug_vars(*args)
  before_filter args.extract_options! do
    @metaslug_vars = args
  end
end

Public Instance Methods

initialize_metas_storage() click to toggle source

Initialize storage to an empty hash, unless already set.

@return [Hash] [Global metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 131
def initialize_metas_storage
  Thread.current[:metas] ||= {}
end
load_all_metas() click to toggle source

A locale corresponds to a YAML file. We load each YAML file individually then merge then into a global hash.

@return [Hash] [Global hash with all metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 23
def load_all_metas
  Thread.current[:metas] = I18n.available_locales.inject({}) do |acc, locale|
    acc.merge!(load_metas_for_locale(locale))
    acc
  end
end
load_metas_for_current_slug() click to toggle source

Initialise the traduction hash, load every metas into it. We only do this once, unless it is the development environment.

@return [void] [Load metas of the current page]

# File lib/metaslug/controllers/action_controller_extension.rb, line 11
def load_metas_for_current_slug
  # initialize storage to an empty Hash, unless already exists
  initialize_metas_storage
  load_all_metas if Rails.env.development? or metas_storage.empty?
  set_metas_for_current_path
end
load_metas_for_locale(locale) click to toggle source

Load a YAML file corresponding to a locale after ensuring it exists. @param locale [Symbol] [Locale]

@return [Hash] [Metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 35
def load_metas_for_locale(locale)
  path = metas_path(locale)
  if File.exists?(path)
    YAML.load(File.open(path))
  else
    logger.error "[Metaslug] #{path} not found."
    {}
  end
end
locale_metas_storage(locale = I18n.locale) click to toggle source

Metas of the given locale @param locale = I18n.locale [Symbol] [Locale]

@return [Hash] [Metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 114
def locale_metas_storage(locale = I18n.locale)
  metas_storage[I18n.locale.to_s]
end
metas_path(locale) click to toggle source

Return path of the YAML file of this locale. @param locale [Symbol] [Locale]

@return [Pathname] [Path of the YAML file]

# File lib/metaslug/controllers/action_controller_extension.rb, line 104
def metas_path(locale)
  # TODO: Let user configure it.
  Rails.root.join('config', 'metaslug', "#{locale}.yml")
end
metas_storage() click to toggle source

Backend storage of the metas. We store it in the current thread to avoid reloading it.

@return [Hash] [Global metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 123
def metas_storage
  Thread.current[:metas]
end
render(*args) click to toggle source

Overriding the default render method because we need to use the action variables to render the liquid template. This had to be done after the action and before the render. @param *args [Array] [Default arguments]

@return [type] [description]

Calls superclass method
# File lib/metaslug/controllers/action_controller_extension.rb, line 159
def render(*args)
  load_metas_for_current_slug
  super
end
set_metas_for_current_path() click to toggle source

Search and load metas of the current path.

@return [void]

# File lib/metaslug/controllers/action_controller_extension.rb, line 49
def set_metas_for_current_path
  locale_metas_storage.keys.each do |k|
    if request.path.match(translate_key_into_regexp(k))
      set_metas_from_hash(locale_metas_storage[k].dup)
      return
    end
  end

  # if no key match the current path, load default metas if present.
  if locale_metas_storage.has_key?('default')
    set_metas_from_hash(locale_metas_storage['default'].dup)
  else
    set_metas_from_hash({})
  end
end
set_metas_from_hash(values) click to toggle source

Load metas into an instance variable to have access to them in the helper. Get the instance variables mark as accessible in the before_filter to interpolate values in the liquid template. @param values [Hash] [Metas]

@return [Hash] [Metas]

# File lib/metaslug/controllers/action_controller_extension.rb, line 72
def set_metas_from_hash(values)
  @metaslug_vars ||= []
  # For each meta we need to interpole the value if it use a dynamic content.
  values.each do |k ,v|
    if v.is_a?(Hash)
      # recursive call for nested hash like { 'og' => { 'locale' => { 'alternate' => 'fr_FR' } } }
      set_metas_from_hash(v)
    else
      # Looks like a liquid template
      if v =~ /{{.*}}/
        if @metaslug_vars.empty?
          Rails.logger.debug "You provide a template but don't set access to your vars in the associated controller."
          values[k] = v
        else
          template  = Liquid::Template.parse(v)
          h = @metaslug_vars.inject({}) do |acc, v|
            acc[v.to_s] = instance_variable_get("@#{v}")
            acc
          end
          values[k] = template.render(h)
        end
      end
    end
  end
  @metaslug = values
end
translate_key_into_regexp(k) click to toggle source

YAML entries may looks like routes, like /categories/:id/edit. To be able to test these entries, we convert them to regexp, replacing :id (and others sym) @param k [String] [key]

@return [Regexp] [Builded regexp]

# File lib/metaslug/controllers/action_controller_extension.rb, line 141
def translate_key_into_regexp(k)
  # replace :id with regular expression
  %r{^#{k.gsub /\:\w+/, '[a-z0-9_.-]+'}$}i
end