# frozen_string_literal: true require_relative "page_meta_for/version" require 'active_support' require 'action_controller' module PageMeta extend ::ActiveSupport::Concern included do initialize_meta helper_method :page_meta_for end module ClassMethods def initialize_meta before_action do @page_meta_for = {} end end # Controller level method to define the part of the meta tags # # class ApplicationController < ActionController::Base # meta_for(:title, :suffix, 'ApplicationName') # meta_for(:title, :prefix) { action_name } # meta_for(:description) { 'Lorem ipsum set' } # end # # class WelcomeController < ApplicationController # meta_for(:title) { 'Landing Page' } # meta_for(:description) { 'Lorem ipsum set2' } # end # # Then views and layouts are able to call `page_meta_for`: # # <%= page_meta_for(:title, join_string: ' * ') %> # # # It renders the following: # # Index * Landing Page * ApplicationName # # # If last argument is Hash, a appropriate method will be called # # class ApplicationController < ActionController::Base # meta_for(:title, :generate_title) # # private # # def generate_title # 'Application Name' # end # end # def meta_for(*keys, &block) content_proc = if block_given? block else c = args.pop c.is_a?(Hash) ? proc { send(c) } : proc { c } end keys = Array.wrap(keys).flatten key = keys.pop scope = keys.pop || :value before_action do @page_meta_for ||= {} @page_meta_for[scope] ||= {} @page_meta_for[scope][key] = instance_exec(&content_proc).presence || nil end end end def page_meta_for(key, scopes: [:prefix, :value, :suffix], join_string: " - ") @page_meta_for ||= {} scopes.map { |s| @page_meta_for.fetch(s, {}).fetch(key, nil) } .select(&:present?) .join(join_string) .presence end end ActionController::Base.include(PageMeta)