middleman-more is fully rdoc'd

This commit is contained in:
Thomas Reynolds 2011-12-31 14:28:17 -08:00
parent 50b9ad7b28
commit c7249a63b1
13 changed files with 173 additions and 8 deletions

View file

@ -1,16 +1,26 @@
# ERb renderer
module Middleman::Renderers::ERb module Middleman::Renderers::ERb
# Setup extension
class << self class << self
# once registered
def registered(app) def registered(app)
# Setup a default ERb engine
app.set :erb_engine, :erb app.set :erb_engine, :erb
app.set :erb_engine_prefix, ::Tilt app.set :erb_engine_prefix, ::Tilt
# After config
app.after_configuration do app.after_configuration do
# Find the user's prefered engine
# Convert symbols to classes
if erb_engine.is_a? Symbol if erb_engine.is_a? Symbol
engine = engine.to_s engine = engine.to_s
engine = engine == "erb" ? "ERB" : engine.camelize engine = engine == "erb" ? "ERB" : engine.camelize
erb_engine = erb_engine_prefix.const_get("#{engine}Template") erb_engine = erb_engine_prefix.const_get("#{engine}Template")
end end
# Tell Tilt to use the preferred engine
::Tilt.prefer(erb_engine) ::Tilt.prefer(erb_engine)
end end
end end

View file

