Move Sprockets into an extension

This commit is contained in:
Thomas Reynolds 2012-05-24 14:29:29 -07:00
parent f8c64f25ec
commit 8d483f882c
43 changed files with 128 additions and 379 deletions

View file

@ -7,7 +7,6 @@
* Remove old 1.x mm- binaries and messaging * Remove old 1.x mm- binaries and messaging
* New default layout functionality: https://github.com/middleman/middleman/issues/165 * New default layout functionality: https://github.com/middleman/middleman/issues/165
* Enable chained templates outside of sprockets (file.html.markdown.erb) * Enable chained templates outside of sprockets (file.html.markdown.erb)
* Finally support Compass in Sprockets! Thanks to @xdite and @petebrowne
* Sitemap object representing the known world * Sitemap object representing the known world
* FileWatcher proxies file change events * FileWatcher proxies file change events
* Unified callback solution * Unified callback solution
@ -38,13 +37,15 @@
* `:asset_hash` extension that generates unique-by-content filenames for assets and rewrites references to use those filenames, so you can set far-future expires on your assets. * `:asset_hash` extension that generates unique-by-content filenames for assets and rewrites references to use those filenames, so you can set far-future expires on your assets.
* Removed the `--relative` CLI option. * Removed the `--relative` CLI option.
* Properly output Compass-generated sprited images. * Properly output Compass-generated sprited images.
* Include vendored assets in sprockets path.
* Switch built-in CSS compressor to Rainpress. * Switch built-in CSS compressor to Rainpress.
* Automatically load helper modules from `helpers/`, like Rails. * Automatically load helper modules from `helpers/`, like Rails.
* `ignore` and `page` both work with file globs or regexes. * `ignore` and `page` both work with file globs or regexes.
* `layout`, `ignore`, and `directory_index` can be set from front matter. * `layout`, `ignore`, and `directory_index` can be set from front matter.
* JavaScript and CSS are minified no matter where they are in the site, including in inline code blocks. * JavaScript and CSS are minified no matter where they are in the site, including in inline code blocks.
* Files with just a template extension get output with the correct exension (foo.erb => foo.html) * Files with just a template extension get output with the correct exension (foo.erb => foo.html)
* Include vendored assets in sprockets path.
* Finally support Compass in Sprockets! Thanks to @xdite and @petebrowne
* Moved Sprockets into an extension
2.0.14 2.0.14
==== ====

View file

@ -17,15 +17,13 @@ group :test do
gem "slim" gem "slim"
gem "coffee-filter", "~> 0.1.1" gem "coffee-filter", "~> 0.1.1"
gem "liquid", "~> 2.2" gem "liquid", "~> 2.2"
gem "jquery-rails", "~> 2.0.1"
# gem "bootstrap-rails", "0.0.5"
# gem "zurb-foundation"
platforms :ruby do platforms :ruby do
gem "redcarpet", "~> 2.1.1" gem "redcarpet", "~> 2.1.1"
end end
end end
gem "middleman-sprockets", :github => "middleman/middleman-sprockets"
gem "middleman-core", :path => "middleman-core" gem "middleman-core", :path => "middleman-core"
gem "middleman-more", :path => "middleman-more" gem "middleman-more", :path => "middleman-more"
gem "middleman", :path => "middleman" gem "middleman", :path => "middleman"

View file

@ -4,7 +4,7 @@ Middleman makes developing stand-alone websites simple. The last few years has s
* Sass for DRY stylesheets * Sass for DRY stylesheets
* CoffeeScript for safer and less verbose javascript * CoffeeScript for safer and less verbose javascript
* Sprockets for combining and minifying assets * Multiple Asset Management Solutions
* ERb & Haml for dynamic pages and simplified HTML syntax * ERb & Haml for dynamic pages and simplified HTML syntax
Middleman gives the stand-alone developer access to all these tool and many, many more. Why would you use a stand-alone framework instead of Ruby on Rails? Middleman gives the stand-alone developer access to all these tool and many, many more. Why would you use a stand-alone framework instead of Ruby on Rails?

View file

@ -1,4 +1,5 @@
ENV["TEST"] = "true" ENV["TEST"] = "true"
ENV["AUTOLOAD_SPROCKETS"] = "false"
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core') require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core')

View file

