Yacht is an application configuration gem that lets you define settings for multiple environments in YAML files. It is similar to AppConfig with additional features like:
-
use of ClassyStruct for improved performance over OpenStruct
-
protection of sensitive settings by specifying a whitelist in a YAML file
-
easy override of nested keys (not pretty with YAML references)
-
no need for an initializer or constant to store loaded values (just use Yacht.my_key)
-
Rails: Add this to your Gemfile and run the
bundle
command.gem "yacht"
-
Outside of rails, just require the gem as usual:
require 'rubygems' require 'yacht'
First create one or more of the following YAML files in the same directory to define your settings:
# /path/to/yacht_config_dir/base.yml (required) production: public_info: copyright_year: 2011 company_name: AT&T Interactive cdn_host: 1.2.3.4 super_secret_info: aws_key: foofoo twitter_key: barbar test: cdn_host: localhost super_secret_info: # you can safely overwrite a single value in a nested key # YAML references (& and *) don't let you do this # see https://gist.github.com/979804 for an explanation aws_key: bazbaz # /path/to/yacht_config_dir/whitelist.yml (optional) # any keys specified here can be used as a whitelist filter: # Yacht::Loader.to_hash(:apply_whitelist? => true) # or # Yacht::Loader.to_classy_struct(:apply_whitelist? => true) # (by default the whitelist is ignored) # NOTE: the whitelist is ignored when using Yacht.my_key or Yacht['my_key'] # you have to use Yacht::Loader.to_hash or # Yacht::Loader.to_classy_struct to use the whitelist - public_info # /path/to/yacht_config_dir/local.yml (optional) # any values set in local.yml will override values set in base.yml # useful for development and testing cdn_host: localhost
Yacht::Loader.dir = '/path/to/yacht_config_dir' Yacht::Loader.environment = 'production'
# now you can access any key set in your YAML files with: Yacht.my_key # => "my_value" Yacht['my_key'] # => "my_value"
Yacht allows for inheritance between environments in a more complex way than standard YAML does. There are limitations to YAML’s inheritance, which are illustrated in this gist. With Yacht, to inherit from another environment, just set the _parent
key, like so:
# /path/to/yacht_config_dir/base.yml grandpa: :clan: McGillicuddy :age: 70 :car: :make: oldsmobile :year: 1955 pa: _parent: grandpa :age: 40 :car: :year: 1980 # Now set up Yacht Yacht::Loader.dir = '/path/to/yacht_config_dir' Yacht::Loader.environment = 'pa' # inherited from grandpa Yacht.clan # => 'McGillicuddy' # inherited from grandpa with an override for :year Yacht.car # => { :make=>"oldsmobile", :year=>1980 }
See the cucumber feature for more details and examples.
If you would like to access values stored in Yacht inside of javascript, there is a helper for that. First, create a YAML file to tell Yacht which keys should be exported:
# /RAILS_ROOT/config/yacht/js_keys.yml # only keys listed here will be available in javascript # remember that any values exported to javascript will be visible to all visitors to your site - cookie_domain
Then use Yacht::Loader.to_js_snippet
to create a string that can be eval’d or included in the DOM:
Yacht::Loader.to_js_snippet # => ";var Yacht = {\"cookie_domain\":\"example.com\"};"
You can also add in extra values from outside of Yacht using the :merge option, like so:
Yacht::Loader.to_js_snippet(:merge => {:current_time => Time.now.to_s}) # => ";var Yacht = {\"cookie_domain\":\"example.com\",\"current_time\":\"06/29/2011\"};"
To use Yacht inside of Rails, just add an initializer to config/initializers
:
# config/initializers/00_yacht_init.rb # look for YAML files in config/yacht inside the Rails app directory Yacht::Loader.dir = Rails.root.join('config', 'yacht') # it makes sense to use your Rails environment names in Yacht Yacht::Loader.environment = Rails.env
When used inside of a Rails application, the yacht_js_snippet
Rails helper is included in the global ApplicationHelper
so you can use it in views. yacht_js_snippet
wraps the string from Yacht::Loader.to_js_snippet
in a script tag using Rails’ javascript_tag
helper.
# inside a view or helper: yacht_js_snippet # => "<script type=\"text/javascript\">\n//<![CDATA[\n;var Yacht = {\"cookie_domain\":\"localhost\"\n//]]>\n</script>" # you can also pass options to yacht_js_snippet, like the the current Rails environment: yacht_js_snippet(:merge => {:current_time => Time.now.to_s, :rails_env => Rails.env}) # => "<script type=\"text/javascript\">\n//<![CDATA[\n;var Yacht = {\"cookie_domain\":\"localhost\",\"rails_env\":\"development\",\"current_time\":\"06/29/2011\"};\n//]]>\n</script>"
Yacht works with ruby 1.8.7 and 1.9.2.
Yacht is licensed under the MIT License.