@ -3,8 +3,6 @@ libdir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
require "middleman-core" require "middleman-core"
require "sass"
require "coffee_script"
# Top-level Middleman object # Top-level Middleman object
module Middleman module Middleman
@ -42,6 +40,7 @@ module Middleman
autoload :MinifyJavascript, "middleman-more/extensions/minify_javascript" autoload :MinifyJavascript, "middleman-more/extensions/minify_javascript"
end end
require "coffee_script"
Base.register Middleman::Renderers::Haml Base.register Middleman::Renderers::Haml
Base.register Middleman::Renderers::Sass Base.register Middleman::Renderers::Sass
Base.register Middleman::Renderers::Markdown Base.register Middleman::Renderers::Markdown
@ -54,6 +53,7 @@ module Middleman
# Sprockets asset handling # Sprockets asset handling
Base.register Middleman::CoreExtensions::Sprockets Base.register Middleman::CoreExtensions::Sprockets
# Register the optional extensions
Extensions.register(:cache_buster) { Extensions.register(:cache_buster) {
::Middleman::Extensions::CacheBuster } ::Middleman::Extensions::CacheBuster }
Extensions.register(:minify_css) { Extensions.register(:minify_css) {

View file

@ -4,7 +4,8 @@ module Middleman::CoreExtensions::Compass
# Extension registered # Extension registered
class << self class << self
# @private
# Once registered
def registered(app) def registered(app)
require "compass" require "compass"

View file

@ -1,9 +1,15 @@
require 'pathname' # Require gem
require "sprockets" require "sprockets"
# Sprockets extension
module Middleman::CoreExtensions::Sprockets module Middleman::CoreExtensions::Sprockets
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Default compression to off
app.set :js_compressor, false app.set :js_compressor, false
app.set :css_compressor, false app.set :css_compressor, false
@ -19,9 +25,12 @@ module Middleman::CoreExtensions::Sprockets
end end
end end
# Once Middleman is setup
app.ready do app.ready do
# Create sprockets env for JS
js_env = Middleman::CoreExtensions::Sprockets::JavascriptEnvironment.new(self) js_env = Middleman::CoreExtensions::Sprockets::JavascriptEnvironment.new(self)
# Add any gems with vendor/assets/javascripts to paths
vendor_dir = File.join("vendor", "assets", "javascripts") vendor_dir = File.join("vendor", "assets", "javascripts")
gems_with_js = ::Middleman.rubygems_latest_specs.select do |spec| gems_with_js = ::Middleman.rubygems_latest_specs.select do |spec|
::Middleman.spec_has_file?(spec, vendor_dir) ::Middleman.spec_has_file?(spec, vendor_dir)
@ -29,6 +38,7 @@ module Middleman::CoreExtensions::Sprockets
js_env.append_path File.join(spec.full_gem_path, vendor_dir) js_env.append_path File.join(spec.full_gem_path, vendor_dir)
end end
# Add any gems with app/assets/javascripts to paths
app_dir = File.join("app", "assets", "javascripts") app_dir = File.join("app", "assets", "javascripts")
gems_with_js = ::Middleman.rubygems_latest_specs.select do |spec| gems_with_js = ::Middleman.rubygems_latest_specs.select do |spec|
::Middleman.spec_has_file?(spec, app_dir) ::Middleman.spec_has_file?(spec, app_dir)
@ -36,14 +46,18 @@ module Middleman::CoreExtensions::Sprockets
js_env.append_path File.join(spec.full_gem_path, app_dir) js_env.append_path File.join(spec.full_gem_path, app_dir)
end end
# add paths to js_env (vendor/assets/javascripts) # Intercept requests to /javascripts and pass to sprockets
map "/#{js_dir}" do map "/#{js_dir}" do
run js_env run js_env
end end
# Setup Sprockets Sass options
sass.each { |k, v| ::Sprockets::Sass.options[k] = v } sass.each { |k, v| ::Sprockets::Sass.options[k] = v }
# Create sprockets env for CSS
css_env = Middleman::CoreExtensions::Sprockets::StylesheetEnvironment.new(self) css_env = Middleman::CoreExtensions::Sprockets::StylesheetEnvironment.new(self)
# Add any gems with vendor/assets/stylesheets to paths
vendor_dir = File.join("vendor", "assets", "stylesheets") vendor_dir = File.join("vendor", "assets", "stylesheets")
gems_with_css = ::Middleman.rubygems_latest_specs.select do |spec| gems_with_css = ::Middleman.rubygems_latest_specs.select do |spec|
::Middleman.spec_has_file?(spec, vendor_dir) ::Middleman.spec_has_file?(spec, vendor_dir)
@ -51,6 +65,7 @@ module Middleman::CoreExtensions::Sprockets
css_env.append_path File.join(spec.full_gem_path, vendor_dir) css_env.append_path File.join(spec.full_gem_path, vendor_dir)
end end
# Add any gems with app/assets/stylesheets to paths
app_dir = File.join("app", "assets", "stylesheets") app_dir = File.join("app", "assets", "stylesheets")
gems_with_css = ::Middleman.rubygems_latest_specs.select do |spec| gems_with_css = ::Middleman.rubygems_latest_specs.select do |spec|
::Middleman.spec_has_file?(spec, app_dir) ::Middleman.spec_has_file?(spec, app_dir)
@ -58,6 +73,7 @@ module Middleman::CoreExtensions::Sprockets
css_env.append_path File.join(spec.full_gem_path, app_dir) css_env.append_path File.join(spec.full_gem_path, app_dir)
end end
# Intercept requests to /stylesheets and pass to sprockets
map("/#{css_dir}") do map("/#{css_dir}") do
run css_env run css_env
end end
@ -66,7 +82,9 @@ module Middleman::CoreExtensions::Sprockets
alias :included :registered alias :included :registered
end end
# Generic Middleman Sprockets env
class MiddlemanEnvironment < ::Sprockets::Environment class MiddlemanEnvironment < ::Sprockets::Environment
# Setup
def initialize(app) def initialize(app)
@app = app @app = app
super app.source_dir super app.source_dir
@ -84,19 +102,26 @@ module Middleman::CoreExtensions::Sprockets
end end
end end
# During development, don't use the asset cache
def find_asset(path, options = {}) def find_asset(path, options = {})
expire_index! if @app.development? expire_index! if @app.development?
super super
end end
end end
# Javascript specific environment
class JavascriptEnvironment < MiddlemanEnvironment class JavascriptEnvironment < MiddlemanEnvironment
# Init
def initialize(app) def initialize(app)
super super
expire_index! expire_index!
# Remove old compressor
unregister_bundle_processor 'application/javascript', :js_compressor unregister_bundle_processor 'application/javascript', :js_compressor
# Register compressor from config
register_bundle_processor 'application/javascript', :js_compressor do |context, data| register_bundle_processor 'application/javascript', :js_compressor do |context, data|
if context.pathname.to_s =~ /\.min\./ if context.pathname.to_s =~ /\.min\./
data data
@ -109,19 +134,26 @@ module Middleman::CoreExtensions::Sprockets
append_path app.js_dir append_path app.js_dir
end end
# Clear cache on error
def javascript_exception_response(exception) def javascript_exception_response(exception)
expire_index! expire_index!
super(exception) super(exception)
end end
end end
# CSS specific environment
class StylesheetEnvironment < MiddlemanEnvironment class StylesheetEnvironment < MiddlemanEnvironment
# Init
def initialize(app) def initialize(app)
super super
expire_index! expire_index!
# Remove old compressor
unregister_bundle_processor 'text/css', :css_compressor unregister_bundle_processor 'text/css', :css_compressor
# Register compressor from config
register_bundle_processor 'text/css', :css_compressor do |context, data| register_bundle_processor 'text/css', :css_compressor do |context, data|
if context.pathname.to_s =~ /\.min\./ if context.pathname.to_s =~ /\.min\./
data data
@ -134,6 +166,7 @@ module Middleman::CoreExtensions::Sprockets
append_path app.css_dir append_path app.css_dir
end end
# Clear cache on error
def css_exception_response(exception) def css_exception_response(exception)
expire_index! expire_index!
super(exception) super(exception)

View file

@ -1,9 +1,18 @@
# Extension namespace
module Middleman::Extensions module Middleman::Extensions
# The Cache Buster extension
module CacheBuster module CacheBuster
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Add instance methods to context
app.send :include, InstanceMethods app.send :include, InstanceMethods
# After compass is setup, make it use the registered cache buster
app.compass_config do |config| app.compass_config do |config|
config.asset_cache_buster do |path, real_path| config.asset_cache_buster do |path, real_path|
real_path = real_path.path if real_path.is_a? File real_path = real_path.path if real_path.is_a? File
@ -19,7 +28,12 @@ module Middleman::Extensions
alias :included :registered alias :included :registered
end end
# Cache buster instance methods
module InstanceMethods module InstanceMethods
# asset_url override if we're using cache busting
# @param [String] path
# @param [String] prefix
def asset_url(path, prefix="") def asset_url(path, prefix="")
http_path = super http_path = super
@ -55,5 +69,6 @@ module Middleman::Extensions
end end
end end
# Register the extension
register :cache_buster, CacheBuster register :cache_buster, CacheBuster
end end

View file

@ -1,7 +1,15 @@
# Extensions namespace
module Middleman::Extensions module Middleman::Extensions
# Minify CSS Extension
module MinifyCss module MinifyCss
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Tell Sprockets to use the built in CSSMin
app.after_configuration do app.after_configuration do
if !css_compressor if !css_compressor
require "middleman-more/extensions/minify_css/cssmin" require "middleman-more/extensions/minify_css/cssmin"
@ -13,5 +21,6 @@ module Middleman::Extensions
end end
end end
# Register extension
register :minify_css, MinifyCss register :minify_css, MinifyCss
end end

View file

@ -1,25 +1,45 @@
# Extension namespace
module Middleman::Extensions module Middleman::Extensions
# Minify Javascript Extension
module MinifyJavascript module MinifyJavascript
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Once config is parsed
app.after_configuration do app.after_configuration do
# Tell sprockets which compressor to use
if !js_compressor if !js_compressor
require 'uglifier' require 'uglifier'
set :js_compressor, ::Uglifier.new set :js_compressor, ::Uglifier.new
end end
# Setup Rack to watch for inline JS
use InlineJavascriptRack, :compressor => js_compressor use InlineJavascriptRack, :compressor => js_compressor
end end
end end
alias :included :registered alias :included :registered
end end
# Rack middleware to look for JS in HTML and compress it
class InlineJavascriptRack class InlineJavascriptRack
# Init
# @param [Class] app
# @param [Hash] options
def initialize(app, options={}) def initialize(app, options={})
@app = app @app = app
@compressor = options[:compressor] @compressor = options[:compressor]
end end
# Rack interface
# @param [Rack::Environmemt] env
# @return [Array]
def call(env) def call(env)
status, headers, response = @app.call(env) status, headers, response = @app.call(env)
@ -52,5 +72,6 @@ module Middleman::Extensions
end end
end end
# Register extension
register :minify_javascript, MinifyJavascript register :minify_javascript, MinifyJavascript
end end

View file

@ -1,17 +1,32 @@
# Extension namespace
module Middleman::Extensions module Middleman::Extensions
# Relative Assets extension
module RelativeAssets module RelativeAssets
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Tell compass to use relative assets
app.compass_config do |config| app.compass_config do |config|
config.relative_assets = true config.relative_assets = true
end end
# Include instance methods
app.send :include, InstanceMethods app.send :include, InstanceMethods
end end
alias :included :registered alias :included :registered
end end
# Relative Assets instance method
module InstanceMethods module InstanceMethods
# asset_url override for relative assets
# @param [String] path
# @param [String] prefix
# @return [String]
def asset_url(path, prefix="") def asset_url(path, prefix="")
begin begin
prefix = images_dir if prefix == http_images_path prefix = images_dir if prefix == http_images_path
@ -42,5 +57,6 @@ module Middleman::Extensions
end end
end end
# Register extension
register :relative_assets, RelativeAssets register :relative_assets, RelativeAssets
end end

View file

@ -1,9 +1,17 @@
# Require gem
require "haml"
# Haml Renderer
module Middleman::Renderers::Haml module Middleman::Renderers::Haml
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
require "haml" # Add haml helpers to context
app.send :include, ::Haml::Helpers app.send :include, ::Haml::Helpers
# Setup haml helper paths
app.ready do app.ready do
init_haml_helpers init_haml_helpers
end end

View file

@ -1,14 +1,23 @@
# Liquid Renderer
module Middleman::Renderers::Liquid module Middleman::Renderers::Liquid
# Setup extension
class << self class << self
# Once registerd
def registered(app) def registered(app)
# Liquid is not included in the default gems, # Liquid is not included in the default gems,
# but we'll support it if available. # but we'll support it if available.
begin begin
# Require Gem
require "liquid" require "liquid"
# After config, setup liquid partial paths
app.after_configuration do app.after_configuration do
Liquid::Template.file_system = Liquid::LocalFileSystem.new(source_dir) Liquid::Template.file_system = Liquid::LocalFileSystem.new(source_dir)
# Convert data object into a hash for liquid
provides_metadata %r{\.liquid$} do |path| provides_metadata %r{\.liquid$} do |path|
{ :locals => { :data => data.to_h } } { :locals => { :data => data.to_h } }
end end

View file

@ -1,6 +1,12 @@
# Markdown renderer
module Middleman::Renderers::Markdown module Middleman::Renderers::Markdown
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Require redcarpet gem
require "redcarpet" require "redcarpet"
# Forcably disable Redcarpet1 support. # Forcably disable Redcarpet1 support.
@ -8,17 +14,24 @@ module Middleman::Renderers::Markdown
# layer disables extensions. # layer disables extensions.
Object.send(:remove_const, :RedcarpetCompat) if defined? ::RedcarpetCompat Object.send(:remove_const, :RedcarpetCompat) if defined? ::RedcarpetCompat
# Set our preference for a markdown engine
app.set :markdown_engine, :redcarpet app.set :markdown_engine, :redcarpet
app.set :markdown_engine_prefix, ::Tilt app.set :markdown_engine_prefix, ::Tilt
# Once configuration is parsed
app.after_configuration do app.after_configuration do
# Look for the user's preferred engine
unless markdown_engine.nil? unless markdown_engine.nil?
# Map symbols to classes
if markdown_engine.is_a? Symbol if markdown_engine.is_a? Symbol
engine = engine.to_s engine = engine.to_s
engine = engine == "rdiscount" ? "RDiscount" : engine.camelize engine = engine == "rdiscount" ? "RDiscount" : engine.camelize
markdown_engine = markdown_engine_prefix.const_get("#{engine}Template") markdown_engine = markdown_engine_prefix.const_get("#{engine}Template")
end end
# Tell tilt to use that engine
::Tilt.prefer(markdown_engine) ::Tilt.prefer(markdown_engine)
end end
end end

View file

@ -1,8 +1,15 @@
# Pull in gems
require "sass"
require "sprockets" require "sprockets"
require "sprockets-sass" require "sprockets-sass"
# Sass renderer
module Middleman::Renderers::Sass module Middleman::Renderers::Sass
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Default sass options # Default sass options
app.set :sass, {} app.set :sass, {}
@ -10,8 +17,13 @@ module Middleman::Renderers::Sass
alias :included :registered alias :included :registered
end end
# A SassTemplate for Sprockets/Tilt which outputs debug messages
class SassPlusCSSFilenameTemplate < ::Sprockets::Sass::SassTemplate class SassPlusCSSFilenameTemplate < ::Sprockets::Sass::SassTemplate
# Add exception messaging # Add exception messaging
# @param [Class] context
# @param [Hash] locals
# @return [String]
def evaluate(context, locals, &block) def evaluate(context, locals, &block)
begin begin
super super
@ -21,6 +33,8 @@ module Middleman::Renderers::Sass
end end
protected protected
# Change Sass path, for url functions, to the build folder if we're building
# @return [Hash]
def sass_options def sass_options
location_of_sass_file = if @context.build? location_of_sass_file = if @context.build?
File.expand_path(@context.build_dir, @context.root) File.expand_path(@context.build_dir, @context.root)
@ -35,18 +49,27 @@ module Middleman::Renderers::Sass
super.merge(:css_filename => css_filename) super.merge(:css_filename => css_filename)
end end
end end
# Tell Sprockets to use our custom Sass template
::Sprockets.register_engine ".sass", SassPlusCSSFilenameTemplate ::Sprockets.register_engine ".sass", SassPlusCSSFilenameTemplate
# Tell Tilt to use it as well (for inline sass blocks)
::Tilt.register 'sass', SassPlusCSSFilenameTemplate ::Tilt.register 'sass', SassPlusCSSFilenameTemplate
::Tilt.prefer(SassPlusCSSFilenameTemplate) ::Tilt.prefer(SassPlusCSSFilenameTemplate)
# SCSS version of the above template
class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate
# Define the expected syntax for the template # Define the expected syntax for the template
# @return [Symbol]
def syntax def syntax
:scss :scss
end end
end end
# Tell Sprockets to use our custom Scss template
::Sprockets.register_engine ".scss", ScssPlusCSSFilenameTemplate ::Sprockets.register_engine ".scss", ScssPlusCSSFilenameTemplate
# Tell Tilt to use it as well (for inline scss blocks)
::Tilt.register 'scss', ScssPlusCSSFilenameTemplate ::Tilt.register 'scss', ScssPlusCSSFilenameTemplate
::Tilt.prefer(ScssPlusCSSFilenameTemplate) ::Tilt.prefer(ScssPlusCSSFilenameTemplate)
end end

View file

@ -1,11 +1,18 @@
# Slim renderer
module Middleman::Renderers::Slim module Middleman::Renderers::Slim
# Setup extension
class << self class << self
# Once registered
def registered(app) def registered(app)
# Slim is not included in the default gems, # Slim is not included in the default gems,
# but we'll support it if available. # but we'll support it if available.
begin begin
# Load gem
require "slim" require "slim"
# Setup Slim options to work with partials
Slim::Engine.set_default_options(:buffer => '@_out_buf', :generator => Temple::Generators::StringBuffer) if defined?(Slim) Slim::Engine.set_default_options(:buffer => '@_out_buf', :generator => Temple::Generators::StringBuffer) if defined?(Slim)
rescue LoadError rescue LoadError
end end