@ -88,7 +88,7 @@ module Middleman
# @return [String] # @return [String]
set :index_file, "index.html" set :index_file, "index.html"
# Location of javascripts within source. Used by Sprockets. # Location of javascripts within source.
# @return [String] # @return [String]
set :js_dir, "javascripts" set :js_dir, "javascripts"
@ -152,9 +152,6 @@ module Middleman
# Initialize the Middleman project # Initialize the Middleman project
def initialize(&block) def initialize(&block)
# Current path defaults to nil, used in views.
self.current_path = nil
# Clear the static class cache # Clear the static class cache
cache.clear cache.clear

View file

@ -45,6 +45,12 @@ module Middleman
app.define_hook :build_config app.define_hook :build_config
app.define_hook :development_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.extend ClassMethods app.extend ClassMethods
app.send :include, InstanceMethods app.send :include, InstanceMethods
app.delegate :configure, :to => :"self.class" app.delegate :configure, :to => :"self.class"
@ -131,6 +137,8 @@ module Middleman
instance_eval File.read(local_config), local_config, 1 instance_eval File.read(local_config), local_config, 1
end end
activate(:sprockets) if autoload_sprockets
run_hook :build_config if build? run_hook :build_config if build?
run_hook :development_config if development? run_hook :development_config if development?

View file

@ -14,7 +14,7 @@ module Middleman
def registered(app) def registered(app)
# CSSPIE HTC File # CSSPIE HTC File
::Rack::Mime::MIME_TYPES['.html'] = 'text/x-component' ::Rack::Mime::MIME_TYPES['.htc'] = 'text/x-component'
# Let's serve all HTML as UTF-8 # Let's serve all HTML as UTF-8
::Rack::Mime::MIME_TYPES['.html'] = 'text/html;charset=utf8' ::Rack::Mime::MIME_TYPES['.html'] = 'text/html;charset=utf8'
@ -152,23 +152,19 @@ module Middleman
# Methods to be mixed-in to Middleman::Application # Methods to be mixed-in to Middleman::Application
module InstanceMethods module InstanceMethods
# Backwards-compatibility with old request.path signature # Backwards-compatibility with old request.path signature
def request attr_reader :request
Thread.current[:request]
end
# Accessor for current path # Accessor for current path
# @return [String] # @return [String]
def current_path attr_reader :current_path
Thread.current[:current_path]
end
# Set the current path # Set the current path
# #
# @param [String] path The new current path # @param [String] path The new current path
# @return [void] # @return [void]
def current_path=(path) def current_path=(path)
Thread.current[:current_path] = path @current_path = path
Thread.current[:request] = ::Thor::CoreExt::HashWithIndifferentAccess.new({ @request = ::Thor::CoreExt::HashWithIndifferentAccess.new({
:path => path, :path => path,
:params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {} :params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {}
}) })
@ -178,30 +174,15 @@ module Middleman
def map(*args, &block); self.class.map(*args, &block); end def map(*args, &block); self.class.map(*args, &block); end
# Rack env # Rack env
def env attr_accessor :env
Thread.current[:env]
end
def env=(value)
Thread.current[:env] = value
end
# Rack request # Rack request
# @return [Rack::Request] # @return [Rack::Request]
def req attr_accessor :req
Thread.current[:req]
end
def req=(value)
Thread.current[:req] = value
end
# Rack response # Rack response
# @return [Rack::Response] # @return [Rack::Response]
def res attr_accessor :res
Thread.current[:res]
end
def res=(value)
Thread.current[:res] = value
end
def call(env) def call(env)
dup.call!(env) dup.call!(env)
@ -243,6 +224,7 @@ module Middleman
# @param [Rack::Response] res # @param [Rack::Response] res
def process_request(env, req, res) def process_request(env, req, res)
start_time = Time.now start_time = Time.now
@current_path = nil
# Normalize the path and add index if we're looking at a directory # Normalize the path and add index if we're looking at a directory
original_path = URI.decode(env["PATH_INFO"].dup) original_path = URI.decode(env["PATH_INFO"].dup)
@ -268,16 +250,19 @@ module Middleman
# If this path is a static file, send it immediately # If this path is a static file, send it immediately
return send_file(resource.source_file, env, res) unless resource.template? return send_file(resource.source_file, env, res) unless resource.template?
# Set the current path for use in helpers current_path = request_path.dup
self.current_path = request_path.dup
# Set a HTTP content type based on the request's extensions # Set a HTTP content type based on the request's extensions
content_type(res, resource.mime_type) content_type(res, resource.mime_type)
begin begin
# Write out the contents of the page # Write out the contents of the page
res.write resource.render output = resource.render do
self.req = req
self.current_path = current_path
end
res.write output
# Valid content is a 200 status # Valid content is a 200 status
res.status = 200 res.status = 200
rescue Middleman::CoreExtensions::Rendering::TemplateNotFound => e rescue Middleman::CoreExtensions::Rendering::TemplateNotFound => e
@ -286,7 +271,7 @@ module Middleman
end end
# End the request # End the request
puts "== Finishing Request: #{self.current_path} (#{(Time.now - start_time).round(2)}s)" if logging? puts "== Finishing Request: #{request_path} (#{(Time.now - start_time).round(2)}s)" if logging?
halt res.finish halt res.finish
end end

