123456789_123456789_123456789_123456789_123456789_

Module: Sinatra::ConfigFile

Relationships & Source Files
Namespace Children
Exceptions:
Defined in: sinatra-contrib/lib/sinatra/config_file.rb

Overview

Sinatra::ConfigFile is an extension that allows you to load the application's configuration from YAML files. It automatically detects if the files contain specific environment settings and it will use those corresponding to the current one.

You can access those options through settings within the application. If you try to get the value for a setting that hasn't been defined in the config file for the current environment, you will get whatever it was set to in the application.

Usage

Once you have written your configurations to a YAML file you can tell the extension to load them. See below for more information about how these files are interpreted.

For the examples, lets assume the following config.yml file:

greeting: Welcome to my file configurable application

Classic Application

require "sinatra"
require "sinatra/config_file"

config_file 'path/to/config.yml'

get '/' do
  @greeting = settings.greeting
  haml :index
end

# The rest of your classic application code goes here...

Modular Application

require "sinatra/base"
require "sinatra/config_file"

class MyApp < Sinatra::Base
  register Sinatra::ConfigFile

  config_file 'path/to/config.yml'

  get '/' do
    @greeting = settings.greeting
    haml :index
  end

  # The rest of your modular application code goes here...
end

Config File Format

In its most simple form this file is just a key-value list:

foo: bar
something: 42
nested:
  a: 1
  b: 2

But it also can provide specific environment configuration. There are two ways to do that: at the file level and at the settings level.

At the settings level (e.g. in 'path/to/config.yml'):

development:
  foo: development
  bar: bar
test:
  foo: test
  bar: bar
production:
  foo: production
  bar: bar

Or at the file level:

foo:
  development: development
  test: test
  production: production
bar: bar

In either case, settings.foo will return the environment name, and settings.bar will return "bar".

If you wish to provide defaults that may be shared among all the environments, this can be done by using a YAML alias, and then overwriting values in environments where appropriate:

default: &common_settings
  foo: 'foo'
  bar: 'bar'

production:
  <<: *common_settings
  bar: 'baz' # override the default value

Class Method Summary

  • .registered(base)

    When the extension is registered sets the environments setting to the traditional environments: development, test and production.

Instance Method Summary

  • #config_file(*paths)

    Loads the configuration from the YAML files whose paths are passed as arguments, filtering the settings for the current environment.

  • #config_for_env(hash) private

    Given a hash containing application configuration it returns settings applicable to the current environment.

  • #environment_keys?(hash) ⇒ Boolean private

    Returns true if supplied with a hash that has any recognized environments in its root keys.

  • #from_environment_key(hash) private

    Given a hash returns the settings corresponding to the current environment.

Class Method Details

.registered(base)

When the extension is registered sets the environments setting to the traditional environments: development, test and production.

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/config_file.rb', line 111

def self.registered(base)
  base.set :environments, %w[test production development]
end

Instance Method Details

#config_file(*paths)

Loads the configuration from the YAML files whose paths are passed as arguments, filtering the settings for the current environment. Note that these paths can actually be globs.

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/config_file.rb', line 118

def config_file(*paths)
  Dir.chdir(root || '.') do
    paths.each do |pattern|
      Dir.glob(pattern) do |file|
        raise UnsupportedConfigType unless ['.yml', '.yaml', '.erb'].include?(File.extname(file))

        logger.info "loading config file '#{file}'" if logging? && respond_to?(:logger)
        document = ERB.new(File.read(file)).result
        yaml = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(document) : YAML.load(document)
        config = config_for_env(yaml)
        config.each_pair { |key, value| set(key, value) }
      end
    end
  end
end

#config_for_env(hash) (private)

Given a hash containing application configuration it returns settings applicable to the current environment. Note: It gives precedence to environment settings defined at the root-level.

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/config_file.rb', line 145

def config_for_env(hash)
  return from_environment_key(hash) if environment_keys?(hash)

  hash.each_with_object(IndifferentHash[]) do |(k, v), acc|
    if environment_keys?(v)
      acc.merge!(k => v[environment.to_s]) if v.key?(environment.to_s)
    else
      acc.merge!(k => v)
    end
  end
end

#environment_keys?(hash) ⇒ Boolean (private)

Returns true if supplied with a hash that has any recognized environments in its root keys.

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/config_file.rb', line 165

def environment_keys?(hash)
  hash.is_a?(Hash) && hash.any? { |k, _| environments.include?(k.to_s) }
end

#from_environment_key(hash) (private)

Given a hash returns the settings corresponding to the current environment.

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/config_file.rb', line 159

def from_environment_key(hash)
  hash[environment.to_s] || hash[environment.to_sym] || {}
end