class Hanami::Config

Hanami app config

@since 2.0.0

Constants

SUPPORTED_MIDDLEWARE_PARSERS

Attributes

actions[R]

Returns the app’s actions config, or a null config if hanami-controller is not bundled.

@example When hanami-controller is bundled

config.actions.default_request_format # => :html

@example When hanami-controller is not bundled

config.actions.default_request_format # => NoMethodError

@return [Hanami::Config::Actions, Hanami::Config::NullConfig]

@api public @since 2.0.0

app_name[R]

Returns the app or slice’s {Hanami::SliceName slice_name}.

This is useful for default config values that depend on this name.

@return [Hanami::SliceName]

@api private @since 2.0.0

assets[R]

Returns the app’s views config, or a null config if hanami-view is not bundled.

@example When hanami-view is bundled

config.views.paths # => [...]

@example When hanami-view is not bundled

config.views.paths # => NoMethodError

@return [Hanami::Config::Assets, Hanami::Config::NullConfig]

@api public @since 2.1.0

db[R]

Returns the app’s db config, or a null config if hanami-db is not bundled.

@example When hanami-db is bundled

config.db.import_from_parent # => false

@example When hanami-db is not bundle

config.db.import_from_parent # => NoMethodError

@return [Hanami::Config::DB, Hanami::Config::NullConfig]

@api public @since 2.2.0

env[R]

Returns the app’s environment.

@example

config.env # => :development

@return [Symbol]

@see environment

@api private @since 2.0.0

middleware[R]

Returns the app’s middleware stack, or nil if hanami-router is not bundled.

Use this to configure middleware that should apply to all routes.

@example

config.middleware.use :body_parser, :json
config.middleware.use MyCustomMiddleware

@return [Hanami::Slice::Routing::Middleware::Stack, nil]

@api public @since 2.0.0

middleware_stack[R]

Returns the app’s middleware stack, or nil if hanami-router is not bundled.

Use this to configure middleware that should apply to all routes.

@example

config.middleware.use :body_parser, :json
config.middleware.use MyCustomMiddleware

@return [Hanami::Slice::Routing::Middleware::Stack, nil]

@api public @since 2.0.0

router[R]

Returns the app’s router config, or a null config if hanami-router is not bundled.

@example When hanami-router is bundled

config.router.resolver # => Hanami::Slice::Routing::Resolver

@example When hanami-router is not bundled

config.router.resolver # => NoMethodError

@return [Hanami::Config::Router, Hanami::Config::NullConfig]

@api public @since 2.0.0

views[R]

Returns the app’s views config, or a null config if hanami-view is not bundled.

@example When hanami-view is bundled

config.views.paths # => [...]

@example When hanami-view is not bundled

config.views.paths # => NoMethodError

@return [Hanami::Config::Views, Hanami::Config::NullConfig]

@api public @since 2.1.0

Public Class Methods

new(app_name:, env:) { |self| ... } click to toggle source

@api private rubocop:disable Metrics/AbcSize

# File lib/hanami/config.rb, line 300
def initialize(app_name:, env:)
  @app_name = app_name
  @env = env

  # Apply default values that are only knowable at initialize-time (vs require-time)
  self.root = Dir.pwd
  self.render_errors = (env == :production)
  self.render_detailed_errors = (env == :development)
  load_from_env


  @actions = load_dependent_config("hanami-controller") {
    require_relative "config/actions"
    Actions.new
  }

  @assets = load_dependent_config("hanami-assets") {
    require_relative "config/assets"
    Hanami::Config::Assets.new
  }

  @db = load_dependent_config("hanami-db") { DB.new }

  @logger = Config::Logger.new(env: env, app_name: app_name)

  @middleware = load_dependent_config("hanami-router") {
    Slice::Routing::Middleware::Stack.new
  }

  @router = load_dependent_config("hanami-router") {
    require_relative "config/router"
    Router.new(self)
  }

  @views = load_dependent_config("hanami-view") {
    require_relative "config/views"
    Views.new
  }

  yield self if block_given?
end

Public Instance Methods

finalize!() click to toggle source

Finalizes the config.

This is called when the app or slice is prepared. After this, no further changes to config can be made.

@api private