View file

@ -110,7 +110,7 @@ module Middleman
end end
# Where a given Gem::Specification has a specific file. Used # Where a given Gem::Specification has a specific file. Used
# to discover extensions and Sprockets-supporting gems. # to discover extensions.
# #
# @private # @private
# @param [Gem::Specification] spec # @param [Gem::Specification] spec

View file

@ -132,6 +132,8 @@ module Middleman
end end
app.instance_eval(&block) if block_given? app.instance_eval(&block) if block_given?
app.current_path ||= self.destination_path
result = app.render_template(source_file, locs, opts) result = app.render_template(source_file, locs, opts)
puts "== Render End: #{source_file} (#{(Time.now - start_time).round(2)}s)" if app.logging? puts "== Render End: #{source_file} (#{(Time.now - start_time).round(2)}s)" if app.logging?

View file

@ -7,8 +7,8 @@ Feature: Assets get a file hash appended to their and references to them are upd
| images/100px-1242c368.png | | images/100px-1242c368.png |
| images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.jpg |
| images/100px-5fd6fb90.gif | | images/100px-5fd6fb90.gif |
| javascripts/application-df677242.js | | javascripts/application-1d8d5276.js |
| stylesheets/site-ed8c2d12.css | | stylesheets/site-ad4a5abd.css |
| index.html | | index.html |
| subdir/index.html | | subdir/index.html |
| other/index.html | | other/index.html |
@ -19,53 +19,53 @@ Feature: Assets get a file hash appended to their and references to them are upd
| javascripts/application.js | | javascripts/application.js |
| stylesheets/site.css | | stylesheets/site.css |
And the file "javascripts/application-df677242.js" should contain "img.src = '/images/100px-5fd6fb90.jpg'" And the file "javascripts/application-1d8d5276.js" should contain "img.src = '/images/100px-5fd6fb90.jpg'"
And the file "stylesheets/site-ed8c2d12.css" should contain "background-image: url('../images/100px-5fd6fb90.jpg')" And the file "stylesheets/site-ad4a5abd.css" should contain "background-image: url('../images/100px-5fd6fb90.jpg')"
And the file "index.html" should contain 'href="stylesheets/site-ed8c2d12.css"' And the file "index.html" should contain 'href="stylesheets/site-ad4a5abd.css"'
And the file "index.html" should contain 'src="javascripts/application-df677242.js"' And the file "index.html" should contain 'src="javascripts/application-1d8d5276.js"'
And the file "index.html" should contain 'src="images/100px-5fd6fb90.jpg"' And the file "index.html" should contain 'src="images/100px-5fd6fb90.jpg"'
And the file "subdir/index.html" should contain 'href="../stylesheets/site-ed8c2d12.css"' And the file "subdir/index.html" should contain 'href="../stylesheets/site-ad4a5abd.css"'
And the file "subdir/index.html" should contain 'src="../javascripts/application-df677242.js"' And the file "subdir/index.html" should contain 'src="../javascripts/application-1d8d5276.js"'
And the file "subdir/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' And the file "subdir/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"'
And the file "other/index.html" should contain 'href="../stylesheets/site-ed8c2d12.css"' And the file "other/index.html" should contain 'href="../stylesheets/site-ad4a5abd.css"'
And the file "other/index.html" should contain 'src="../javascripts/application-df677242.js"' And the file "other/index.html" should contain 'src="../javascripts/application-1d8d5276.js"'
And the file "other/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' And the file "other/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"'
Scenario: Hashed assets work in preview server Scenario: Hashed assets work in preview server
Given the Server is running at "asset-hash-app" Given the Server is running at "asset-hash-app"
When I go to "/" When I go to "/"
Then I should see 'href="stylesheets/site-ed8c2d12.css"' Then I should see 'href="stylesheets/site-ad4a5abd.css"'
And I should see 'src="javascripts/application-df677242.js"' And I should see 'src="javascripts/application-1d8d5276.js"'
And I should see 'src="images/100px-5fd6fb90.jpg"' And I should see 'src="images/100px-5fd6fb90.jpg"'
When I go to "/subdir/" When I go to "/subdir/"
Then I should see 'href="../stylesheets/site-ed8c2d12.css"' Then I should see 'href="../stylesheets/site-ad4a5abd.css"'
And I should see 'src="../javascripts/application-df677242.js"' And I should see 'src="../javascripts/application-1d8d5276.js"'
And I should see 'src="../images/100px-5fd6fb90.jpg"' And I should see 'src="../images/100px-5fd6fb90.jpg"'
When I go to "/other/" When I go to "/other/"
Then I should see 'href="../stylesheets/site-ed8c2d12.css"' Then I should see 'href="../stylesheets/site-ad4a5abd.css"'
And I should see 'src="../javascripts/application-df677242.js"' And I should see 'src="../javascripts/application-1d8d5276.js"'
And I should see 'src="../images/100px-5fd6fb90.jpg"' And I should see 'src="../images/100px-5fd6fb90.jpg"'
When I go to "/javascripts/application-df677242.js" When I go to "/javascripts/application-1d8d5276.js"
Then I should see "img.src = '/images/100px-5fd6fb90.jpg'" Then I should see "img.src = '/images/100px-5fd6fb90.jpg'"
When I go to "/stylesheets/site-ed8c2d12.css" When I go to "/stylesheets/site-ad4a5abd.css"
Then I should see "background-image: url('../images/100px-5fd6fb90.jpg')" Then I should see "background-image: url('../images/100px-5fd6fb90.jpg')"
Scenario: Enabling an asset host still produces hashed files and references Scenario: Enabling an asset host still produces hashed files and references
Given the Server is running at "asset-hash-host-app" Given the Server is running at "asset-hash-host-app"
When I go to "/" When I go to "/"
Then I should see 'href="http://middlemanapp.com/stylesheets/site-e5a31a3e.css"' Then I should see 'href="http://middlemanapp.com/stylesheets/site-1bac75d8.css"'
And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"'
When I go to "/subdir/" When I go to "/subdir/"
Then I should see 'href="http://middlemanapp.com/stylesheets/site-e5a31a3e.css"' Then I should see 'href="http://middlemanapp.com/stylesheets/site-1bac75d8.css"'
And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"'
When I go to "/other/" When I go to "/other/"
Then I should see 'href="http://middlemanapp.com/stylesheets/site-e5a31a3e.css"' Then I should see 'href="http://middlemanapp.com/stylesheets/site-1bac75d8.css"'
And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"'
# Asset helpers don't appear to work from Compass right now # Asset helpers don't appear to work from Compass right now
# When I go to "/stylesheets/site-e5a31a3e.css" # When I go to "/stylesheets/site-e5a31a3e.css"
# Then I should see "background-image: url('http://middlemanapp.com/images/100px-5fd6fb90.jpg')" # Then I should see "background-image: url('http://middlemanapp.com/images/100px-5fd6fb90.jpg')"
Scenario: The asset hash should change when a SASS or Sprockets partial changes Scenario: The asset hash should change when a SASS partial changes
Given the Server is running at "asset-hash-app" Given the Server is running at "asset-hash-app"
And the file "source/stylesheets/_partial.sass" has the contents And the file "source/stylesheets/_partial.sass" has the contents
""" """
@ -73,12 +73,12 @@ Feature: Assets get a file hash appended to their and references to them are upd
font-size: 14px font-size: 14px
""" """
When I go to "/partials/" When I go to "/partials/"
Then I should see 'href="../stylesheets/uses_partials-8b948098.css' Then I should see 'href="../stylesheets/uses_partials-b1ef0501.css'
And the file "source/stylesheets/_partial.sass" has the contents And the file "source/stylesheets/_partial.sass" has the contents
""" """
body body
font-size: 18px !important font-size: 18px !important
""" """
When I go to "/partials/" When I go to "/partials/"
Then I should see 'href="../stylesheets/uses_partials-1f9f0ed2.css' Then I should see 'href="../stylesheets/uses_partials-05453ae6.css'

