Rewritten core which makes better use of Tilt. Support for SCSS, Coffee and Less.
This commit is contained in:
parent
bccc6d2d74
commit
5523a10d9b
33
Rakefile
33
Rakefile
|
@ -13,24 +13,21 @@ begin
|
||||||
gem.authors = ["Thomas Reynolds"]
|
gem.authors = ["Thomas Reynolds"]
|
||||||
gem.rubyforge_project = "middleman"
|
gem.rubyforge_project = "middleman"
|
||||||
gem.executables = %w(mm-init mm-build mm-server)
|
gem.executables = %w(mm-init mm-build mm-server)
|
||||||
gem.add_dependency("rack")
|
gem.add_dependency("rack", "~>1.0")
|
||||||
gem.add_dependency("thin")
|
gem.add_dependency("thin", "~>1.2.0")
|
||||||
|
gem.add_dependency("shotgun", "~>0.8.0")
|
||||||
gem.add_dependency("shotgun", ">=0.8")
|
gem.add_dependency("templater", "~>1.0.0")
|
||||||
gem.add_dependency("templater")
|
gem.add_dependency("sprockets", "~>1.0.0")
|
||||||
gem.add_dependency("sprockets")
|
gem.add_dependency("sinatra", "~>1.0")
|
||||||
gem.add_dependency("sinatra", ">=1.0")
|
gem.add_dependency("sinatra-content-for", "~>0.2.0")
|
||||||
gem.add_dependency("sinatra-content-for")
|
gem.add_dependency("rack-test", "~>0.5.0")
|
||||||
gem.add_dependency("less")
|
gem.add_dependency("yui-compressor", "~>0.9.0")
|
||||||
gem.add_dependency("builder")
|
gem.add_dependency("haml", "~>3.0")
|
||||||
gem.add_dependency("rack-test")
|
gem.add_dependency("compass", "~>0.10.0")
|
||||||
gem.add_dependency("yui-compressor")
|
gem.add_dependency("json_pure", "~>1.4.0")
|
||||||
gem.add_dependency("haml", ">=3.0")
|
gem.add_dependency("smusher", "~>0.4.5")
|
||||||
gem.add_dependency("compass", ">=0.10")
|
gem.add_dependency("compass-slickmap", "~>0.3.0")
|
||||||
gem.add_dependency("fancy-buttons")
|
gem.add_dependency("livereload", "~>1.4.0")
|
||||||
gem.add_dependency("json_pure")
|
|
||||||
gem.add_dependency("smusher")
|
|
||||||
gem.add_dependency("compass-slickmap")
|
|
||||||
|
|
||||||
gem.add_development_dependency("rspec")
|
gem.add_development_dependency("rspec")
|
||||||
gem.add_development_dependency("cucumber")
|
gem.add_development_dependency("cucumber")
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
Feature: Automatically detect and insert image dimensions into tags
|
Feature: Automatically detect and insert image dimensions into tags
|
||||||
In order to speed up development and appease YSlow
|
In order to speed up development and appease YSlow
|
||||||
|
|
||||||
Scenario: Rendering an image with the feature enabled
|
|
||||||
Given "automatic_image_sizes" feature is "enabled"
|
|
||||||
When I go to "/auto-image-sizes.html"
|
|
||||||
Then I should see "width="
|
|
||||||
And I should see "height="
|
|
||||||
|
|
||||||
Scenario: Rendering an image with the feature disabled
|
Scenario: Rendering an image with the feature disabled
|
||||||
Given "automatic_image_sizes" feature is "disabled"
|
Given "automatic_image_sizes" feature is "disabled"
|
||||||
When I go to "/auto-image-sizes.html"
|
When I go to "/auto-image-sizes.html"
|
||||||
Then I should not see "width="
|
Then I should not see "width="
|
||||||
And I should not see "height="
|
And I should not see "height="
|
||||||
|
|
||||||
|
Scenario: Rendering an image with the feature enabled
|
||||||
|
Given "automatic_image_sizes" feature is "enabled"
|
||||||
|
When I go to "/auto-image-sizes.html"
|
||||||
|
Then I should see "width="
|
||||||
|
And I should see "height="
|
|
@ -1,16 +1,6 @@
|
||||||
Feature: Generate mtime-based query string for busting browser caches
|
Feature: Generate mtime-based query string for busting browser caches
|
||||||
In order to display the most recent content for IE & CDNs and appease YSlow
|
In order to display the most recent content for IE & CDNs and appease YSlow
|
||||||
|
|
||||||
Scenario: Rendering css with the feature enabled
|
|
||||||
Given "cache_buster" feature is "enabled"
|
|
||||||
When I go to "/stylesheets/relative_assets.css"
|
|
||||||
Then I should see "?"
|
|
||||||
|
|
||||||
Scenario: Rendering html with the feature enabled
|
|
||||||
Given "cache_buster" feature is "enabled"
|
|
||||||
When I go to "/cache-buster.html"
|
|
||||||
Then I should not see "?"
|
|
||||||
|
|
||||||
Scenario: Rendering css with the feature disabled
|
Scenario: Rendering css with the feature disabled
|
||||||
Given "cache_buster" feature is "disabled"
|
Given "cache_buster" feature is "disabled"
|
||||||
When I go to "/stylesheets/relative_assets.css"
|
When I go to "/stylesheets/relative_assets.css"
|
||||||
|
@ -20,3 +10,13 @@ Feature: Generate mtime-based query string for busting browser caches
|
||||||
Given "cache_buster" feature is "disabled"
|
Given "cache_buster" feature is "disabled"
|
||||||
When I go to "/cache-buster.html"
|
When I go to "/cache-buster.html"
|
||||||
Then I should not see "?"
|
Then I should not see "?"
|
||||||
|
|
||||||
|
Scenario: Rendering css with the feature enabled
|
||||||
|
Given "cache_buster" feature is "enabled"
|
||||||
|
When I go to "/stylesheets/relative_assets.css"
|
||||||
|
Then I should see "?"
|
||||||
|
|
||||||
|
Scenario: Rendering html with the feature enabled
|
||||||
|
Given "cache_buster" feature is "enabled"
|
||||||
|
When I go to "/cache-buster.html"
|
||||||
|
Then I should not see "?"
|
|
@ -1,22 +1,22 @@
|
||||||
Feature: Minify CSS
|
Feature: Minify CSS
|
||||||
In order reduce bytes sent to client and appease YSlow
|
In order reduce bytes sent to client and appease YSlow
|
||||||
|
|
||||||
Scenario: Rendering inline css with the feature enabled
|
|
||||||
Given "minify_css" feature is "enabled"
|
|
||||||
When I go to "/inline-css.html"
|
|
||||||
Then I should see "1" lines
|
|
||||||
|
|
||||||
Scenario: Rendering inline css with the feature disabled
|
Scenario: Rendering inline css with the feature disabled
|
||||||
Given "minify_css" feature is "disabled"
|
Given "minify_css" feature is "disabled"
|
||||||
When I go to "/inline-css.html"
|
When I go to "/inline-css.html"
|
||||||
Then I should see "4" lines
|
Then I should see "4" lines
|
||||||
|
|
||||||
Scenario: Rendering external css with the feature enabled
|
|
||||||
Given "minify_css" feature is "enabled"
|
|
||||||
When I go to "/stylesheets/site.css"
|
|
||||||
Then I should see "1" lines
|
|
||||||
|
|
||||||
Scenario: Rendering external css with the feature disabled
|
Scenario: Rendering external css with the feature disabled
|
||||||
Given "minify_css" feature is "disabled"
|
Given "minify_css" feature is "disabled"
|
||||||
When I go to "/stylesheets/site.css"
|
When I go to "/stylesheets/site.css"
|
||||||
Then I should see "51" lines
|
Then I should see "51" lines
|
||||||
|
|
||||||
|
Scenario: Rendering inline css with the feature enabled
|
||||||
|
Given "minify_css" feature is "enabled"
|
||||||
|
When I go to "/inline-css.html"
|
||||||
|
Then I should see "1" lines
|
||||||
|
|
||||||
|
Scenario: Rendering external css with the feature enabled
|
||||||
|
Given "minify_css" feature is "enabled"
|
||||||
|
When I go to "/stylesheets/site.css"
|
||||||
|
Then I should see "1" lines
|
|
@ -1,12 +1,12 @@
|
||||||
Feature: Minify Javascript
|
Feature: Minify Javascript
|
||||||
In order reduce bytes sent to client and appease YSlow
|
In order reduce bytes sent to client and appease YSlow
|
||||||
|
|
||||||
Scenario: Rendering inline js with the feature enabled
|
|
||||||
Given "minify_javascript" feature is "enabled"
|
|
||||||
When I go to "/inline-js.html"
|
|
||||||
Then I should see "1" lines
|
|
||||||
|
|
||||||
Scenario: Rendering inline js with the feature disabled
|
Scenario: Rendering inline js with the feature disabled
|
||||||
Given "minify_javascript" feature is "disabled"
|
Given "minify_javascript" feature is "disabled"
|
||||||
When I go to "/inline-js.html"
|
When I go to "/inline-js.html"
|
||||||
Then I should see "10" lines
|
Then I should see "10" lines
|
||||||
|
|
||||||
|
Scenario: Rendering inline js with the feature enabled
|
||||||
|
Given "minify_javascript" feature is "enabled"
|
||||||
|
When I go to "/inline-js.html"
|
||||||
|
Then I should see "1" lines
|
|
@ -1,4 +1,5 @@
|
||||||
Given /^I am using an asset host$/ do
|
Given /^I am using an asset host$/ do
|
||||||
|
Middleman::Base.enable :asset_host
|
||||||
Middleman::Base.set :asset_host do |asset|
|
Middleman::Base.set :asset_host do |asset|
|
||||||
"http://assets%d.example.com" % (asset.hash % 4)
|
"http://assets%d.example.com" % (asset.hash % 4)
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,6 @@ Then /^I should not see "([^\"]*)"$/ do |expected|
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I should see "([^\"]*)" lines$/ do |lines|
|
Then /^I should see "([^\"]*)" lines$/ do |lines|
|
||||||
puts @browser.last_response.body
|
$stderr.puts @browser.last_response.body
|
||||||
@browser.last_response.body.chomp.split($/).length.should == lines.to_i
|
@browser.last_response.body.chomp.split($/).length.should == lines.to_i
|
||||||
end
|
end
|
|
@ -4,22 +4,5 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
|
|
||||||
module Rack
|
|
||||||
autoload :Sprockets, "middleman/rack/sprockets"
|
|
||||||
autoload :MinifyJavascript, "middleman/rack/minify_javascript"
|
|
||||||
autoload :MinifyCSS, "middleman/rack/minify_css"
|
|
||||||
end
|
|
||||||
|
|
||||||
module Renderers
|
|
||||||
autoload :ERb, "middleman/renderers/erb"
|
|
||||||
autoload :Builder, "middleman/renderers/builder"
|
|
||||||
autoload :Less, "middleman/renderers/less"
|
|
||||||
end
|
|
||||||
|
|
||||||
autoload :Base, "middleman/base"
|
autoload :Base, "middleman/base"
|
||||||
autoload :Haml, "middleman/renderers/haml"
|
|
||||||
autoload :Sass, "middleman/renderers/sass"
|
|
||||||
autoload :Helpers, "middleman/helpers"
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
33
lib/middleman/assets.rb
Normal file
33
lib/middleman/assets.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
module Middleman
|
||||||
|
module Assets
|
||||||
|
@@asset_handler_map = []
|
||||||
|
@@asset_handler_stack = []
|
||||||
|
|
||||||
|
def self.register(handler_name, &block)
|
||||||
|
if block_given?
|
||||||
|
@@asset_handler_stack << block
|
||||||
|
@@asset_handler_map << handler_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_url(path, prefix="", request=nil)
|
||||||
|
@@asset_handler_stack.last.call(path, prefix, request)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.before(position, *args)
|
||||||
|
current_index = @@asset_handler_map.index(position)
|
||||||
|
return nil unless current_index
|
||||||
|
|
||||||
|
previous = current_index - 1
|
||||||
|
if (previous >= 0) && (previous < @@asset_handler_map.length)
|
||||||
|
@@asset_handler_stack[previous].call(*args)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Assets.register :base do |path, prefix, request|
|
||||||
|
path.include?("://") ? path : File.join(Middleman::Base.http_prefix || "/", prefix, path)
|
||||||
|
end
|
|
@ -7,7 +7,6 @@ class Sinatra::Request
|
||||||
end
|
end
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Rack; end
|
|
||||||
class Base < Sinatra::Base
|
class Base < Sinatra::Base
|
||||||
set :app_file, __FILE__
|
set :app_file, __FILE__
|
||||||
set :root, ENV["MM_DIR"] || Dir.pwd
|
set :root, ENV["MM_DIR"] || Dir.pwd
|
||||||
|
@ -42,10 +41,9 @@ module Middleman
|
||||||
def self.set(option, value=self, &block)
|
def self.set(option, value=self, &block)
|
||||||
if block_given?
|
if block_given?
|
||||||
value = Proc.new { block }
|
value = Proc.new { block }
|
||||||
super(option, value, &nil)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
super(option, value, &nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@afters = []
|
@@afters = []
|
||||||
|
@ -59,22 +57,6 @@ module Middleman
|
||||||
::Rack::Mime::MIME_TYPES[ext.to_s] = type
|
::Rack::Mime::MIME_TYPES[ext.to_s] = type
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convenience function to discover if a template exists for the requested renderer (haml, sass, etc)
|
|
||||||
def template_exists?(path, renderer=nil)
|
|
||||||
template_path = path.dup
|
|
||||||
template_path << ".#{renderer}" if renderer
|
|
||||||
File.readable? File.join(settings.views, template_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Base case renderer (do nothing), Should be over-ridden
|
|
||||||
module StaticRender
|
|
||||||
def render_path(path, layout)
|
|
||||||
return false if !template_exists?(path, :erb)
|
|
||||||
erb(path.to_sym, :layout => layout)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
include StaticRender
|
|
||||||
|
|
||||||
@@layout = nil
|
@@layout = nil
|
||||||
def self.page(url, options={}, &block)
|
def self.page(url, options={}, &block)
|
||||||
layout = @@layout
|
layout = @@layout
|
||||||
|
@ -114,44 +96,33 @@ module Middleman
|
||||||
path << settings.index_file if path.match(%r{/$})
|
path << settings.index_file if path.match(%r{/$})
|
||||||
path.gsub!(%r{^/}, '')
|
path.gsub!(%r{^/}, '')
|
||||||
|
|
||||||
# If the enabled renderers succeed, return the content, mime-type and an HTTP 200
|
template_path = locate_template_file(path)
|
||||||
if content = render_path(path, layout)
|
if template_path
|
||||||
content_type mime_type(File.extname(path)), :charset => 'utf-8'
|
content_type mime_type(File.extname(path)), :charset => 'utf-8'
|
||||||
|
|
||||||
|
renderer = Middleman::Renderers.get_method(template_path)
|
||||||
|
if respond_to? renderer
|
||||||
status 200
|
status 200
|
||||||
content
|
return send(renderer, path.to_sym, { :layout => layout })
|
||||||
else
|
end
|
||||||
|
end
|
||||||
|
|
||||||
status 404
|
status 404
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def locate_template_file(path)
|
||||||
|
template_path = File.join(settings.views, "#{path}.*")
|
||||||
|
Dir.glob(template_path).first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "middleman/renderers/erb"
|
require "middleman/assets"
|
||||||
require "middleman/renderers/haml"
|
require "middleman/renderers"
|
||||||
require "middleman/renderers/sass"
|
require "middleman/features"
|
||||||
require "middleman/renderers/less"
|
|
||||||
require "middleman/renderers/builder"
|
|
||||||
|
|
||||||
|
# The Rack App
|
||||||
class Middleman::Base
|
class Middleman::Base
|
||||||
helpers Middleman::Helpers
|
|
||||||
|
|
||||||
# Features disabled by default
|
|
||||||
enable :asset_host
|
|
||||||
disable :slickmap
|
|
||||||
disable :cache_buster
|
|
||||||
disable :minify_css
|
|
||||||
disable :minify_javascript
|
|
||||||
disable :relative_assets
|
|
||||||
disable :smush_pngs
|
|
||||||
disable :automatic_image_sizes
|
|
||||||
disable :relative_assets
|
|
||||||
disable :cache_buster
|
|
||||||
disable :ugly_haml
|
|
||||||
|
|
||||||
# Default build features
|
|
||||||
configure :build do
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.new(*args, &block)
|
def self.new(*args, &block)
|
||||||
# Check for and evaluate local configuration
|
# Check for and evaluate local configuration
|
||||||
local_config = File.join(self.root, "init.rb")
|
local_config = File.join(self.root, "init.rb")
|
||||||
|
@ -164,22 +135,11 @@ class Middleman::Base
|
||||||
# loop over enabled feature
|
# loop over enabled feature
|
||||||
features.flatten.each do |feature_name|
|
features.flatten.each do |feature_name|
|
||||||
next unless send(:"#{feature_name}?")
|
next unless send(:"#{feature_name}?")
|
||||||
|
$stderr.puts "== Enabling: #{feature_name.to_s.capitalize}" if logging?
|
||||||
feature_path = "features/#{feature_name}"
|
Middleman::Features.run(feature_name, self)
|
||||||
if File.exists? File.join(File.dirname(__FILE__), "#{feature_path}.rb")
|
|
||||||
puts "== Enabling: #{feature_name.to_s.capitalize}" if logging?
|
|
||||||
require "middleman/#{feature_path}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
use ::Rack::ConditionalGet if environment == :development
|
use ::Rack::ConditionalGet if environment == :development
|
||||||
use Middleman::Rack::MinifyJavascript if minify_javascript?
|
|
||||||
use Middleman::Rack::MinifyCSS if minify_css?
|
|
||||||
|
|
||||||
# Built-in javascript combination
|
|
||||||
use Middleman::Rack::Sprockets, :root => Middleman::Base.root,
|
|
||||||
:load_path => [ File.join("public", Middleman::Base.js_dir),
|
|
||||||
File.join("views", Middleman::Base.js_dir) ]
|
|
||||||
|
|
||||||
@@afters.each { |block| class_eval(&block) }
|
@@afters.each { |block| class_eval(&block) }
|
||||||
|
|
||||||
|
|
40
lib/middleman/features.rb
Normal file
40
lib/middleman/features.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
module Middleman
|
||||||
|
module Features
|
||||||
|
# Top-level method to register a new feature
|
||||||
|
@@features = {}
|
||||||
|
def self.register(feature_name, feature_class=nil, options={})
|
||||||
|
@@features[feature_name] = feature_class
|
||||||
|
|
||||||
|
# Default to disabled, unless the class asks to auto-enable
|
||||||
|
activate_method = (options.has_key?(:auto_enable) && options[:auto_enable]) ? :enable : :disable
|
||||||
|
Middleman::Base.send(activate_method, feature_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.run(feature_name, scope)
|
||||||
|
feature_class = @@features[feature_name]
|
||||||
|
feature_class.new(scope) unless feature_class.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.all
|
||||||
|
@@features
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%w(asset_host
|
||||||
|
automatic_image_sizes
|
||||||
|
cache_buster
|
||||||
|
default_helpers
|
||||||
|
livereload
|
||||||
|
minify_css
|
||||||
|
minify_javascript
|
||||||
|
relative_assets
|
||||||
|
slickmap
|
||||||
|
smush_pngs
|
||||||
|
sprockets
|
||||||
|
ugly_haml).each do |feature|
|
||||||
|
|
||||||
|
require File.join("middleman/features", feature)
|
||||||
|
|
||||||
|
end
|
|
@ -1,24 +1,21 @@
|
||||||
class Middleman::Base
|
class Middleman::Features::AssetHost
|
||||||
after_feature_init do
|
def initialize(app)
|
||||||
::Compass.configuration do |config|
|
Middleman::Base.after_feature_init do
|
||||||
config.asset_host(&self.asset_host)
|
if Middleman::Base.asset_host.is_a?(Proc)
|
||||||
|
::Compass.configuration.asset_host(&Middleman::Base.asset_host)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end if self.enabled?(:asset_host) && self.asset_host && self.asset_host.is_a?(Proc)
|
|
||||||
end
|
|
||||||
|
|
||||||
class << Middleman::Base
|
Middleman::Assets.register :asset_host do |path, prefix, request|
|
||||||
alias_method :pre_asset_host_asset_url, :asset_url
|
original_output = Middleman::Assets.before(:asset_host, path, prefix, request)
|
||||||
def asset_url(path, prefix="", request=nil)
|
|
||||||
original_output = pre_asset_host_asset_url(path, prefix, request)
|
|
||||||
|
|
||||||
valid_extensions = %w(.png .gif .jpg .jpeg .js .css)
|
valid_extensions = %w(.png .gif .jpg .jpeg .js .css)
|
||||||
|
|
||||||
if !self.enabled?(:asset_host) || path.include?("://") || !valid_extensions.include?(File.extname(path)) || !self.asset_host || !self.asset_host.is_a?(Proc) || !self.asset_host.respond_to?(:call)
|
asset_prefix = Middleman::Base.asset_host.call(original_output)
|
||||||
return original_output
|
|
||||||
|
File.join(asset_prefix, original_output)
|
||||||
end
|
end
|
||||||
|
|
||||||
asset_prefix = self.asset_host.call(original_output)
|
|
||||||
|
|
||||||
return File.join(asset_prefix, original_output)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :asset_host, Middleman::Features::AssetHost
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
require "middleman/fastimage"
|
class Middleman::Features::AutomaticImageSizes
|
||||||
|
def initialize(app)
|
||||||
|
require "middleman/features/automatic_image_sizes/fastimage"
|
||||||
|
|
||||||
class Middleman::Base
|
Middleman::Base.send :alias_method, :pre_automatic_image_tag, :image_tag
|
||||||
alias_method :pre_automatic_image_tag, :image_tag
|
Middleman::Base.helpers do
|
||||||
helpers do
|
|
||||||
def image_tag(path, params={})
|
def image_tag(path, params={})
|
||||||
if !self.enabled?(:automatic_image_sizes)
|
|
||||||
return pre_automatic_image_tag(path, params)
|
|
||||||
end
|
|
||||||
|
|
||||||
if (!params[:width] || !params[:height]) && !path.include?("://")
|
if (!params[:width] || !params[:height]) && !path.include?("://")
|
||||||
params[:alt] ||= ""
|
params[:alt] ||= ""
|
||||||
http_prefix = settings.http_images_path rescue settings.images_dir
|
http_prefix = settings.http_images_path rescue settings.images_dir
|
||||||
|
@ -28,4 +25,7 @@ class Middleman::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :automatic_image_sizes, Middleman::Features::AutomaticImageSizes
|
|
@ -1,50 +1,43 @@
|
||||||
class Middleman::Base
|
class Middleman::Features::CacheBuster
|
||||||
after_feature_init do
|
def initialize(app)
|
||||||
::Compass.configuration do |config|
|
Middleman::Assets.register :cache_buster do |path, prefix, request|
|
||||||
if self.enabled?(:cache_buster)
|
http_path = Middleman::Assets.before(:cache_buster, path, prefix, request)
|
||||||
config.asset_cache_buster do |path, real_path|
|
|
||||||
real_path = real_path.path if real_path.is_a? File
|
|
||||||
real_path = real_path.gsub(File.join(self.root, self.build_dir), self.public)
|
|
||||||
if File.readable?(real_path)
|
|
||||||
File.mtime(real_path).strftime("%s")
|
|
||||||
else
|
|
||||||
$stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
config.asset_cache_buster { false }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
::Compass.configure_sass_plugin!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class << Middleman::Base
|
|
||||||
alias_method :pre_cache_buster_asset_url, :asset_url
|
|
||||||
def asset_url(path, prefix="", request=nil)
|
|
||||||
http_path = pre_cache_buster_asset_url(path, prefix, request)
|
|
||||||
|
|
||||||
return http_path unless self.enabled?(:cache_buster)
|
|
||||||
|
|
||||||
if http_path.include?("://") || !%w(.css .png .jpg .js .gif).include?(File.extname(http_path))
|
if http_path.include?("://") || !%w(.css .png .jpg .js .gif).include?(File.extname(http_path))
|
||||||
http_path
|
http_path
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
prefix = self.images_dir if prefix == self.http_images_path
|
prefix = Middleman::Base.images_dir if prefix == Middleman::Base.http_images_path
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
|
||||||
real_path_static = File.join(self.public, prefix, path)
|
real_path_static = File.join(Middleman::Base.public, prefix, path)
|
||||||
|
|
||||||
if File.readable?(real_path_static)
|
if File.readable?(real_path_static)
|
||||||
http_path << "?" + File.mtime(real_path_static).strftime("%s")
|
http_path << "?" + File.mtime(real_path_static).strftime("%s")
|
||||||
elsif Middleman::Base.environment == "build"
|
elsif Middleman::Base.environment == "build"
|
||||||
real_path_dynamic = File.join(self.root, self.build_dir, prefix, path)
|
real_path_dynamic = File.join(Middleman::Base.root, Middleman::Base.build_dir, prefix, path)
|
||||||
http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
|
http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
|
||||||
end
|
end
|
||||||
|
|
||||||
http_path
|
http_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Base.after_feature_init do
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
config.asset_cache_buster do |path, real_path|
|
||||||
|
real_path = real_path.path if real_path.is_a? File
|
||||||
|
real_path = real_path.gsub(File.join(Middleman::Base.root, Middleman::Base.build_dir), Middleman::Base.public)
|
||||||
|
if File.readable?(real_path)
|
||||||
|
File.mtime(real_path).strftime("%s")
|
||||||
|
else
|
||||||
|
$stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :cache_buster, Middleman::Features::CacheBuster
|
19
lib/middleman/helpers.rb → lib/middleman/features/default_helpers.rb
Executable file → Normal file
19
lib/middleman/helpers.rb → lib/middleman/features/default_helpers.rb
Executable file → Normal file
|
@ -1,15 +1,9 @@
|
||||||
module Middleman
|
class Middleman::Features::DefaultHelpers
|
||||||
class Base
|
def initialize(app)
|
||||||
def self.asset_url(path, prefix="", request=nil)
|
Middleman::Base.helpers Helpers
|
||||||
path.include?("://") ? path : File.join(self.http_prefix || "/", prefix, path)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Helpers
|
module Helpers
|
||||||
def haml_partial(name, options = {})
|
|
||||||
haml name.to_sym, options.merge(:layout => false)
|
|
||||||
end
|
|
||||||
|
|
||||||
def auto_stylesheet_link_tag(separator="/")
|
def auto_stylesheet_link_tag(separator="/")
|
||||||
path = request.path_info.dup
|
path = request.path_info.dup
|
||||||
path << self.class.index_file if path.match(%r{/$})
|
path << self.class.index_file if path.match(%r{/$})
|
||||||
|
@ -19,8 +13,9 @@ module Middleman
|
||||||
|
|
||||||
css_file = File.join(self.class.public, self.class.css_dir, "#{path}.css")
|
css_file = File.join(self.class.public, self.class.css_dir, "#{path}.css")
|
||||||
sass_file = File.join(self.class.views, self.class.css_dir, "#{path}.css.sass")
|
sass_file = File.join(self.class.views, self.class.css_dir, "#{path}.css.sass")
|
||||||
|
scss_file = File.join(self.class.views, self.class.css_dir, "#{path}.css.scss")
|
||||||
|
|
||||||
if File.exists?(css_file) || File.exists?(sass_file)
|
if File.exists?(css_file) || File.exists?(sass_file) || File.exists?(scss_file)
|
||||||
stylesheet_link_tag "#{path}.css"
|
stylesheet_link_tag "#{path}.css"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,7 +33,7 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def asset_url(path, prefix="")
|
def asset_url(path, prefix="")
|
||||||
self.class.asset_url(path, prefix, request)
|
Middleman::Assets.get_url(path, prefix, request)
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to(title, url="#", params={})
|
def link_to(title, url="#", params={})
|
||||||
|
@ -69,3 +64,5 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :default_helpers, Middleman::Features::DefaultHelpers, { :auto_enable => true }
|
19
lib/middleman/features/livereload.rb
Normal file
19
lib/middleman/features/livereload.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
class Middleman::Features::LiveReload
|
||||||
|
def initialize(app)
|
||||||
|
return unless Middleman::Base.environment == :development
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'livereload'
|
||||||
|
rescue LoadError
|
||||||
|
puts "Livereload not available. Install it with: gem install livereload"
|
||||||
|
end
|
||||||
|
|
||||||
|
new_config = ::LiveReload::Config.new do |config|
|
||||||
|
config.exts = %w(haml sass scss coffee less builder)
|
||||||
|
end
|
||||||
|
|
||||||
|
::LiveReload.run [Middleman::Base.public, Middleman::Base.views], new_config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :livereload, Middleman::Features::LiveReload
|
|
@ -0,0 +1,9 @@
|
||||||
|
class Middleman::Features::MinifyCSS
|
||||||
|
def initialize(app)
|
||||||
|
Middleman::Base.after_feature_init do
|
||||||
|
::Compass.configuration.output_style = :compressed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :minify_css, Middleman::Features::MinifyCSS
|
|
@ -1,22 +1,20 @@
|
||||||
module Middleman
|
class Middleman::Features::MinifyJavascript
|
||||||
module Minified
|
def initialize(app)
|
||||||
|
Haml::Javascript.send :include, ::Haml::Filters::Base
|
||||||
|
|
||||||
|
require "middleman/features/minify_javascript/rack"
|
||||||
|
app.use Middleman::Rack::MinifyJavascript
|
||||||
|
end
|
||||||
|
|
||||||
|
module Haml
|
||||||
module Javascript
|
module Javascript
|
||||||
include ::Haml::Filters::Base
|
|
||||||
def render_with_options(text, options)
|
def render_with_options(text, options)
|
||||||
if Middleman::Base.respond_to?(:minify_javascript?) && Middleman::Base.minify_javascript?
|
|
||||||
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
||||||
data = compressor.compress(text)
|
data = compressor.compress(text)
|
||||||
%Q{<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script>}
|
%Q{<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script>}
|
||||||
else
|
|
||||||
<<END
|
|
||||||
<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>
|
|
||||||
//<![CDATA[
|
|
||||||
#{text.rstrip.gsub("\n", "\n ")}
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
END
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :minify_javascript, Middleman::Features::MinifyJavascript
|
31
lib/middleman/features/minify_javascript/rack.rb
Normal file
31
lib/middleman/features/minify_javascript/rack.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
begin
|
||||||
|
require "yui/compressor"
|
||||||
|
rescue LoadError
|
||||||
|
puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Rack
|
||||||
|
|
||||||
|
class MinifyJavascript
|
||||||
|
def initialize(app, options={})
|
||||||
|
@app = app
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
status, headers, response = @app.call(env)
|
||||||
|
|
||||||
|
if env["PATH_INFO"].match(/\.js$/)
|
||||||
|
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
||||||
|
|
||||||
|
uncompressed_source = response.is_a?(::Rack::File) ? File.read(response.path) : response
|
||||||
|
response = compressor.compress(uncompressed_source)
|
||||||
|
headers["Content-Length"] = ::Rack::Utils.bytesize(response).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
[status, headers, response]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,35 +1,21 @@
|
||||||
class Middleman::Base
|
class Middleman::Features::RelativeAssets
|
||||||
after_feature_init do
|
def initialize(app)
|
||||||
::Compass.configuration do |config|
|
::Compass.configuration.relative_assets = true
|
||||||
config.relative_assets = Proc.new do
|
|
||||||
Middleman::Base.enabled?(:relative_assets)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
::Compass.configure_sass_plugin!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class << Middleman::Base
|
|
||||||
alias_method :pre_relative_asset_url, :asset_url
|
|
||||||
def asset_url(path, prefix="", request=nil)
|
|
||||||
if !self.enabled?(:relative_assets)
|
|
||||||
return pre_relative_asset_url(path, prefix, request)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
Middleman::Assets.register :relative_assets do |path, prefix, request|
|
||||||
begin
|
begin
|
||||||
prefix = self.images_dir if prefix == self.http_images_path
|
prefix = Middleman::Base.images_dir if prefix == Middleman::Base.http_images_path
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
|
||||||
if path.include?("://")
|
if path.include?("://")
|
||||||
pre_relative_asset_url(path, prefix, request)
|
Middleman::Assets.before(:relative_assets, path, prefix, request)
|
||||||
elsif path[0,1] == "/"
|
elsif path[0,1] == "/"
|
||||||
path
|
path
|
||||||
else
|
else
|
||||||
path = File.join(prefix, path) if prefix.length > 0
|
path = File.join(prefix, path) if prefix.length > 0
|
||||||
request_path = request.path_info.dup
|
request_path = request.path_info.dup
|
||||||
request_path << self.index_file if path.match(%r{/$})
|
request_path << Middleman::Base.index_file if path.match(%r{/$})
|
||||||
request_path.gsub!(%r{^/}, '')
|
request_path.gsub!(%r{^/}, '')
|
||||||
parts = request_path.split('/')
|
parts = request_path.split('/')
|
||||||
|
|
||||||
|
@ -43,4 +29,7 @@ class << Middleman::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :relative_assets, Middleman::Features::RelativeAssets
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
begin
|
|
||||||
require 'slickmap'
|
|
||||||
::Compass.configure_sass_plugin!
|
|
||||||
rescue LoadError
|
|
||||||
puts "Slickmap not available. Install it with: gem install compass-slickmap"
|
|
||||||
end
|
|
||||||
|
|
||||||
if Middleman::Base.environment == "build"
|
|
||||||
Middleman::Builder.template :slickmap, "sitemap.html", "sitemap.html"
|
|
||||||
end
|
|
||||||
|
|
||||||
Entry = Struct.new(:dir, :children)
|
Entry = Struct.new(:dir, :children)
|
||||||
|
|
||||||
class Middleman::Base
|
class Middleman::Features::Slickmap
|
||||||
|
def initialize(app)
|
||||||
|
require 'slickmap'
|
||||||
|
|
||||||
|
if Middleman::Base.environment == "build"
|
||||||
|
Middleman::Builder.template :slickmap, "sitemap.html", "sitemap.html"
|
||||||
|
end
|
||||||
|
|
||||||
def build_sitemap(&block)
|
def build_sitemap(&block)
|
||||||
@@utility = []
|
@@utility = []
|
||||||
[recurse_sitemap(Middleman::Base.views, &block), @@utility]
|
[recurse_sitemap(Middleman::Base.views, &block), @@utility]
|
||||||
|
@ -42,7 +38,7 @@ class Middleman::Base
|
||||||
entry
|
entry
|
||||||
end
|
end
|
||||||
|
|
||||||
helpers do
|
Middleman::Base.helpers do
|
||||||
def sitemap_node(n, first=false)
|
def sitemap_node(n, first=false)
|
||||||
if n.children.length < 1
|
if n.children.length < 1
|
||||||
if !first && File.extname(n.dir).length > 0
|
if !first && File.extname(n.dir).length > 0
|
||||||
|
@ -76,7 +72,7 @@ class Middleman::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/sitemap.html' do
|
Middleman::Base.get '/sitemap.html' do
|
||||||
# Return :utility to put it util top menu. False to ignore
|
# Return :utility to put it util top menu. False to ignore
|
||||||
@tree, @utility = build_sitemap do |file_name|
|
@tree, @utility = build_sitemap do |file_name|
|
||||||
:valid
|
:valid
|
||||||
|
@ -84,9 +80,12 @@ class Middleman::Base
|
||||||
haml :sitemap, :layout => false
|
haml :sitemap, :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
use_in_file_templates!
|
Middleman::Base.use_in_file_templates!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :slickmap, Middleman::Features::Slickmap
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
@@ sitemap
|
@@ sitemap
|
||||||
|
@ -97,7 +96,7 @@ __END__
|
||||||
%title Sitemap
|
%title Sitemap
|
||||||
%style{ :type => "text/css" }
|
%style{ :type => "text/css" }
|
||||||
:sass
|
:sass
|
||||||
@import slickmap.sass
|
@import "slickmap"
|
||||||
+slickmap
|
+slickmap
|
||||||
:javascript
|
:javascript
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
require "middleman/builder"
|
class Middleman::Features::SmushPngs
|
||||||
|
def initialize(app)
|
||||||
|
require "middleman/builder"
|
||||||
|
|
||||||
module Middleman
|
Middleman::Base.alias_method :pre_smush_after_run, :after_run
|
||||||
class Builder
|
Middleman::Base.define_method :after_run do
|
||||||
alias_method :pre_smush_after_run, :after_run
|
|
||||||
def after_run
|
|
||||||
pre_smush_after_run
|
pre_smush_after_run
|
||||||
smush_dir = File.join(Middleman::Base.build_dir, Middleman::Base.images_dir)
|
smush_dir = File.join(Middleman::Base.build_dir, Middleman::Base.images_dir)
|
||||||
|
|
||||||
|
@ -34,3 +34,5 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :smush_pngs, Middleman::Features::SmushPngs
|
13
lib/middleman/features/sprockets.rb
Normal file
13
lib/middleman/features/sprockets.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class Middleman::Features::Sprockets
|
||||||
|
def initialize(app)
|
||||||
|
require "middleman/features/sprockets/rack"
|
||||||
|
app.use Middleman::Rack::Sprockets,
|
||||||
|
:root => Middleman::Base.root,
|
||||||
|
:load_path => [ File.join("public", Middleman::Base.js_dir),
|
||||||
|
File.join("views", Middleman::Base.js_dir) ]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :sprockets, Middleman::Features::Sprockets, { :auto_enable => true }
|
||||||
|
|
||||||
|
|
64
lib/middleman/features/sprockets/rack.rb
Normal file
64
lib/middleman/features/sprockets/rack.rb
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
require 'sprockets'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Rack
|
||||||
|
|
||||||
|
class Sprockets
|
||||||
|
def initialize(app, options={})
|
||||||
|
@app = app
|
||||||
|
@options = options
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
if env["PATH_INFO"].match(/\.js$/)
|
||||||
|
public_file_path = File.join(Middleman::Base.public, env["PATH_INFO"])
|
||||||
|
view_file_path = File.join(Middleman::Base.views, env["PATH_INFO"])
|
||||||
|
|
||||||
|
source_file = ::Rack::File.new(Middleman::Base.public) if File.exists?(public_file_path)
|
||||||
|
source_file = ::Rack::File.new(Middleman::Base.views) if File.exists?(view_file_path)
|
||||||
|
|
||||||
|
if source_file
|
||||||
|
status, headers, response = source_file.call(env)
|
||||||
|
secretary = ::Sprockets::Secretary.new(@options.merge( :source_files => [ response.path ] ))
|
||||||
|
response = secretary.concatenation.to_s
|
||||||
|
headers["Content-Length"] = ::Rack::Utils.bytesize(response).to_s
|
||||||
|
return [status, headers, response]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sprockets ruby 1.9 duckpunch
|
||||||
|
module Sprockets
|
||||||
|
class SourceFile
|
||||||
|
def source_lines
|
||||||
|
@lines ||= begin
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
comments = []
|
||||||
|
File.open(pathname.absolute_location, 'rb') do |file|
|
||||||
|
file.each do |line|
|
||||||
|
lines << line = SourceLine.new(self, line, file.lineno)
|
||||||
|
|
||||||
|
if line.begins_pdoc_comment? || comments.any?
|
||||||
|
comments << line
|
||||||
|
end
|
||||||
|
|
||||||
|
if line.ends_multiline_comment?
|
||||||
|
if line.ends_pdoc_comment?
|
||||||
|
comments.each { |l| l.comment! }
|
||||||
|
end
|
||||||
|
comments.clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lines
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
lib/middleman/features/ugly_haml.rb
Normal file
7
lib/middleman/features/ugly_haml.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class Middleman::Features::UglyHaml
|
||||||
|
def initialize(app)
|
||||||
|
Middleman::Base.set :haml, Middleman::Base.settings.haml.merge({ :ugly_haml => true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Features.register :ugly_haml, Middleman::Features::UglyHaml
|
|
@ -1,25 +0,0 @@
|
||||||
begin
|
|
||||||
require "yui/compressor"
|
|
||||||
rescue LoadError
|
|
||||||
puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Rack::MinifyCSS
|
|
||||||
def initialize(app, options={})
|
|
||||||
@app = app
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @app.call(env)
|
|
||||||
|
|
||||||
if Middleman::Base.enabled?(:minify_css) && env["PATH_INFO"].match(/\.css$/)
|
|
||||||
compressor = ::YUI::CssCompressor.new
|
|
||||||
|
|
||||||
uncompressed_source = response.is_a?(::Rack::File) ? File.read(response.path) : response
|
|
||||||
response = compressor.compress(uncompressed_source)
|
|
||||||
headers["Content-Length"] = ::Rack::Utils.bytesize(response).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,25 +0,0 @@
|
||||||
begin
|
|
||||||
require "yui/compressor"
|
|
||||||
rescue LoadError
|
|
||||||
puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Rack::MinifyJavascript
|
|
||||||
def initialize(app, options={})
|
|
||||||
@app = app
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @app.call(env)
|
|
||||||
|
|
||||||
if env["PATH_INFO"].match(/\.js$/)
|
|
||||||
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
|
||||||
|
|
||||||
uncompressed_source = response.is_a?(::Rack::File) ? File.read(response.path) : response
|
|
||||||
response = compressor.compress(uncompressed_source)
|
|
||||||
headers["Content-Length"] = ::Rack::Utils.bytesize(response).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,61 +0,0 @@
|
||||||
require 'sprockets'
|
|
||||||
|
|
||||||
class Middleman::Rack::Sprockets
|
|
||||||
def initialize(app, options={})
|
|
||||||
@app = app
|
|
||||||
@options = options
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
if env["PATH_INFO"].match(/\.js$/)
|
|
||||||
public_file_path = File.join(Middleman::Base.public, env["PATH_INFO"])
|
|
||||||
view_file_path = File.join(Middleman::Base.views, env["PATH_INFO"])
|
|
||||||
|
|
||||||
source_file = Rack::File.new(Middleman::Base.public) if File.exists?(public_file_path)
|
|
||||||
source_file = Rack::File.new(Middleman::Base.views) if File.exists?(view_file_path)
|
|
||||||
|
|
||||||
if source_file
|
|
||||||
status, headers, response = source_file.call(env)
|
|
||||||
secretary = ::Sprockets::Secretary.new(@options.merge( :source_files => [ response.path ] ))
|
|
||||||
response = secretary.concatenation.to_s
|
|
||||||
headers["Content-Length"] = ::Rack::Utils.bytesize(response).to_s
|
|
||||||
return [status, headers, response]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@app.call(env)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Middleman::Base.supported_formats << "js"
|
|
||||||
|
|
||||||
# Sprockets ruby 1.9 duckpunch
|
|
||||||
module Sprockets
|
|
||||||
class SourceFile
|
|
||||||
def source_lines
|
|
||||||
@lines ||= begin
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
comments = []
|
|
||||||
File.open(pathname.absolute_location, 'rb') do |file|
|
|
||||||
file.each do |line|
|
|
||||||
lines << line = SourceLine.new(self, line, file.lineno)
|
|
||||||
|
|
||||||
if line.begins_pdoc_comment? || comments.any?
|
|
||||||
comments << line
|
|
||||||
end
|
|
||||||
|
|
||||||
if line.ends_multiline_comment?
|
|
||||||
if line.ends_pdoc_comment?
|
|
||||||
comments.each { |l| l.comment! }
|
|
||||||
end
|
|
||||||
comments.clear
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
lines
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
26
lib/middleman/renderers.rb
Normal file
26
lib/middleman/renderers.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module Middleman
|
||||||
|
|
||||||
|
module Renderers
|
||||||
|
@@render_method_for_template_types = {}
|
||||||
|
|
||||||
|
def self.register(method_name, template_type)
|
||||||
|
@@render_method_for_template_types[template_type.to_s] = method_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_method(template_path)
|
||||||
|
template_type = Tilt[template_path].to_s
|
||||||
|
@@render_method_for_template_types[template_type]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Types built into Sinatra
|
||||||
|
Middleman::Renderers.register(:less, Tilt::LessTemplate)
|
||||||
|
Middleman::Renderers.register(:haml, Tilt::HamlTemplate)
|
||||||
|
Middleman::Renderers.register(:builder, Tilt::BuilderTemplate)
|
||||||
|
Middleman::Renderers.register(:erb, Tilt::ERBTemplate)
|
||||||
|
|
||||||
|
%w(haml
|
||||||
|
sass
|
||||||
|
coffee).each { |renderer| require "middleman/renderers/#{renderer}" }
|
|
@ -1,23 +0,0 @@
|
||||||
require "builder"
|
|
||||||
|
|
||||||
module Middleman
|
|
||||||
module Renderers
|
|
||||||
module Builder
|
|
||||||
def self.included(base)
|
|
||||||
base.supported_formats << "builder"
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_path(path, layout)
|
|
||||||
if template_exists?(path, :builder)
|
|
||||||
builder(path.to_sym, :layout => layout)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Base
|
|
||||||
include Middleman::Renderers::Builder
|
|
||||||
end
|
|
28
lib/middleman/renderers/coffee.rb
Executable file
28
lib/middleman/renderers/coffee.rb
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
class Middleman::Base
|
||||||
|
def coffee(template, options={}, locals={})
|
||||||
|
options[:layout] = false
|
||||||
|
render :coffee, template, options, locals
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless defined? Tilt::CoffeeTemplate
|
||||||
|
# CoffeeScript info:
|
||||||
|
# http://jashkenas.github.com/coffee-script/
|
||||||
|
class Tilt::CoffeeTemplate < Tilt::Template
|
||||||
|
def initialize_engine
|
||||||
|
return if defined? ::CoffeeScript
|
||||||
|
require_template_library 'coffee-script'
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepare
|
||||||
|
@output = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def evaluate(scope, locals, &block)
|
||||||
|
@output ||= ::CoffeeScript::compile(data, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Tilt.register 'coffee', Tilt::CoffeeTemplate
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Renderers.register(:coffee, Tilt::CoffeeTemplate)
|
|
@ -1,24 +0,0 @@
|
||||||
require "erb"
|
|
||||||
|
|
||||||
module Middleman
|
|
||||||
module Renderers
|
|
||||||
module ERb
|
|
||||||
def self.included(base)
|
|
||||||
base.supported_formats << "erb"
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_path(path, layout)
|
|
||||||
if template_exists?(path, :erb)
|
|
||||||
layout = false if File.extname(path) == ".xml"
|
|
||||||
erb(path.to_sym, :layout => layout)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Base
|
|
||||||
include Middleman::Renderers::ERb
|
|
||||||
end
|
|
|
@ -2,29 +2,6 @@ require "haml"
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Haml
|
module Haml
|
||||||
module Renderer
|
|
||||||
def self.included(base)
|
|
||||||
base.supported_formats << "haml"
|
|
||||||
base.helpers Middleman::Haml::Helpers
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_path(path, layout)
|
|
||||||
if template_exists?(path, :haml)
|
|
||||||
result = nil
|
|
||||||
begin
|
|
||||||
layout = false if File.extname(path) == ".xml"
|
|
||||||
result = haml(path.to_sym, :layout => layout, :ugly => Middleman::Base.enabled?(:ugly_haml))
|
|
||||||
rescue ::Haml::Error => e
|
|
||||||
result = "Haml Error: #{e}"
|
|
||||||
result << "<pre>Backtrace: #{e.backtrace.join("\n")}</pre>"
|
|
||||||
end
|
|
||||||
result
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Helpers
|
module Helpers
|
||||||
def haml_partial(name, options = {})
|
def haml_partial(name, options = {})
|
||||||
item_name = name.to_sym
|
item_name = name.to_sym
|
||||||
|
@ -66,5 +43,5 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
class Middleman::Base
|
class Middleman::Base
|
||||||
include Middleman::Haml::Renderer
|
helpers Middleman::Haml::Helpers
|
||||||
end
|
end
|
|
@ -1,23 +0,0 @@
|
||||||
require "less"
|
|
||||||
|
|
||||||
module Middleman
|
|
||||||
module Renderers
|
|
||||||
module Less
|
|
||||||
def self.included(base)
|
|
||||||
base.supported_formats << "less"
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_path(path, layout)
|
|
||||||
if template_exists?(path, :less)
|
|
||||||
less(path.to_sym)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Base
|
|
||||||
include Middleman::Renderers::Less
|
|
||||||
end
|
|
|
@ -1,93 +1,18 @@
|
||||||
require "sass"
|
require "sass"
|
||||||
require "compass"
|
require "compass"
|
||||||
require "fancy-buttons"
|
|
||||||
|
|
||||||
begin
|
|
||||||
require "yui/compressor"
|
|
||||||
rescue LoadError
|
|
||||||
puts "YUI-Compressor not available. Install it with: gem install yui-compressor"
|
|
||||||
end
|
|
||||||
|
|
||||||
module Middleman::Sass
|
|
||||||
def self.included(base)
|
|
||||||
base.supported_formats << "sass"
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_path(path, layout)
|
|
||||||
if template_exists?(path, :sass)
|
|
||||||
begin
|
|
||||||
static_version = settings.public + request.path_info
|
|
||||||
send_file(static_version) if File.exists? static_version
|
|
||||||
|
|
||||||
location_of_sass_file = settings.environment == "build" ?
|
|
||||||
File.join(Dir.pwd, settings.build_dir) :
|
|
||||||
settings.public
|
|
||||||
|
|
||||||
css_filename = File.join(location_of_sass_file, request.path_info)
|
|
||||||
result = sass(path.to_sym, ::Compass.sass_engine_options.merge({ :css_filename => css_filename }))
|
|
||||||
|
|
||||||
if enabled?(:minify_css)
|
|
||||||
::YUI::CssCompressor.new.compress(result)
|
|
||||||
else
|
|
||||||
result
|
|
||||||
end
|
|
||||||
rescue Exception => e
|
|
||||||
sass_exception_string(e)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Handle Sass errors
|
|
||||||
def sass_exception_string(e)
|
|
||||||
e_string = "#{e.class}: #{e.message}"
|
|
||||||
|
|
||||||
if e.is_a? ::Sass::SyntaxError
|
|
||||||
e_string << "\non line #{e.sass_line}"
|
|
||||||
|
|
||||||
if e.sass_filename
|
|
||||||
e_string << " of #{e.sass_filename}"
|
|
||||||
|
|
||||||
if File.exists?(e.sass_filename)
|
|
||||||
e_string << "\n\n"
|
|
||||||
|
|
||||||
min = [e.sass_line - 5, 0].max
|
|
||||||
begin
|
|
||||||
File.read(e.sass_filename).rstrip.split("\n")[
|
|
||||||
min .. e.sass_line + 5
|
|
||||||
].each_with_index do |line, i|
|
|
||||||
e_string << "#{min + i + 1}: #{line}\n"
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
e_string << "Couldn't read sass file: #{e.sass_filename}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
<<END
|
|
||||||
/*
|
|
||||||
#{e_string}
|
|
||||||
|
|
||||||
Backtrace:\n#{e.backtrace.join("\n")}
|
|
||||||
*/
|
|
||||||
body:before {
|
|
||||||
white-space: pre;
|
|
||||||
font-family: monospace;
|
|
||||||
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
|
||||||
END
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Middleman::Base
|
class Middleman::Base
|
||||||
include Middleman::Sass
|
def scss(template, options={}, locals={})
|
||||||
|
options[:layout] = false
|
||||||
|
render :scss, template, options, locals
|
||||||
|
end
|
||||||
|
|
||||||
after_feature_init do
|
after_feature_init do
|
||||||
::Compass.configuration do |config|
|
::Compass.configuration do |config|
|
||||||
config.cache_path = File.join(self.root, ".sassc") # For sassc files
|
config.cache_path = File.join(self.root, ".sass-cache") # For sassc files
|
||||||
config.project_path = self.root
|
config.project_path = self.root
|
||||||
config.sass_dir = File.join(File.basename(self.views), self.css_dir)
|
config.sass_dir = File.join(File.basename(self.views), self.css_dir)
|
||||||
config.output_style = self.enabled?(:minify_css) ? :compressed : :nested
|
config.output_style = :nested
|
||||||
config.fonts_dir = File.join(File.basename(self.public), self.fonts_dir)
|
config.fonts_dir = File.join(File.basename(self.public), self.fonts_dir)
|
||||||
config.css_dir = File.join(File.basename(self.public), self.css_dir)
|
config.css_dir = File.join(File.basename(self.public), self.css_dir)
|
||||||
config.images_dir = File.join(File.basename(self.public), self.images_dir)
|
config.images_dir = File.join(File.basename(self.public), self.images_dir)
|
||||||
|
@ -98,17 +23,45 @@ class Middleman::Base
|
||||||
config.add_import_path(config.sass_dir)
|
config.add_import_path(config.sass_dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
::Compass.configure_sass_plugin!
|
|
||||||
Sass::Plugin.options.update(:line_comments => true, :debug_info => true)
|
|
||||||
|
|
||||||
configure :build do
|
configure :build do
|
||||||
::Compass.configuration do |config|
|
::Compass.configuration do |config|
|
||||||
config.css_dir = File.join(File.basename(self.build_dir), self.css_dir)
|
config.css_dir = File.join(File.basename(self.build_dir), self.css_dir)
|
||||||
config.images_dir = File.join(File.basename(self.build_dir), self.images_dir)
|
config.images_dir = File.join(File.basename(self.build_dir), self.images_dir)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
::Compass.configure_sass_plugin!
|
end
|
||||||
Sass::Plugin.options.update(:line_comments => false, :debug_info => false)
|
end
|
||||||
|
|
||||||
|
class Tilt::SassPlusCSSFilenameTemplate < Tilt::SassTemplate
|
||||||
|
def sass_options
|
||||||
|
location_of_sass_file = Middleman::Base.environment == "build" ?
|
||||||
|
File.join(Middleman::Base.root, Middleman::Base.build_dir) :
|
||||||
|
Middleman::Base.public
|
||||||
|
|
||||||
|
parts = basename.split('.')
|
||||||
|
parts.pop
|
||||||
|
css_filename = File.join(location_of_sass_file, Middleman::Base.css_dir, parts.join("."))
|
||||||
|
super.merge(::Compass.configuration.to_sass_engine_options).merge(:css_filename => css_filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Tilt.register 'sass', Tilt::SassPlusCSSFilenameTemplate
|
||||||
|
Middleman::Renderers.register(:sass, Tilt::SassPlusCSSFilenameTemplate)
|
||||||
|
|
||||||
|
class Tilt::ScssPlusCSSFilenameTemplate < Tilt::SassPlusCSSFilenameTemplate
|
||||||
|
def sass_options
|
||||||
|
super.merge(:syntax => :scss)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Tilt.register 'scss', Tilt::ScssPlusCSSFilenameTemplate
|
||||||
|
Middleman::Renderers.register(:scss, Tilt::ScssPlusCSSFilenameTemplate)
|
||||||
|
|
||||||
|
|
||||||
|
module Middleman::Haml
|
||||||
|
module Sass
|
||||||
|
include ::Haml::Filters::Base
|
||||||
|
|
||||||
|
def render(text)
|
||||||
|
::Sass::Engine.new(text, ::Compass.configuration.to_sass_engine_options).render
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,6 +1,14 @@
|
||||||
<% if css_dir %>set :css_dir, "<%= css_dir -%>"<% end %>
|
# Automatic sitemaps
|
||||||
<% if js_dir %>set :js_dir, "<%= js_dir -%>"<% end %>
|
# enable :slickmap
|
||||||
<% if images_dir %>set :images_dir, "<%= images_dir -%>"<% end %>
|
|
||||||
|
# Automatic image dimension calculations
|
||||||
|
# enable :automatic_image_sizes
|
||||||
|
|
||||||
|
# Per-page layout changes
|
||||||
|
# With no layout
|
||||||
|
# page "/path/to/file.html", :layout => false
|
||||||
|
# With alternative layout
|
||||||
|
# page "/path/to/file.html", :layout => :otherlayout
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
helpers do
|
helpers do
|
||||||
|
@ -9,11 +17,26 @@ helpers do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Automatic sitemaps
|
<% if css_dir %>
|
||||||
# enable :slickmap
|
set :css_dir, "<%= css_dir -%>"
|
||||||
|
<% else %>
|
||||||
|
# Change the CSS directory
|
||||||
|
# set :css_dir, "alternative_css_directory"
|
||||||
|
<% end %>
|
||||||
|
|
||||||
# Automatic image dimension calculations
|
<% if js_dir %>
|
||||||
# enable :automatic_image_sizes
|
set :js_dir, "<%= js_dir -%>"
|
||||||
|
<% else %>
|
||||||
|
# Change the JS directory
|
||||||
|
# set :js_dir, "alternative_js_directory"
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if images_dir %>
|
||||||
|
set :images_dir, "<%= images_dir -%>"
|
||||||
|
<% else %>
|
||||||
|
# Change the images directory
|
||||||
|
# set :images_dir, "alternative_image_directory"
|
||||||
|
<% end %>
|
||||||
|
|
||||||
# Build-specific configuration
|
# Build-specific configuration
|
||||||
configure :build do
|
configure :build do
|
||||||
|
|
|
@ -42,6 +42,16 @@ describe "Builder" do
|
||||||
File.read("#{@root_dir}/build/stylesheets/site.css").gsub(/\s/, "").should include("html,body,div,span,applet,object,iframe")
|
File.read("#{@root_dir}/build/stylesheets/site.css").gsub(/\s/, "").should include("html,body,div,span,applet,object,iframe")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should build less files" do
|
||||||
|
File.exists?("#{@root_dir}/build/stylesheets/test_less.css").should be_true
|
||||||
|
File.read("#{@root_dir}/build/stylesheets/test_less.css").should include("666")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build scss files" do
|
||||||
|
File.exists?("#{@root_dir}/build/stylesheets/site_scss.css").should be_true
|
||||||
|
File.read("#{@root_dir}/build/stylesheets/site_scss.css").gsub(/\s/, "").should include("html,body,div,span,applet,object,iframe")
|
||||||
|
end
|
||||||
|
|
||||||
it "should build static css files" do
|
it "should build static css files" do
|
||||||
File.exists?("#{@root_dir}/build/stylesheets/static.css").should be_true
|
File.exists?("#{@root_dir}/build/stylesheets/static.css").should be_true
|
||||||
end
|
end
|
||||||
|
|
1
spec/fixtures/sample/views/stylesheets/site_scss.css.scss
vendored
Executable file
1
spec/fixtures/sample/views/stylesheets/site_scss.css.scss
vendored
Executable file
|
@ -0,0 +1 @@
|
||||||
|
@import "compass/reset";
|
5
spec/fixtures/sample/views/stylesheets/test_less.css.less
vendored
Executable file
5
spec/fixtures/sample/views/stylesheets/test_less.css.less
vendored
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
@brand_color: #666666;
|
||||||
|
|
||||||
|
#header {
|
||||||
|
color: @brand_color;
|
||||||
|
}
|
Loading…
Reference in a new issue