module Metaslug::ActionControllerExtension
Public Class Methods
# 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 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
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
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 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
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
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
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
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]
# File lib/metaslug/controllers/action_controller_extension.rb, line 159 def render(*args) load_metas_for_current_slug super end
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
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
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