View file

@ -49,39 +49,6 @@ Feature: Sass Updates and Partials
Then I should see "color: blue;" Then I should see "color: blue;"
And I should see "font-size: 18px" And I should see "font-size: 18px"
Scenario: The preview server should update stylesheets when Sprockets partials change
Given the Server is running at "preview-app"
And the file "source/stylesheets/main2.css.sass" has the contents
"""
//= require "_partial2.css.sass"
red
color: red
"""
And the file "source/stylesheets/_partial2.css.sass" has the contents
"""
body
font-size: 14px
"""
When I go to "/stylesheets/main2.css"
Then I should see "color: red;"
Then I should see "font-size: 14px"
And the file "source/stylesheets/main2.css.sass" has the contents
"""
//= require "_partial2.css.sass"
red
color: blue
"""
And the file "source/stylesheets/_partial2.css.sass" has the contents
"""
body
font-size: 18px
"""
When I go to "/stylesheets/main2.css"
Then I should see "color: blue;"
Then I should see "font-size: 18px"
Scenario: Sass partials should work when building Scenario: Sass partials should work when building
Given a successfully built app at "preview-app" Given a successfully built app at "preview-app"
Then the file "build/stylesheets/main.css" should contain "font-size: 18px" Then the file "build/stylesheets/main.css" should contain "font-size: 18px"