Calls superclass method
# File lib/hanami/config.rb, line 367
def finalize!
  # Finalize nested configs
  assets.finalize!
  actions.finalize!(self)
  views.finalize!
  logger.finalize!
  router.finalize!

  use_body_parser_middleware

  super
end
inflections(&block) click to toggle source

Configures the app’s custom inflections.

You should call this one time only. Subsequent calls will override previously configured inflections.

@example

config.inflections do |inflections|
  inflections.acronym "WNBA"
end

@see dry-rb.org/gems/dry-inflector

@return [Dry::Inflector] the configured inflector

@api public @since 2.0.0

# File lib/hanami/config.rb, line 396
def inflections(&block)
  self.inflector = Dry::Inflector.new(&block)
end
logger() click to toggle source

Returns the logger config.

Use this to configure various options for the default ‘Dry::Logger::Dispatcher` logger instance.

@example

config.logger.level = :debug

@return [Hanami::Config::Logger]

@see Hanami::Config::Logger

@api public @since 2.0.0

# File lib/hanami/config.rb, line 417
def logger
  @logger
end
logger=(logger_instance) click to toggle source

Sets the app’s logger instance.

This entirely replaces the default ‘Dry::Logger::Dispatcher` instance that would have been

@see logger_instance

@api public @since 2.0.0

# File lib/hanami/config.rb, line 429
def logger=(logger_instance)
  @logger_instance = logger_instance
end
logger_instance() click to toggle source

Returns the configured logger instance.

Unless you’ve replaced the logger with {#logger=}, this returns a ‘Dry::Logger::Dispatcher` configured with the options configured through {#logger}.

This configured logger is registered in all app and slice containers as ‘“logger”`. For typical usage, you should access the logger via this component, not directly from config.

@example Accessing the logger component

Hanami.app["logger"] # => #<Dry::Logger::Dispatcher>

@example Injecting the logger as a dependency

module MyApp
  class MyClass
    include Deps["logger"]

    def my_method
      logger.info("hello")
    end
  end
end

@return [Dry::Logger::Dispatcher]

@see logger @see Hanami::Config::Logger

@api public @since 2.0.0

# File lib/hanami/config.rb, line 464
def logger_instance
  @logger_instance || logger.instance
end

Private Instance Methods

initialize_copy(source) click to toggle source

@api private

Calls superclass method
# File lib/hanami/config.rb, line 344
def initialize_copy(source)
  super

  @app_name = app_name.dup

  @actions = source.actions.dup
  @assets = source.assets.dup
  @db = source.db.dup
  @logger = source.logger.dup
  @middleware = source.middleware.dup
  @router = source.router.dup.tap do |router|
    router.instance_variable_set(:@base_config, self)
  end
  @views = source.views.dup
end
load_dependent_config(gem_name) { || ... } click to toggle source
# File lib/hanami/config.rb, line 494
def load_dependent_config(gem_name)
  if Hanami.bundled?(gem_name)
    yield
  else
    require_relative "config/null_config"
    NullConfig.new
  end
end
load_from_env() click to toggle source
# File lib/hanami/config.rb, line 470
def load_from_env
  self.slices = ENV["HANAMI_SLICES"]&.split(",")&.map(&:strip)
end
method_missing(name, *args, &block) click to toggle source
Calls superclass method
# File lib/hanami/config.rb, line 503
def method_missing(name, *args, &block)
  if config.respond_to?(name)
    config.public_send(name, *args, &block)
  else
    super
  end
end
respond_to_missing?(name, _include_all = false) click to toggle source
Calls superclass method
# File lib/hanami/config.rb, line 511
def respond_to_missing?(name, _include_all = false)
  config.respond_to?(name) || super
end
use_body_parser_middleware() click to toggle source
# File lib/hanami/config.rb, line 477
def use_body_parser_middleware
  return unless Hanami.bundled?("hanami-controller")

  return if actions.formats.empty?
  return if middleware.stack["/"].map(&:first).any? { |klass| klass == "Hanami::Middleware::BodyParser" }

  parsers = SUPPORTED_MIDDLEWARE_PARSERS & actions.formats.values
  return if parsers.empty?

  middleware.use(
    :body_parser,
    [parsers.to_h { |parser_format|
      [parser_format, actions.formats.mime_types_for(parser_format)]
    }]
  )
end