# frozen_string_literal: true # PageTitleHelper provides an +ActionView+ helper method to simplify adding # custom titles to pages. # # Author:: Lukas Westermann # Copyright:: Copyright (c) 2009 Lukas Westermann (Zurich, Switzerland) # Licence:: MIT-Licence (https://www.opensource.org/licenses/mit-license.php) # # See documentation for +page_title+ for usage examples and more information. require 'active_support' # PageTitleHelper module PageTitleHelper # https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/interpolations.rb module Interpolations extend self def self.interpolate(pattern, *args) instance_methods(false).sort.reverse.inject(pattern.to_s.dup) do |result, tag| result.gsub(/:#{tag}/) do |_match| send(tag, *args) end end end def app(env) env[:app] || I18n.t('app.name', default: File.basename(Rails.root).humanize) end def title(env) env[:title] end end # Add new, custom, interpolation. def self.interpolates(key, &) Interpolations.send(:define_method, key, &) end # Default options, which are globally referenced and can # be changed globally, which might be useful in some cases. def self.options @options ||= { format: :default, default: :'app.tagline' } end # Defined alias formats, pretty useful. def self.formats @formats ||= { app: ':app', default: ':title - :app', title: ':title' } end # Specify page title def page_title!(*args) @_page_title = args.size > 1 ? args : args.first @_page_title.is_a?(Array) ? @_page_title.first : @_page_title end def page_title(options = nil) return page_title!(yield) if block_given? # define title options = PageTitleHelper.options.merge(options || {}).symbolize_keys! options[:format] ||= :title # handles :format => false options.assert_valid_keys(:app, :default, :format) format, real_title = build_title_and_format(options) # handle format aliases format = PageTitleHelper.formats[format] if PageTitleHelper.formats.include?(format) # construct basic env to pass around env = { title: real_title, app: options[:app], options:, view: self } # interpolate format Interpolations.interpolate(format, env) end protected # Find translation for `controller.action.title` combination, falls back to # `controller.title` or supplied default if no title was found. def page_title_from_translation(default) base = controller.controller_path.tr('/', '.') action = params[:action].to_s keys = [:"#{base}.#{action}.title"] keys << :"#{base}.new.title" if action == 'create' keys << :"#{base}.edit.title" if action == 'update' keys << :"#{base}.title" keys << default I18n.t(keys.shift, default: keys) end private ## # Read the page title and splits it into 'real' title and the customized # format. # # @param {Hash} options # # @return {Array} # def build_title_and_format(options) raw_title = @_page_title ||= page_title_from_translation(options[:default]) if raw_title.is_a?(Array) title_and_format = raw_title + [options[:format]] real_title, format = *title_and_format else real_title = raw_title format = options[:format] end [format, real_title] end end # include helper methods in ActionView ActiveSupport.on_load(:action_view) { include PageTitleHelper }