View file

@ -1,74 +0,0 @@
Feature: Sprockets
Scenario: Sprockets JS require
Given the Server is running at "sprockets-app2"
When I go to "/javascripts/sprockets_base.js"
Then I should see "sprockets_sub_function"
Scenario: Sprockets JS require with custom :js_dir
Given the Server is running at "sprockets-app"
When I go to "/library/js/sprockets_base.js"
Then I should see "sprockets_sub_function"
Scenario: Plain JS require with custom :js_dir
Given the Server is running at "sprockets-app"
When I go to "/library/css/plain.css"
Then I should see "helloWorld"
Scenario: Sprockets JS should have access to yaml data
Given the Server is running at "sprockets-app2"
When I go to "/javascripts/multiple_engines.js"
Then I should see "Hello One"
Scenario: Multiple engine files should build correctly
Given a successfully built app at "sprockets-app2"
When I cd to "build"
Then a file named "javascripts/multiple_engines.js" should exist
And the file "javascripts/multiple_engines.js" should contain "Hello One"
Scenario: Sprockets CSS require //require
Given the Server is running at "sprockets-app2"
When I go to "/stylesheets/sprockets_base1.css"
Then I should see "hello"
Scenario: Sprockets CSS require @import
Given the Server is running at "sprockets-app2"
When I go to "/stylesheets/sprockets_base2.css"
Then I should see "hello"
Scenario: Sprockets CSS require //require (updates)
Given the Server is running at "sprockets-app2"
When I go to "/stylesheets/sprockets_base1.css"
Then I should see "hello"
And the file "source/stylesheets/sprockets_sub.css.scss" has the contents
"""
hola { mundo: "hola"; }
"""
When I go to "/stylesheets/sprockets_base1.css"
Then I should see "hola"
Scenario: Sprockets CSS require @import (updates)
Given the Server is running at "sprockets-app2"
When I go to "/stylesheets/sprockets_base2.css"
Then I should see "hello"
And the file "source/stylesheets/sprockets_sub.css.scss" has the contents
"""
hola { mundo: "hola"; }
"""
When I go to "/stylesheets/sprockets_base2.css"
Then I should see "hola"
Scenario: Sprockets CSS require with custom :css_dir //require
Given the Server is running at "sprockets-app"
When I go to "/library/css/sprockets_base1.css"
Then I should see "hello"
Scenario: Plain CSS require with custom :css_dir
Given the Server is running at "sprockets-app"
When I go to "/library/css/plain.css"
Then I should see "helloWorld"
Scenario: Sprockets CSS require with custom :css_dir @import
Given the Server is running at "sprockets-app"
When I go to "/library/css/sprockets_base2.css"
Then I should see "hello"

View file

