diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index be560400..38ba9ed2 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -12,10 +12,14 @@ require "middleman-core/vendor/hooks-0.2.0/lib/hooks" require "middleman-core/sitemap" require "middleman-core/core_extensions" +require "middleman-core/configuration" # Core Middleman Class module Middleman class Application + # Global configuration + include Configuration::Global + # Uses callbacks include Hooks @@ -25,115 +29,75 @@ module Middleman # Ready (all loading and parsing of extensions complete) hook define_hook :ready - class << self - - # Mix-in helper methods. Accepts either a list of Modules - # and/or a block to be evaluated - # @return [void] - def helpers(*extensions, &block) - class_eval(&block) if block_given? - include(*extensions) if extensions.any? - end - - # Access class-wide defaults - # - # @private - # @return [Hash] Hash of default values - def defaults - @defaults ||= {} - end - - # Set class-wide defaults - # - # @param [Symbol] key Unique key name - # @param value Default value - # @return [void] - def set(key, value=nil, &block) - @defaults ||= {} - @defaults[key] = value - - @inst.set(key, value, &block) if @inst - end - end - - delegate :helpers, :to => :"self.class" - - # Set attributes (global variables) - # - # @param [Symbol] key Name of the attribue - # @param value Attribute value + # Mix-in helper methods. Accepts either a list of Modules + # and/or a block to be evaluated # @return [void] - def set(key, value=nil, &block) - setter = "#{key}=".to_sym - self.class.send(:attr_accessor, key) if !respond_to?(setter) - value = block if block_given? - send(setter, value) + def self.helpers(*extensions, &block) + class_eval(&block) if block_given? + include(*extensions) if extensions.any? end + delegate :helpers, :to => :"self.class" # Root project directory (overwritten in middleman build/server) # @return [String] - set :root, ENV["MM_ROOT"] || Dir.pwd + def self.root + ENV["MM_ROOT"] || Dir.pwd + end + delegate :root, :to => :"self.class" # Pathname-addressed root - def root_path - @_root_path ||= Pathname.new(root) + def self.root_path + Pathname(root) end + delegate :root_path, :to => :"self.class" # Name of the source directory # @return [String] - set :source, "source" + config.define_setting :source, "source", 'Name of the source directory' # Middleman environment. Defaults to :development, set to :build by the build process # @return [String] - set :environment, (ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :development + config.define_setting :environment, ((ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :development), 'Middleman environment. Defaults to :development, set to :build by the build process' # Which file should be used for directory indexes # @return [String] - set :index_file, "index.html" + config.define_setting :index_file, "index.html", 'Which file should be used for directory indexes' # Whether to strip the index file name off links to directory indexes # @return [Boolean] - set :strip_index_file, true + config.define_setting :strip_index_file, true, 'Whether to strip the index file name off links to directory indexes' # Whether to include a trailing slash when stripping the index file # @return [Boolean] - set :trailing_slash, true + config.define_setting :trailing_slash, true, 'Whether to include a trailing slash when stripping the index file' # Location of javascripts within source. # @return [String] - set :js_dir, "javascripts" + config.define_setting :js_dir, "javascripts", 'Location of javascripts within source' # Location of stylesheets within source. Used by Compass. # @return [String] - set :css_dir, "stylesheets" + config.define_setting :css_dir, "stylesheets", 'Location of stylesheets within source' # Location of images within source. Used by HTML helpers and Compass. # @return [String] - set :images_dir, "images" + config.define_setting :images_dir, "images", 'Location of images within source' # Location of fonts within source. Used by Compass. # @return [String] - set :fonts_dir, "fonts" + config.define_setting :fonts_dir, "fonts", 'Location of fonts within source' # Where to build output files # @return [String] - set :build_dir, "build" + config.define_setting :build_dir, "build", 'Where to build output files' # Default prefix for building paths. Used by HTML helpers and Compass. # @return [String] - set :http_prefix, "/" - - # Default string encoding for templates and output. - # @return [String] - set :encoding, "utf-8" - - # Whether to catch and display exceptions - # @return [Boolean] - set :show_exceptions, true + config.define_setting :http_prefix, "/", 'Default prefix for building paths' # Default layout name # @return [String, Symbold] - set :layout, :_auto_layout + config.define_setting :layout, :_auto_layout, 'Default layout name' # Activate custom features and extensions include Middleman::CoreExtensions::Extensions @@ -178,12 +142,12 @@ module Middleman cache.clear # Setup the default values from calls to set before initialization - self.class.superclass.defaults.each { |k,v| set(k,v) } + self.class.superclass.config.to_h.each { |k,v| self.class.config.define_setting(k,v) } # Evaluate a passed block if given instance_exec(&block) if block_given? - set :source, ENV["MM_SOURCE"] if ENV["MM_SOURCE"] + config[:source] = ENV["MM_SOURCE"] if ENV["MM_SOURCE"] super end @@ -199,24 +163,17 @@ module Middleman # Whether we're in development mode # @return [Boolean] If we're in dev mode - def development?; environment == :development; end + def development?; config[:environment] == :development; end # Whether we're in build mode # @return [Boolean] If we're in build mode - def build?; environment == :build; end - - # Backwards compatibilty with old Sinatra template interface - # - # @return [Middleman::Application] - def settings - self - end + def build?; config[:environment] == :build; end # The full path to the source directory # # @return [String] def source_dir - File.join(root, source) + File.join(root, config[:source]) end delegate :logger, :instrument, :to => ::Middleman::Util @@ -239,7 +196,7 @@ module Middleman if !resource # Try it with /index.html at the end - indexed_path = File.join(path.sub(%r{/$}, ''), index_file) + indexed_path = File.join(path.sub(%r{/$}, ''), config[:index_file]) resource = sitemap.find_resource_by_destination_path(indexed_path) end diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 7ec7a558..6b9dcb5a 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -83,7 +83,7 @@ module Middleman::Cli # @return [Middleman::Application] def shared_instance(verbose=false, instrument=false) @_shared_instance ||= ::Middleman::Application.server.inst do - set :environment, :build + config[:environment] = :build logger(verbose ? 0 : 1, instrument) end end @@ -114,7 +114,7 @@ module Middleman::Cli # @param [Middleman::Sitemap::Resource] resource # @return [String] The full path of the file that was written def render_to_file(resource) - build_dir = self.class.shared_instance.build_dir + build_dir = self.class.shared_instance.config[:build_dir] output_file = File.join(build_dir, resource.destination_path) begin diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb new file mode 100644 index 00000000..6cede94d --- /dev/null +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -0,0 +1,231 @@ +module Middleman + module Configuration + # Access to a global configuration manager for the whole Middleman project, + # plus backwards compatibility mechanisms for older Middleman projects. + module Global + def self.included(app) + app.send :extend, ClassMethods + end + + module ClassMethods + # Global configuration for the whole Middleman project. + # @return [ConfigurationManager] + def config + @_config ||= ConfigurationManager.new + end + + # Set attributes (global variables) + # + # @deprecated Prefer accessing settings through "config". + # + # @param [Symbol] key Name of the attribue + # @param value Attribute value + # @return [void] + def set(key, default=nil, &block) + config.define_setting(key, default) + @inst.set(key, default, &block) if @inst + end + + # Access global settings as methods, to preserve compatibility with + # old Middleman. + # + # @deprecated Prefer accessing settings through "config". + def method_missing(method, *args) + if config.defines_setting? method + config[method] + else + super + end + end + + # Needed so that method_missing makes sense + def respond_to?(method, include_private = false) + super || config.defines_setting?(method) + end + end + + def config + self.class.config + end + + # Backwards compatibilty with old Sinatra template interface + # + # @deprecated Prefer accessing settings through "config". + # + # @return [ConfigurationManager] + alias :settings :config + + # Set attributes (global variables) + # + # @deprecated Prefer accessing settings through "config". + # + # @param [Symbol] key Name of the attribue + # @param value Attribute value + # @return [void] + def set(key, value=nil, &block) + value = block if block_given? + config[key] = value + end + + # Access global settings as methods, to preserve compatibility with + # old Middleman. + # + # @deprecated Prefer accessing settings through "config". + def method_missing(method, *args) + if config.defines_setting? method + config[method] + else + super + end + end + + # Needed so that method_missing makes sense + def respond_to?(method, include_private = false) + super || config.defines_setting?(method) + end + end + + # A class that manages a collection of documented settings. + # Can be used by extensions as well as the main Middleman + # application. Extensions should probably finalize their instance + # after defining all the settings they want to expose. + class ConfigurationManager + def initialize + # A hash from setting key to ConfigSetting instance. + @settings = {} + @finalized = false + end + + # Get all settings, sorted by key, as ConfigSetting objects. + # @return [Array] + def all_settings + @settings.values.sort_by(&:key) + end + + # Get a full ConfigSetting object for the setting with the give key. + # @return [ConfigSetting] + def setting(key) + @settings[key] + end + + # Get the value of a setting by key. Returns nil if there is no such setting. + # @return [Object] + def [](key) + setting = @settings[key] + setting ? setting.value : nil + end + + # Set the value of a setting by key. Creates the setting if it doesn't exist. + # @param [Symbol] key + # @param [Object] val + def []=(key, val) + setting = @settings[key] || define_setting(key) + setting.value = val + end + + # Allow configuration settings to be read and written via methods + def method_missing(method, *args) + if defines_setting?(method) && args.size == 0 + self[method] + elsif method =~ /^(\w+)=$/ && args.size == 1 + self[$1.to_sym] = args[0] + else + super + end + end + + # Needed so that method_missing makes sense + def respond_to?(method, include_private = false) + super || defines_setting?(method) || (method =~ /^(\w+)=$/ && defines_setting?($1)) + end + + # Does this configuration manager know about the setting identified by key? + # @param [Symbol] key + # @return [Boolean] + def defines_setting?(key) + @settings.has_key?(key) + end + + # Define a new setting, with optional default and user-friendly description. + # Once the configuration manager is finalized, no new settings may be defined. + # + # @param [Symbol] key + # @param [Object] default + # @param [String] description + # @return [ConfigSetting] + def define_setting(key, default=nil, description=nil) + raise "Setting #{key} doesn't exist" if @finalized + raise "Setting #{key} already defined" if @settings.has_key?(key) + raise "Setting key must be a Symbol" unless key.is_a? Symbol + + @settings[key] = ConfigSetting.new(key, default, description) + end + + # Switch the configuration manager is finalized, it switches to read-only + # mode and no new settings may be defined. + def finalize! + @finalized = true + end + + # Deep duplicate of the configuration manager + def dup + copy = ConfigurationManager.new + @settings.each do |key, setting| + copy_setting = copy.define_setting setting.key, setting.default, setting.description + copy_setting.value = setting.value if setting.value_set? + end + copy + end + + def to_h + hash = {} + @settings.each do |key, setting| + hash[key] = setting.value + end + hash + end + + def to_s + to_h.inspect + end + end + + # An individual configuration setting, with an optional default and description. + # Also models whether or not a value has been set. + class ConfigSetting + # The name of this setting + attr_accessor :key + + # The default value for this setting + attr_accessor :default + + # A human-friendly description of the setting + attr_accessor :description + + def initialize(key, default, description) + @value_set = false + self.key = key + self.default = default + self.description = description + end + + # The user-supplied value for this setting, overriding the default + def value=(value) + @value = value + @value_set = true + end + + # The effective value of the setting, which may be the default + # if the user has not set a value themselves. Note that even if the + # user sets the value to nil it will override the default. + def value + value_set? ? @value : default + end + + # Whether or not there has been a value set beyond the default + def value_set? + @value_set + end + end + end +end diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 360d953f..bc2778af 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -13,7 +13,7 @@ module Middleman require "yaml" require "active_support/json" - app.set :data_dir, "data" + app.config.define_setting :data_dir, "data", "The directory data files are stored in" app.send :include, InstanceMethods end alias :included :registered @@ -24,12 +24,12 @@ module Middleman # Setup data files before anything else so they are available when # parsing config.rb def initialize - self.files.changed DataStore.matcher do |file| - self.data.touch_file(file) if file.match(%r{^#{self.data_dir}\/}) + files.changed DataStore.matcher do |file| + data.touch_file(file) if file.match(%r{^#{config[:data_dir]}\/}) end - self.files.deleted DataStore.matcher do |file| - self.data.remove_file(file) if file.match(%r{^#{self.data_dir}\/}) + files.deleted DataStore.matcher do |file| + data.remove_file(file) if file.match(%r{^#{config[data_dir]}\/}) end super diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index e10359ab..3f8d1d01 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -37,19 +37,13 @@ module Middleman class << self # @private def registered(app) - # Using for version parsing - require "rubygems" - app.define_hook :after_configuration app.define_hook :before_configuration app.define_hook :build_config app.define_hook :development_config - if ENV["AUTOLOAD_SPROCKETS"] - app.set :autoload_sprockets, (ENV["AUTOLOAD_SPROCKETS"] == "true") - else - app.set :autoload_sprockets, true - end + app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' + app.config[:autoload_sprockets] = (ENV["AUTOLOAD_SPROCKETS"] == "true") if ENV["AUTOLOAD_SPROCKETS"] app.extend ClassMethods app.send :include, InstanceMethods @@ -137,7 +131,7 @@ module Middleman instance_eval File.read(local_config), local_config, 1 end - if autoload_sprockets + if config[:autoload_sprockets] begin require "middleman-sprockets" activate(:sprockets) diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index 0f2118ea..6907740b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -9,20 +9,20 @@ module Middleman # once registered def registered(app) # Setup a default helpers paths - app.set :helpers_dir, "helpers" - app.set :helpers_filename_glob, "**{,/*/**}/*.rb" - app.set :helpers_filename_to_module_name_proc, Proc.new { |filename| + app.config.define_setting :helpers_dir, "helpers", 'Directory to autoload helper modules from' + app.config.define_setting :helpers_filename_glob, "**.rb", 'Glob pattern for matching helper ruby files' + app.config.define_setting :helpers_filename_to_module_name_proc, Proc.new { |filename| basename = File.basename(filename, File.extname(filename)) basename.camelcase - } + }, 'Proc implementing the conversion from helper filename to module name' # After config app.after_configuration do - helpers_path = File.expand_path(helpers_dir, root) + helpers_path = File.join(root, config[:helpers_dir]) next unless File.exists?(helpers_path) - Dir[File.join(helpers_path, helpers_filename_glob)].each do |filename| - module_name = helpers_filename_to_module_name_proc.call(filename) + Dir[File.join(helpers_path, config[:helpers_filename_glob])].each do |filename| + module_name = config[:helpers_filename_to_module_name_proc].call(filename) next unless module_name require filename diff --git a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb index 1883b57b..a55471d9 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -29,7 +29,7 @@ module Middleman # Before parsing config, load the data/ directory app.before_configuration do - files.reload_path(data_dir) + files.reload_path(config[:data_dir]) end # After config, load everything else diff --git a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb index bfc6f87c..f021dde8 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -62,7 +62,7 @@ module Middleman::CoreExtensions def clear_data(file) # Copied from Sitemap::Store#file_to_path, but without # removing the file extension - file = File.expand_path(file, @app.root) + file = File.join(@app.root, file) prefix = @app.source_dir.sub(/\/$/, "") + "/" return unless file.include?(prefix) path = file.sub(prefix, "") diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index cfca198f..2836a105 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -257,7 +257,7 @@ module Middleman extension_class = ::Tilt[ext] ::Tilt.mappings.each do |ext, engines| next unless engines.include? extension_class - engine_options = respond_to?(ext.to_sym) ? send(ext.to_sym) : {} + engine_options = config[ext.to_sym] || {} options.merge!(engine_options) end @@ -272,7 +272,7 @@ module Middleman # @return [String] def fetch_layout(engine, opts) # The layout name comes from either the system default or the options - local_layout = opts.has_key?(:layout) ? opts[:layout] : layout + local_layout = opts.has_key?(:layout) ? opts[:layout] : config[:layout] return false unless local_layout # Look for engine-specific options diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 53f3c3ed..ba5c7e7b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -28,12 +28,12 @@ module Middleman # @param [String, Symbol] layout_name # @return [void] def with_layout(layout_name, &block) - old_layout = layout + old_layout = config[:layout] - set :layout, layout_name + config[:layout] = layout_name instance_exec(&block) if block_given? ensure - set :layout, old_layout + config[:layout] = old_layout end # The page method allows the layout to be set on a specific path @@ -48,7 +48,7 @@ module Middleman blocks = Array(block) # Default layout - opts[:layout] = layout if opts[:layout].nil? + opts[:layout] = config[:layout] if opts[:layout].nil? # If the url is a regexp if url.is_a?(Regexp) || url.include?("*") @@ -64,7 +64,7 @@ module Middleman # Normalized path url = '/' + Middleman::Util.normalize_path(url) if url.end_with?('/') || File.directory?(File.join(source_dir, url)) - url = File.join(url, index_file) + url = File.join(url, config[:index_file]) end # Setup proxy diff --git a/middleman-core/lib/middleman-core/core_extensions/ruby_encoding.rb b/middleman-core/lib/middleman-core/core_extensions/ruby_encoding.rb index e9168386..3ff70b13 100644 --- a/middleman-core/lib/middleman-core/core_extensions/ruby_encoding.rb +++ b/middleman-core/lib/middleman-core/core_extensions/ruby_encoding.rb @@ -6,6 +6,10 @@ module Middleman::CoreExtensions::RubyEncoding # Once registerd def registered(app) + # Default string encoding for templates and output. + # @return [String] + app.config.define_setting :encoding, "utf-8", 'Default string encoding for templates and output' + app.send :include, InstanceMethods end @@ -15,8 +19,8 @@ module Middleman::CoreExtensions::RubyEncoding module InstanceMethods def initialize if Object.const_defined?(:Encoding) - Encoding.default_internal = encoding - Encoding.default_external = encoding + Encoding.default_internal = config[:encoding] + Encoding.default_external = config[:encoding] end super diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index 9dd27fb8..8c34612a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -11,10 +11,14 @@ module Middleman # Once registered def registered(app) + # Whether to catch and display exceptions + # @return [Boolean] + app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions' + # When in dev app.configure :development do # Include middlemare - if show_exceptions + if config[:show_exceptions] use ::Middleman::CoreExtensions::ShowExceptions::Middleware end end diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 2d6f187d..0d6b3bec 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -71,7 +71,7 @@ module Middleman opts = @options @app =::Middleman::Application.server.inst do if opts[:environment] - set :environment, opts[:environment].to_sym + config[:environment] = opts[:environment].to_sym end logger(opts[:debug] ? 0 : 1, opts[:instrumenting] || false) diff --git a/middleman-core/lib/middleman-core/renderers/erb.rb b/middleman-core/lib/middleman-core/renderers/erb.rb index 6ae858bb..e6a6f6b6 100644 --- a/middleman-core/lib/middleman-core/renderers/erb.rb +++ b/middleman-core/lib/middleman-core/renderers/erb.rb @@ -8,8 +8,8 @@ module Middleman # once registered def registered(app) # Setup a default ERb engine - app.set :erb_engine, :erb - app.set :erb_engine_prefix, ::Tilt + app.config.define_setting :erb_engine, :erb, 'The engine to use for rendering ERb templates' + app.config.define_setting :erb_engine_prefix, ::Tilt, 'The parent module for ERb template engines' app.before_configuration do template_extensions :erb => :html @@ -19,14 +19,14 @@ module Middleman app.after_configuration do # Find the user's prefered engine # Convert symbols to classes - if erb_engine.is_a? Symbol + if config[:erb_engine].is_a? Symbol engine = engine.to_s engine = engine == "erb" ? "ERB" : engine.camelize - erb_engine = erb_engine_prefix.const_get("#{engine}Template") + config[:erb_engine] = config[:erb_engine_prefix].const_get("#{engine}Template") end # Tell Tilt to use the preferred engine - ::Tilt.prefer(erb_engine) + ::Tilt.prefer(config[:erb_engine]) end end alias :included :registered diff --git a/middleman-core/lib/middleman-core/renderers/less.rb b/middleman-core/lib/middleman-core/renderers/less.rb index b4382d6d..6784e54c 100644 --- a/middleman-core/lib/middleman-core/renderers/less.rb +++ b/middleman-core/lib/middleman-core/renderers/less.rb @@ -11,15 +11,15 @@ module Middleman # Once registered def registered(app) - # Default sass options - app.set :less, {} + # Default less options + app.config.define_setting :less, {}, 'LESS compiler options' app.before_configuration do template_extensions :less => :css end app.after_configuration do - ::Less.paths << File.expand_path(css_dir, source_dir) + ::Less.paths << File.join(source_dir, config[:css_dir]) end # Tell Tilt to use it as well (for inline sass blocks) diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index ae2dd78c..06d017cb 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -10,8 +10,8 @@ module Middleman # Once registered def registered(app) # Set our preference for a markdown engine - app.set :markdown_engine, :maruku - app.set :markdown_engine_prefix, ::Tilt + app.config.define_setting :markdown_engine, :maruku, 'Preferred markdown engine' + app.config.define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines' app.before_configuration do template_extensions :markdown => :html, @@ -26,24 +26,24 @@ module Middleman begin # Look for the user's preferred engine - if markdown_engine == :redcarpet + if config[:markdown_engine] == :redcarpet require "middleman-core/renderers/redcarpet" ::Tilt.prefer(::Middleman::Renderers::RedcarpetTemplate) - elsif !markdown_engine.nil? + elsif !config[:markdown_engine].nil? # Map symbols to classes - markdown_engine_klass = if markdown_engine.is_a? Symbol - engine = markdown_engine.to_s + markdown_engine_klass = if config[:markdown_engine].is_a? Symbol + engine = config[:markdown_engine].to_s engine = engine == "rdiscount" ? "RDiscount" : engine.camelize - markdown_engine_prefix.const_get("#{engine}Template") + config[:markdown_engine_prefix].const_get("#{engine}Template") else - markdown_engine_prefix + config[:markdown_engine_prefix] end # Tell tilt to use that engine ::Tilt.prefer(markdown_engine_klass) end rescue LoadError - logger.warn "Requested Markdown engine (#{markdown_engine}) not found. Maybe the gem needs to be installed and required?" + logger.warn "Requested Markdown engine (#{config[:markdown_engine]}) not found. Maybe the gem needs to be installed and required?" end end end diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index c77ff611..38b6afa1 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -12,16 +12,16 @@ module Middleman # Once registered def registered(app) # Default sass options - app.set :sass, {} + app.config.define_setting :sass, {}, 'Sass engine options' # Location of SASS .sass_cache directory. # @return [String] - # set :sass_cache_path, "/tmp/middleman-app-name/sass_cache" - app.set(:sass_cache_path) { File.join(app.root_path, '.sass_cache') } # runtime compile of path + app.config.define_setting :sass_cache_path, nil, 'Location of sass cache' # runtime compile of path app.before_configuration do template_extensions :scss => :css, :sass => :css + config[:sass_cache_path] = File.join(app.root_path, '.sass_cache') end # Tell Tilt to use it as well (for inline sass blocks) @@ -76,11 +76,11 @@ module Middleman more_opts = { :filename => eval_file, :line => line, :syntax => syntax } if @context.is_a?(::Middleman::Application) && file - location_of_sass_file = File.expand_path(@context.source, @context.root) + location_of_sass_file = @context.source_dir parts = basename.split('.') parts.pop - more_opts[:css_filename] = File.join(location_of_sass_file, @context.css_dir, parts.join(".")) + more_opts[:css_filename] = File.join(location_of_sass_file, @context.config[:css_dir], parts.join(".")) end options.merge(more_opts) diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index 3b7c3ef1..a5693630 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -20,10 +20,10 @@ module Middleman app.register Middleman::Sitemap::Extensions::Ignores # Set to automatically convert some characters into a directory - app.set :automatic_directory_matcher, nil + app.config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory' # Setup callbacks which can exclude paths from the sitemap - app.set :ignored_sitemap_matchers, { + app.config.define_setting :ignored_sitemap_matchers, { # dotfiles and folders in the root :root_dotfiles => proc { |file| file.match(%r{^\.}) }, @@ -38,7 +38,7 @@ module Middleman :layout => proc { |file| file.match(%r{^source/layout\.}) || file.match(%r{^source/layouts/}) } - } + }, 'Callbacks that can exclude paths from the sitemap' # Include instance methods app.send :include, InstanceMethods diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 52600ed7..d311973d 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -45,7 +45,7 @@ module Middleman path = @sitemap.file_to_path(file) return false unless path - ignored = @app.ignored_sitemap_matchers.any? do |name, callback| + ignored = @app.config[:ignored_sitemap_matchers].any? do |name, callback| callback.call(file) end @@ -85,7 +85,7 @@ module Middleman ::Middleman::Sitemap::Resource.new( @sitemap, @sitemap.file_to_path(file), - File.expand_path(file, @app.root) + File.join(@app.root, file) ) end end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 6eb0d300..5108b9a7 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -152,7 +152,7 @@ module Middleman # @param [String] file # @return [String] def file_to_path(file) - file = File.expand_path(file, @app.root) + file = File.join(@app.root, file) prefix = @app.source_dir.sub(/\/$/, "") + "/" return false unless file.start_with?(prefix) @@ -160,8 +160,8 @@ module Middleman path = file.sub(prefix, "") # Replace a file name containing automatic_directory_matcher with a folder - unless @app.automatic_directory_matcher.nil? - path = path.gsub(@app.automatic_directory_matcher, "/") + unless @app.config[:automatic_directory_matcher].nil? + path = path.gsub(@app.config[:automatic_directory_matcher], "/") end extensionless_path(path) diff --git a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb index be1bb082..e119568d 100644 --- a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb @@ -10,9 +10,12 @@ end Given /^an empty app$/ do step %Q{a directory named "empty_app"} step %Q{I cd to "empty_app"} + ENV["MM_ROOT"] = nil end Given /^a fixture app "([^\"]*)"$/ do |path| + ENV["MM_ROOT"] = nil + # This step can be reentered from several places but we don't want # to keep re-copying and re-cd-ing into ever-deeper directories next if File.basename(current_dir) == path diff --git a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb index 8a0997f5..ac0a7c3c 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -40,9 +40,10 @@ Given /^the Server is running$/ do ENV["MM_SOURCE"] = "" end + ENV["MM_ROOT"] = root_dir + initialize_commands = @initialize_commands || [] initialize_commands.unshift lambda { - set :root, root_dir set :environment, @current_env || :development set :show_exceptions, false } diff --git a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb index a2459194..1eb1796c 100644 --- a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb +++ b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb @@ -7,9 +7,6 @@ module MyExtension # Called when user `activate`s your extension def registered(app, options={}) - # Setup extension-specific config - app.set :config_variable, false - # Include class methods # app.extend ClassMethods @@ -18,9 +15,6 @@ module MyExtension app.after_configuration do # Do something - - # config_variable is now either the default or the user's - # setting from config.rb end end alias :included :registered diff --git a/middleman-more/lib/middleman-more/core_extensions/assets.rb b/middleman-more/lib/middleman-more/core_extensions/assets.rb index 13fb0a6f..8fdde3ca 100644 --- a/middleman-more/lib/middleman-more/core_extensions/assets.rb +++ b/middleman-more/lib/middleman-more/core_extensions/assets.rb @@ -33,7 +33,7 @@ module Middleman if resource = sitemap.find_resource_by_path(path) resource.url else - File.join(http_prefix, path) + File.join(config[:http_prefix], path) end end end diff --git a/middleman-more/lib/middleman-more/core_extensions/compass.rb b/middleman-more/lib/middleman-more/core_extensions/compass.rb index 2f9f98dd..78b7d13f 100644 --- a/middleman-more/lib/middleman-more/core_extensions/compass.rb +++ b/middleman-more/lib/middleman-more/core_extensions/compass.rb @@ -19,38 +19,38 @@ module Middleman # Location of SASS/SCSS files external to source directory. # @return [Array] - # set :sass_assets_paths, ["#{root}/assets/sass/", "/path/2/external/sass/repository/"] - app.set :sass_assets_paths, [] + # config[:sass_assets_paths] = ["#{root}/assets/sass/", "/path/2/external/sass/repository/"] + app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' app.after_configuration do - ::Compass.configuration do |config| - config.project_path = source_dir - config.environment = :development - config.cache_path = sass_cache_path - config.sass_dir = css_dir - config.additional_import_paths = sass_assets_paths - config.css_dir = css_dir - config.javascripts_dir = js_dir - config.fonts_dir = fonts_dir - config.images_dir = images_dir - config.http_path = http_prefix + ::Compass.configuration do |compass_config| + compass_config.project_path = source_dir + compass_config.environment = :development + compass_config.cache_path = config[:sass_cache_path] + compass_config.sass_dir = config[:css_dir] + compass_config.additional_import_paths = config[:sass_assets_paths] + compass_config.css_dir = config[:css_dir] + compass_config.javascripts_dir = config[:js_dir] + compass_config.fonts_dir = config[:fonts_dir] + compass_config.images_dir = config[:images_dir] + compass_config.http_path = config[:http_prefix] # Disable this initially, the cache_buster extension will # re-enable it if requested. - config.asset_cache_buster :none + compass_config.asset_cache_buster :none # Disable this initially, the relative_assets extension will # re-enable it if requested. - config.relative_assets = false + compass_config.relative_assets = false # Default output style - config.output_style = :nested + compass_config.output_style = :nested # No line-comments in test mode (changing paths mess with sha1) - config.line_comments = false if ENV["TEST"] + compass_config.line_comments = false if ENV["TEST"] - if respond_to?(:asset_host) && asset_host.is_a?(Proc) - config.asset_host(&asset_host) + if config.defines_setting?(:asset_host) && config[:asset_host].is_a?(Proc) + compass_config.asset_host(&config[:asset_host]) end end diff --git a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb index b9b5076e..f9b66cb6 100644 --- a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb @@ -20,7 +20,7 @@ module Middleman app.helpers Helpers - app.set :relative_links, false + app.config.define_setting :relative_links, false, 'Whether to generate relative links instead of absolute ones' end alias :included :registered end @@ -110,7 +110,7 @@ module Middleman # :relative option which, if set to true, will produce # relative URLs instead of absolute URLs. You can also add # - # set :relative_links, true + # config[:relative_links] = true # # to config.rb to have all links default to relative. def link_to(*args, &block) @@ -136,10 +136,10 @@ module Middleman resource = sitemap.find_resource_by_path(url) - # Allow people to turn on relative paths for all links with set :relative_links, true + # Allow people to turn on relative paths for all links with config[:relative_links] = true # but still override on a case by case basis with the :relative parameter. effective_relative = relative || false - if relative.nil? && relative_links + if relative.nil? && config[:relative_links] effective_relative = true end diff --git a/middleman-more/lib/middleman-more/core_extensions/i18n.rb b/middleman-more/lib/middleman-more/core_extensions/i18n.rb index eb23e70f..d0f6d80b 100644 --- a/middleman-more/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-more/lib/middleman-more/core_extensions/i18n.rb @@ -9,11 +9,11 @@ module Middleman # Once registerd def registered(app, options={}) - app.set :locales_dir, "locales" + app.config.define_setting :locales_dir, "locales", 'The directory holding your locale configurations' # Needed for helpers as well app.after_configuration do - locales_glob = File.join(locales_dir, "*.yml"); + locales_glob = File.join(config[:locales_dir], "*.yml"); ::I18n.load_path += Dir[File.join(root, locales_glob)] ::I18n.reload! diff --git a/middleman-more/lib/middleman-more/extensions/asset_host.rb b/middleman-more/lib/middleman-more/extensions/asset_host.rb index 0cddce83..d43e9a39 100644 --- a/middleman-more/lib/middleman-more/extensions/asset_host.rb +++ b/middleman-more/lib/middleman-more/extensions/asset_host.rb @@ -11,7 +11,7 @@ module Middleman # Once registered def registered(app) # Default to no host - app.set :asset_host, false + app.config.define_setting :asset_host, false, 'The asset host to use, or false for no asset host, or a Proc to determine asset host' # Include methods app.send :include, InstanceMethods @@ -30,12 +30,12 @@ module Middleman # @return [String] def asset_url(path, prefix="") original_output = super - return original_output unless asset_host + return original_output unless config[:asset_host] - asset_prefix = if asset_host.is_a?(Proc) - asset_host.call(original_output) - elsif asset_host.is_a?(String) - asset_host + asset_prefix = if config[:asset_host].is_a?(Proc) + config[:asset_host].call(original_output) + elsif config[:asset_host].is_a?(String) + config[:asset_host] end File.join(asset_prefix, original_output) diff --git a/middleman-more/lib/middleman-more/extensions/minify_css.rb b/middleman-more/lib/middleman-more/extensions/minify_css.rb index ac4b9644..d4f4bed0 100644 --- a/middleman-more/lib/middleman-more/extensions/minify_css.rb +++ b/middleman-more/lib/middleman-more/extensions/minify_css.rb @@ -10,13 +10,13 @@ module Middleman # Once registered def registered(app, options={}) - app.set :css_compressor, false + app.config.define_setting :css_compressor, nil, 'Set the CSS compressor to use. Deprecated in favor of the :compressor option when activating :minify_css' ignore = Array(options[:ignore]) << /\.min\./ inline = options[:inline] || false app.after_configuration do - chosen_compressor = css_compressor || options[:compressor] || begin + chosen_compressor = config[:css_compressor] || options[:compressor] || begin require "middleman-more/extensions/minify_css/rainpress" ::Rainpress end diff --git a/middleman-more/lib/middleman-more/extensions/minify_javascript.rb b/middleman-more/lib/middleman-more/extensions/minify_javascript.rb index 5ffae15c..9a1e91e6 100644 --- a/middleman-more/lib/middleman-more/extensions/minify_javascript.rb +++ b/middleman-more/lib/middleman-more/extensions/minify_javascript.rb @@ -10,7 +10,7 @@ module Middleman # Once registered def registered(app, options={}) - app.set :js_compressor, false + app.config.define_setting :js_compressor, nil, 'Set the JS compressor to use. Deprecated in favor of the :compressor option when activating :minify_js' ignore = Array(options[:ignore]) << /\.min\./ inline = options[:inline] || false