# Using Tilt for templating require 'tilt' # i18n Built-in require 'i18n' # Don't fail on invalid locale, that's not what our current # users expect. ::I18n.enforce_available_locales = false # Use ActiveSupport JSON require 'active_support/json' require 'active_support/core_ext/integer/inflections' # Simple callback library require 'hooks' # Our custom logger require 'middleman-core/logger' require 'middleman-core/sitemap' require 'middleman-core/configuration' require 'middleman-core/core_extensions' # Core Middleman Class module Middleman class Application # Global configuration include Configuration::Global # Uses callbacks include Hooks include Hooks::InstanceHooks # Before request hook define_hook :before # Ready (all loading and parsing of extensions complete) hook define_hook :ready # Runs before the build is started define_hook :before_build # Runs after the build is finished define_hook :after_build # Mix-in helper methods. Accepts either a list of Modules # and/or a block to be evaluated # @return [void] 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] def self.root ENV['MM_ROOT'] || Dir.pwd end delegate :root, :to => :"self.class" # Pathname-addressed root def self.root_path Pathname(root) end delegate :root_path, :to => :"self.class" # Name of the source directory # @return [String] config.define_setting :source, 'source', 'Name of the source directory' # Middleman environment. Defaults to :development, set to :build by the build process # @return [String] 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] 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] 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] config.define_setting :trailing_slash, true, 'Whether to include a trailing slash when stripping the index file' # Location of javascripts within source. # @return [String] config.define_setting :js_dir, 'javascripts', 'Location of javascripts within source' # Location of stylesheets within source. Used by Compass. # @return [String] config.define_setting :css_dir, 'stylesheets', 'Location of stylesheets within source' # Location of images within source. Used by HTML helpers and Compass. # @return [String] config.define_setting :images_dir, 'images', 'Location of images within source' # Location of fonts within source. Used by Compass. # @return [String] config.define_setting :fonts_dir, 'fonts', 'Location of fonts within source' # Location of partials within source. Used by renderers. # @return [String] config.define_setting :partials_dir, '', 'Location of partials within source' # Location of layouts within source. Used by renderers. # @return [String] config.define_setting :layouts_dir, 'layouts', 'Location of layouts within source' # Where to build output files # @return [String] config.define_setting :build_dir, 'build', 'Where to build output files' # Default prefix for building paths. Used by HTML helpers and Compass. # @return [String] config.define_setting :http_prefix, '/', 'Default prefix for building paths' # Default layout name # @return [String, Symbold] config.define_setting :layout, :_auto_layout, 'Default layout name' # Default string encoding for templates and output. # @return [String] config.define_setting :encoding, 'utf-8', 'Default string encoding for templates and output' # Should Padrino include CRSF tag # @return [Boolean] config.define_setting :protect_from_csrf, false, 'Should Padrino include CRSF tag' # Activate custom features and extensions include Middleman::CoreExtensions::Extensions # Basic Rack Request Handling register Middleman::CoreExtensions::Request # Handle exceptions register Middleman::CoreExtensions::ShowExceptions # Add Watcher Callbacks register Middleman::CoreExtensions::FileWatcher # Activate Data package register Middleman::CoreExtensions::Data # Setup custom rendering register Middleman::CoreExtensions::Rendering # Parse YAML from templates. Must be before sitemap so sitemap # extensions see updated frontmatter! register Middleman::CoreExtensions::FrontMatter # Sitemap register Middleman::Sitemap # Setup external helpers register Middleman::CoreExtensions::ExternalHelpers # with_layout and page routing include Middleman::CoreExtensions::Routing attr_reader :logger # Initialize the Middleman project def initialize(&block) @logger = ::Middleman::Logger.singleton # Clear the static class cache cache.clear # Setup the default values from calls to set before initialization self.class.config.load_settings(self.class.superclass.config.all_settings) if Object.const_defined?(:Encoding) Encoding.default_internal = config[:encoding] Encoding.default_external = config[:encoding] end # Evaluate a passed block if given instance_exec(&block) if block_given? config[:source] = ENV['MM_SOURCE'] if ENV['MM_SOURCE'] super end # Shared cache instance # # @private # @return [Middleman::Util::Cache] The cache def self.cache @_cache ||= ::Tilt::Cache.new end delegate :cache, :to => :"self.class" # Whether we're in development mode # @return [Boolean] If we're in dev mode def development? config[:environment] == :development end # Whether we're in build mode # @return [Boolean] If we're in build mode def build? config[:environment] == :build end # The full path to the source directory # # @return [String] def source_dir File.join(root, config[:source]) end delegate :instrument, :to => ::Middleman::Util # Work around this bug: http://bugs.ruby-lang.org/issues/4521 # where Ruby will call to_s/inspect while printing exception # messages, which can take a long time (minutes at full CPU) # if the object is huge or has cyclic references, like this. def to_s "#" end alias :inspect :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s # Hooks clones _hooks from the class to the instance. # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 # Middleman expects the same list of hooks for class and instance hooks: def _hooks self.class._hooks end end end Middleman::CoreExtensions::DefaultHelpers.activate Middleman::CoreExtensions::Internationalization.register(:i18n) if defined?(Middleman::CoreExtensions::Compass) Middleman::CoreExtensions::Compass.activate end Middleman::Extensions::Lorem.activate