@ -1,15 +0,0 @@
Feature: Sprockets Gems
Scenario: Sprockets can pull jQuery from gem
Given the Server is running at "sprockets-app"
When I go to "/library/js/jquery_include.js"
Then I should see "var jQuery ="
# Scenario: Sprockets can pull CSS from gem
# Given the Server is running at "sprockets-app"
# When I go to "/library/css/bootstrap_include.css"
# Then I should see "Bootstrap"
Scenario: Sprockets can pull js from vendored assets
Given the Server is running at "sprockets-app"
When I go to "/library/js/vendored_include.js"
Then I should see "var vendored_js_included = true;"

View file

@ -1,4 +1,5 @@
ENV["TEST"] = "true" ENV["TEST"] = "true"
ENV["AUTOLOAD_SPROCKETS"] = "false"
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))

View file

@ -1,2 +0,0 @@
set :js_dir, "library/js"
set :css_dir, "library/css"

View file

@ -1 +0,0 @@
//= require "bootstrap.scss"

View file

@ -1,3 +0,0 @@
#helloWorld {
color: red;
}

View file

@ -1 +0,0 @@
//= require "sprockets_sub"

View file

@ -1 +0,0 @@
//= require "jquery"

View file

@ -1,3 +0,0 @@
function hellowWorld() {
}

View file

@ -1,5 +0,0 @@
//= require "sprockets_sub"
function base() {
}

View file

@ -1,3 +0,0 @@
function sprockets_sub_function() {
}

View file

@ -1 +0,0 @@
//= require "vendored_js"

View file

@ -1 +0,0 @@
var vendored_js_included = true;

View file

@ -1,4 +0,0 @@
-
title: "One"
-
title: "Two"

View file

@ -1,4 +0,0 @@
[
{ "title": "One" },
{ "title": "Two" }
]

View file

@ -1 +0,0 @@
alert "Hello <%= data.test[0].title %>"

View file

@ -1,5 +0,0 @@
//= require "sprockets_sub"
function base() {
}

View file

@ -1,3 +0,0 @@
function sprockets_sub_function() {
}

View file

@ -1 +0,0 @@
//= require "sprockets_sub"

View file

@ -71,10 +71,6 @@ module Middleman::More
require "middleman-more/core_extensions/compass" require "middleman-more/core_extensions/compass"
Middleman::Application.register Middleman::CoreExtensions::Compass Middleman::Application.register Middleman::CoreExtensions::Compass
# Sprockets asset handling
require "middleman-more/core_extensions/sprockets"
Middleman::Application.register Middleman::CoreExtensions::Sprockets
### ###
# Setup Optional Extensions # Setup Optional Extensions
### ###

View file

@ -50,6 +50,14 @@ module Middleman
# Call hook # Call hook
run_hook :compass_config, ::Compass.configuration run_hook :compass_config, ::Compass.configuration
# Tell Tilt to use it as well (for inline sass blocks)
::Tilt.register 'sass', CompassSassTemplate
::Tilt.prefer(CompassSassTemplate)
# Tell Tilt to use it as well (for inline scss blocks)
::Tilt.register 'scss', CompassScssTemplate
::Tilt.prefer(CompassScssTemplate)
end end
end end
alias :included :registered alias :included :registered
@ -57,5 +65,20 @@ module Middleman
end end
# A Compass template for Tilt
class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate
private
def sass_options
super.merge(::Compass.configuration.to_sass_engine_options)
end
end
class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate
private
def sass_options
super.merge(::Compass.configuration.to_sass_engine_options)
end
end
end end
end end

View file

