module Pageflow # Describes a type of file that can be managed in the editor and # used in revisions. class FileType class NotFoundError < RuntimeError end # Path of a partial rendered in the json representation of the # file in both the editor and published entries # @return {String} attr_reader :partial # Path of a partial rendered in the json representation of the # file inside the editor. # @return {String} attr_reader :editor_partial # File types that are allowed to be nested inside the file # @return {Array} attr_reader :nested_file_types # Is this file type used in situations where it is not nested into # another file type? # @return {Boolean} attr_reader :top_level_type # Callable that receives a file record and returns a hash of one # of the following forms: # # { # poster: "url/of/image" # } # # where `poster` is an arbitrary css class infix. Use `default` to # skip the infix in the generated css class name. Or # # { # poster: { # desktop: "desktop/url/of/image", # mobile: "mobile/url/of/image" # } # } # # to provide different urls for the two media breakpoints. # # @return [#call] attr_reader :css_background_image_urls # Callable that returns a hash of url template strings indexed by # their names. # @return [#call] attr_reader :url_templates # @api private attr_reader :custom_attributes # Create file type to be returned in {PageType#file_types}. # # @example # # Pageflow::FileType.new(model: Pageflow::Rainbow::File, # editor_partial: 'pageflow/rainbow/editor/files/file') # # @param [Hash] options # @option options [ActiveRecord::Base, String] :model # Required. Model representing the file, or name of that model. # @option options [String] :partial # Optional. Path of a partial to include in json representations # of the file both inside the editor and published entries. # @option options [String] :editor_partial # Optional. Path of a partial to include in json representations # of the file inside the editor. # @option options [String] :collection_name Optional. String to # be used in routes. Defaults to `"pageflow_rainbow_file"` for # model `Pageflow::Rainbow::File`. # @option options [Array] :nested_file_types # Optional. Array of FileTypes allowed for nested files. Defaults to []. # @option options [#call] :css_background_image_urls # Optional. See {#css_background_image_urls} # @option options [#call] :url_templates # Optional. Callable returning a hash of url template strings # indexed by their names. # @option options [Array] :custom_attributes # Optional. Array of strings containing attribute names that are # custom to this file type def initialize(options) @model_string_or_reference = options.fetch(:model) @partial = options[:partial] @editor_partial = options[:editor_partial] @collection_name_or_blank = options[:collection_name] @nested_file_types = options.fetch(:nested_file_types, []) @top_level_type = options.fetch(:top_level_type, false) @css_background_image_urls = options[:css_background_image_urls] @css_background_image_class_prefix = options[:css_background_image_class_prefix] @url_templates = options.fetch(:url_templates, -> { {} }) @custom_attributes = convert_custom_attributes_option(options[:custom_attributes]) end # ActiveRecord model that represents the files of this type. # @return {ActiveRecord::Model} def model @model ||= if @model_string_or_reference.is_a?(String) @model_string_or_reference.constantize else @model_string_or_reference end end # Underscored plural name for usage in routes. # @return {String} def collection_name if @collection_name_or_blank.blank? model.model_name.plural else @collection_name_or_blank end end # @api private def css_background_image_class_prefix @css_background_image_class_prefix || model.model_name.singular end # @api private def param_key model.model_name.param_key.to_sym end # @api private alias_method :short_name, :param_key # @api private def type_name model.name end # @api private def i18n_key model.model_name.i18n_key end private def convert_custom_attributes_option(custom_attributes) if custom_attributes.is_a?(Array) custom_attributes.each_with_object({}) do |attribute_name, result| result[attribute_name] = {permitted_create_param: true} end elsif custom_attributes.is_a?(Hash) custom_attributes else {} end end end end