@ -1,101 +0,0 @@
# Require gem
require "sprockets"
# Sprockets extension
module Middleman::CoreExtensions::Sprockets
# Setup extension
class << self
# Once registered
def registered(app)
# Add class methods to context
app.send :include, InstanceMethods
# Once Middleman is setup
app.ready do
# Add any gems with (vendor|app|.)/assets/javascripts to paths
# also add similar directories from project root (like in rails)
root_paths = [%w{ app }, %w{ assets }, %w{ vendor }, %w{ app assets }, %w{ vendor assets }, %w{ lib }, %w{ lib assets }]
try_paths = root_paths.map {|rp| File.join(rp, 'javascripts') } +
root_paths.map {|rp| File.join(rp, 'stylesheets') }
([root] + ::Middleman.rubygems_latest_specs.map(&:full_gem_path)).each do |root_path|
try_paths.map {|p| File.join(root_path, p) }.
select {|p| File.directory?(p) }.
each {|path| sprockets.append_path(path) }
end
# Setup Sprockets Sass options
sass.each { |k, v| ::Sprockets::Sass.options[k] = v }
# Intercept requests to /javascripts and /stylesheets and pass to sprockets
our_sprockets = sprockets
map("/#{js_dir}") { run our_sprockets }
map("/#{css_dir}") { run our_sprockets }
end
end
alias :included :registered
end
module InstanceMethods
# @return [Middleman::CoreExtensions::Sprockets::MiddlemanSprocketsEnvironment]
def sprockets
@sprockets ||= MiddlemanSprocketsEnvironment.new(self)
end
end
# Generic Middleman Sprockets env
class MiddlemanSprocketsEnvironment < ::Sprockets::Environment
# Setup
def initialize(app)
@app = app
super app.source_dir
# Make the app context available to Sprockets
context_class.send(:define_method, :app) { app }
context_class.class_eval do
def method_missing(name)
if app.respond_to?(name)
app.send(name)
else
super
end
end
end
# Remove compressors, we handle these with middleware
unregister_bundle_processor 'application/javascript', :js_compressor
unregister_bundle_processor 'text/css', :css_compressor
# configure search paths
append_path app.js_dir
append_path app.css_dir
end
# Override Sprockets' default digest function to *not*
# change depending on the exact Sprockets version. It still takes
# into account "version" which is a user-suppliable version
# number that can be used to force assets to have a new
# hash.
def digest
@digest ||= Digest::SHA1.new.update(version.to_s)
@digest.dup
end
# During development, don't use the asset cache
def find_asset(path, options = {})
expire_index! if @app.development?
super
end
# Clear cache on error
def javascript_exception_response(exception)
expire_index!
super(exception)
end
# Clear cache on error
alias :css_exception_response :javascript_exception_response
end
end

View file

@ -2,9 +2,9 @@ module Middleman
module Extensions module Extensions
module AssetHash module AssetHash
class << self class << self
def registered(app, options) def registered(app, options={})
require 'digest/sha1' require 'digest/sha1'
exts = options[:exts] || %w(.jpg .jpeg .png .gif .js .css) exts = options[:exts] || %w(.ico .manifest .jpg .jpeg .png .gif .js .css)
# Allow specifying regexes to ignore, plus always ignore apple touch icons # Allow specifying regexes to ignore, plus always ignore apple touch icons
ignore = Array(options[:ignore]) << /^apple-touch-icon/ ignore = Array(options[:ignore]) << /^apple-touch-icon/
@ -31,20 +31,8 @@ module Middleman
# @return [void] # @return [void]
def manipulate_resource_list(resources) def manipulate_resource_list(resources)
resources.each do |resource| resources.each do |resource|
if @exts.include?(resource.ext) && @ignore.none? {|ignore| resource.path =~ ignore } if @exts.include? resource.ext
# figure out the path Sprockets would use for this asset if resource.template? # if it's a template, render it out
if resource.ext == '.js'
sprockets_path = resource.path.sub(@app.js_dir,'').sub(/^\//,'')
elsif resource.ext == '.css'
sprockets_path = resource.path.sub(@app.css_dir,'').sub(/^\//,'')
end
# See if Sprockets knows about the file
asset = @app.sprockets.find_asset(sprockets_path) if sprockets_path
if asset # if it's a Sprockets asset, ask sprockets for its digest
digest = asset.digest[0..7]
elsif resource.template? # if it's a template, render it out
digest = Digest::SHA1.hexdigest(resource.render)[0..7] digest = Digest::SHA1.hexdigest(resource.render)[0..7]
else # if it's a static file, just hash it else # if it's a static file, just hash it
digest = Digest::SHA1.file(resource.source_file).hexdigest[0..7] digest = Digest::SHA1.file(resource.source_file).hexdigest[0..7]

View file

@ -14,9 +14,29 @@ module Middleman
app.before_configuration do app.before_configuration do
template_extensions :coffee => :js template_extensions :coffee => :js
end end
# Tell Tilt to use it as well (for inline scss blocks)
::Tilt.register 'coffee', DebuggingCoffeeScriptTemplate
::Tilt.prefer(DebuggingCoffeeScriptTemplate)
end end
alias :included :registered alias :included :registered
end end
# A Template for Tilt which outputs debug messages
class DebuggingCoffeeScriptTemplate < ::Tilt::CoffeeScriptTemplate
# Add exception messaging
# @param [Class] context
# @param [Hash] locals
# @return [String]
def evaluate(context, locals, &block)
begin
super
rescue ::ExecJS::RuntimeError=> e
e.to_s
end
end
end
end end
end end
end end

View file

@ -1,7 +1,3 @@
# Pull in gems
require "sprockets"
require "sprockets-sass"
module Middleman module Middleman
module Renderers module Renderers
@ -15,9 +11,6 @@ module Middleman
def registered(app) def registered(app)
require "sass" require "sass"
# Stick with Compass' asset functions
::Sprockets::Sass.add_sass_functions = false
# Default sass options # Default sass options
app.set :sass, {} app.set :sass, {}
@ -26,16 +19,10 @@ module Middleman
:sass => :css :sass => :css
end end
# Tell Sprockets to use our custom Sass template
::Sprockets.register_engine ".sass", SassPlusCSSFilenameTemplate
# Tell Tilt to use it as well (for inline sass blocks) # 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)
# Tell Sprockets to use our custom Scss template
::Sprockets.register_engine ".scss", ScssPlusCSSFilenameTemplate
# Tell Tilt to use it as well (for inline scss blocks) # 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)
@ -44,22 +31,33 @@ module Middleman
alias :included :registered alias :included :registered
end end
# A SassTemplate for Sprockets/Tilt which outputs debug messages # A SassTemplate for Tilt which outputs debug messages
class SassPlusCSSFilenameTemplate < ::Sprockets::Sass::SassTemplate class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate
# Define the expected syntax for the template
# @return [Symbol]
def syntax
:sass
end
def prepare; end
# Add exception messaging # Add exception messaging
# @param [Class] context # @param [Class] context
# @param [Hash] locals # @param [Hash] locals
# @return [String] # @return [String]
def evaluate(context, locals, &block) def evaluate(context, locals, &block)
@context = context
@engine = ::Sass::Engine.new(data, sass_options)
begin begin
super @engine.render
rescue ::Sass::SyntaxError => e rescue ::Sass::SyntaxError => e
::Sass::SyntaxError.exception_to_css(e, :full_exception => true) ::Sass::SyntaxError.exception_to_css(e, :full_exception => true)
end end
end end
protected private
# Change Sass path, for url functions, to the build folder if we're building # Change Sass path, for url functions, to the build folder if we're building
# @return [Hash] # @return [Hash]
def sass_options def sass_options
@ -69,7 +67,7 @@ module Middleman
parts.pop parts.pop
css_filename = File.join(location_of_sass_file, @context.css_dir, parts.join(".")) css_filename = File.join(location_of_sass_file, @context.css_dir, parts.join("."))
super.merge(:css_filename => css_filename) options.merge(:filename => eval_file, :line => line, :syntax => syntax, :css_filename => css_filename)
end end
end end

View file

@ -24,11 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency("compass", [">= 0.12.1"]) s.add_dependency("compass", [">= 0.12.1"])
s.add_dependency("coffee-script", ["~> 2.2.0"]) s.add_dependency("coffee-script", ["~> 2.2.0"])
s.add_dependency("execjs", ["~> 1.3.2"]) s.add_dependency("execjs", ["~> 1.3.2"])
s.add_dependency("sprockets", ["~> 2.1"])
s.add_dependency("sprockets-sass", ["~> 0.8.0"])
s.add_dependency("maruku", ["~> 0.6.0"]) s.add_dependency("maruku", ["~> 0.6.0"])
# i18n
s.add_dependency("i18n", ["~> 0.6.0"]) s.add_dependency("i18n", ["~> 0.6.0"])
s.add_dependency("padrino-helpers", ["~> 0.10.6"]) s.add_dependency("padrino-helpers", ["~> 0.10.6"])
end end

View file

@ -18,5 +18,6 @@ Gem::Specification.new do |s|
s.add_dependency("middleman-core", Middleman::VERSION) s.add_dependency("middleman-core", Middleman::VERSION)
s.add_dependency("middleman-more", Middleman::VERSION) s.add_dependency("middleman-more", Middleman::VERSION)
s.add_dependency("middleman-sprockets", Middleman::VERSION)
end end