middleman 0.9.17 → 0.9.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/mm-build +1 -1
- data/bin/mm-server +31 -7
- data/lib/middleman/base.rb +70 -85
- data/lib/middleman/builder.rb +4 -2
- data/lib/middleman/config.ru +2 -0
- data/lib/middleman/features/cache_buster.rb +9 -11
- data/lib/middleman/features/compass.rb +0 -2
- data/lib/middleman/features/minify_javascript.rb +17 -13
- data/lib/middleman/features/relative_assets.rb +20 -26
- data/lib/middleman/{features/haml.rb → haml.rb} +1 -64
- data/lib/middleman/helpers.rb +11 -5
- data/lib/middleman/{features → rack}/sprockets+ruby19.rb +0 -0
- data/lib/middleman/rack/sprockets.rb +34 -0
- data/lib/middleman/rack/static.rb +21 -0
- data/lib/middleman/sass.rb +70 -0
- data/lib/middleman/templater+dynamic_renderer.rb +8 -14
- data/middleman.gemspec +18 -9
- data/spec/cache_buster_spec.rb +6 -16
- data/spec/fixtures/sample/views/javascripts/empty-with-include.js +1 -0
- metadata +29 -7
- data/lib/middleman/features/content_for.rb +0 -9
- data/lib/middleman/features/sprockets.rb +0 -29
- data/spec/fixtures/sample/public/javascripts/empty-with-include.js +0 -1
data/Rakefile
CHANGED
@@ -11,6 +11,8 @@ begin
|
|
11
11
|
gem.authors = ["Thomas Reynolds"]
|
12
12
|
gem.rubyforge_project = "middleman"
|
13
13
|
gem.executables = %w(mm-init mm-build mm-server)
|
14
|
+
gem.add_dependency("thin")
|
15
|
+
gem.add_dependency("shotgun")
|
14
16
|
gem.add_dependency("templater")
|
15
17
|
gem.add_dependency("sprockets")
|
16
18
|
gem.add_dependency("sinatra")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.18
|
data/bin/mm-build
CHANGED
@@ -6,7 +6,7 @@ ENV['MM_ENV'] = "build"
|
|
6
6
|
require File.join(File.dirname(__FILE__), "..", "lib", "middleman")
|
7
7
|
require 'middleman/builder'
|
8
8
|
|
9
|
-
Middleman::Base.init!
|
9
|
+
#Middleman::Base.init!
|
10
10
|
Middleman::Builder.init!
|
11
11
|
|
12
12
|
Middleman::Generators.run_cli(Dir.pwd, 'mm-build', 1, %w(build --force).concat(ARGV))
|
data/bin/mm-server
CHANGED
@@ -5,15 +5,39 @@ require 'optparse'
|
|
5
5
|
# Require Middleman
|
6
6
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'middleman')
|
7
7
|
|
8
|
+
env = ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development'
|
9
|
+
options = { :Port => 4567, :AccessLog => [] }
|
10
|
+
|
11
|
+
OptionParser.new { |opts|
|
12
|
+
opts.banner = "Usage: mm-server [rack options]"
|
13
|
+
opts.separator ""
|
14
|
+
opts.separator "Rack options:"
|
15
|
+
opts.on("-p", "--port PORT", "use PORT (default: 4567)") { |port|
|
16
|
+
options[:Port] = port
|
17
|
+
}
|
18
|
+
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
19
|
+
env = e
|
20
|
+
}
|
21
|
+
opts.on("--debug", "Debug mode") {
|
22
|
+
::Middleman::Base.set :logging, true
|
23
|
+
}
|
24
|
+
|
25
|
+
opts.parse! ARGV
|
26
|
+
}
|
27
|
+
|
28
|
+
ENV['RACK_ENV'] = env
|
29
|
+
|
8
30
|
class Middleman::Base
|
9
31
|
set :root, Dir.pwd
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'shotgun'
|
35
|
+
config = File.join(File.dirname(__FILE__), '..', 'lib', 'middleman', 'config.ru')
|
36
|
+
app = Shotgun.new(config, lambda { |inner_app| Middleman::Base })
|
10
37
|
|
11
|
-
|
12
|
-
|
13
|
-
op.on('-s server') { |val| set :server, val }
|
14
|
-
op.on('-p port') { |val| set :port, val.to_i }
|
15
|
-
}.parse!(ARGV.dup)
|
38
|
+
require 'thin'
|
39
|
+
Thin::Logging.silent = true
|
16
40
|
|
17
|
-
|
18
|
-
|
41
|
+
Rack::Handler::Thin.run app, options do |inst|
|
42
|
+
puts "== The Middleman is standing watch on port #{options[:Port]}"
|
19
43
|
end
|
data/lib/middleman/base.rb
CHANGED
@@ -8,49 +8,44 @@ module Middleman
|
|
8
8
|
class Base < Sinatra::Base
|
9
9
|
set :app_file, __FILE__
|
10
10
|
set :root, Dir.pwd
|
11
|
+
set :reload, false
|
12
|
+
set :logging, false
|
11
13
|
set :environment, ENV['MM_ENV'] || :development
|
12
|
-
set :supported_formats,
|
14
|
+
set :supported_formats, %w(erb)
|
13
15
|
set :index_file, "index.html"
|
14
16
|
set :js_dir, "javascripts"
|
15
17
|
set :css_dir, "stylesheets"
|
16
18
|
set :images_dir, "images"
|
17
19
|
set :build_dir, "build"
|
18
20
|
set :http_prefix, "/"
|
19
|
-
|
20
|
-
# Features enabled by default
|
21
|
-
enable :compass
|
22
|
-
enable :content_for
|
23
|
-
enable :sprockets
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
disable :minify_css
|
29
|
-
disable :minify_javascript
|
30
|
-
disable :relative_assets
|
31
|
-
disable :maruku
|
32
|
-
disable :smush_pngs
|
22
|
+
use Rack::ConditionalGet if environment == :development
|
23
|
+
|
24
|
+
@@features = []
|
33
25
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
enable :minify_javascript
|
38
|
-
enable :cache_buster
|
26
|
+
def self.enable(*opts)
|
27
|
+
@@features << opts
|
28
|
+
super
|
39
29
|
end
|
40
|
-
|
30
|
+
|
31
|
+
def self.disable(*opts)
|
32
|
+
@@features -= opts
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
41
36
|
# Rack helper for adding mime-types during local preview
|
42
37
|
def self.mime(ext, type)
|
43
38
|
ext = ".#{ext}" unless ext.to_s[0] == ?.
|
44
|
-
Rack::Mime::MIME_TYPES[ext.to_s] = type
|
39
|
+
::Rack::Mime::MIME_TYPES[ext.to_s] = type
|
45
40
|
end
|
46
|
-
|
41
|
+
|
47
42
|
# Convenience function to discover if a tempalte exists for the requested renderer (haml, sass, etc)
|
48
43
|
def template_exists?(path, renderer=nil)
|
49
44
|
template_path = path.dup
|
50
45
|
template_path << ".#{renderer}" if renderer
|
51
46
|
File.exists? File.join(options.views, template_path)
|
52
47
|
end
|
53
|
-
|
48
|
+
|
54
49
|
# Base case renderer (do nothing), Should be over-ridden
|
55
50
|
module StaticRender
|
56
51
|
def render_path(path)
|
@@ -62,84 +57,74 @@ module Middleman
|
|
62
57
|
end
|
63
58
|
end
|
64
59
|
include StaticRender
|
65
|
-
|
66
|
-
# Disable static asset handling in Rack, so we can customize it here
|
67
|
-
disable :static
|
68
|
-
|
60
|
+
|
69
61
|
# This will match all requests not overridden in the project's init.rb
|
70
62
|
not_found do
|
71
63
|
# Normalize the path and add index if we're looking at a directory
|
72
64
|
path = request.path
|
73
65
|
path << options.index_file if path.match(%r{/$})
|
74
66
|
path.gsub!(%r{^/}, '')
|
75
|
-
|
67
|
+
|
76
68
|
# If the enabled renderers succeed, return the content, mime-type and an HTTP 200
|
77
69
|
if content = render_path(path)
|
78
70
|
content_type media_type(File.extname(path)), :charset => 'utf-8'
|
79
71
|
status 200
|
80
72
|
content
|
81
73
|
else
|
82
|
-
|
83
|
-
path = File.join(options.public, request.path)
|
84
|
-
if !File.directory?(path) && File.exists?(path)
|
85
|
-
status 200
|
86
|
-
send_file(path)
|
87
|
-
else
|
88
|
-
status 404
|
89
|
-
end
|
74
|
+
status 404
|
90
75
|
end
|
91
76
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Haml is required & includes helpers
|
81
|
+
require "middleman/haml"
|
82
|
+
require "middleman/sass"
|
83
|
+
require 'sinatra/content_for'
|
84
|
+
require 'middleman/helpers'
|
85
|
+
require 'middleman/rack/static'
|
86
|
+
require 'middleman/rack/sprockets'
|
87
|
+
|
88
|
+
class Middleman::Base
|
89
|
+
helpers Sinatra::ContentFor
|
90
|
+
helpers Middleman::Helpers
|
91
|
+
|
92
|
+
use Middleman::Rack::Static
|
93
|
+
use Middleman::Rack::Sprockets
|
94
|
+
|
95
|
+
enable :compass
|
96
|
+
|
97
|
+
# Features disabled by default
|
98
|
+
disable :slickmap
|
99
|
+
disable :cache_buster
|
100
|
+
disable :minify_css
|
101
|
+
disable :minify_javascript
|
102
|
+
disable :relative_assets
|
103
|
+
disable :maruku
|
104
|
+
disable :smush_pngs
|
105
|
+
|
106
|
+
# Default build features
|
107
|
+
configure :build do
|
108
|
+
enable :minify_css
|
109
|
+
enable :minify_javascript
|
110
|
+
enable :cache_buster
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.new(*args, &bk)
|
114
|
+
# Check for and evaluate local configuration
|
115
|
+
local_config = File.join(self.root, "init.rb")
|
116
|
+
if File.exists? local_config
|
117
|
+
puts "== Reading: Local config" if logging?
|
118
|
+
class_eval File.read(local_config)
|
116
119
|
end
|
117
120
|
|
118
|
-
#
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
# Haml is required & includes helpers
|
125
|
-
require "middleman/features/haml"
|
126
|
-
|
127
|
-
# Check for and evaluate local configuration
|
128
|
-
local_config = File.join(self.root, "init.rb")
|
129
|
-
if File.exists? local_config
|
130
|
-
puts "== Local config at: #{local_config}" unless quiet
|
131
|
-
class_eval File.read(local_config)
|
132
|
-
end
|
133
|
-
|
134
|
-
# loop over enabled feature
|
135
|
-
features_path = File.expand_path("features/*.rb", File.dirname(__FILE__))
|
136
|
-
Dir[features_path].each do |f|
|
137
|
-
feature_name = File.basename(f, '.rb')
|
138
|
-
option_name = :"#{feature_name}?"
|
139
|
-
if respond_to?(option_name) && send(option_name) === true
|
140
|
-
require "middleman/features/#{feature_name}"
|
141
|
-
end
|
142
|
-
end
|
121
|
+
# loop over enabled feature
|
122
|
+
@@features.flatten.each do |feature_name|
|
123
|
+
next unless send(:"#{feature_name}?")
|
124
|
+
puts "== Enabling: #{feature_name.capitalize}" if logging?
|
125
|
+
require "middleman/features/#{feature_name}"
|
143
126
|
end
|
127
|
+
|
128
|
+
super
|
144
129
|
end
|
145
130
|
end
|
data/lib/middleman/builder.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'templater'
|
2
2
|
require 'middleman/templater+dynamic_renderer.rb'
|
3
|
-
require 'rack/test' # Use Rack::Test to access Sinatra without starting up a full server
|
4
3
|
|
5
4
|
# Placeholder for any methods the builder needs to abstract to allow feature integration
|
6
5
|
module Middleman
|
@@ -37,9 +36,12 @@ module Middleman
|
|
37
36
|
end
|
38
37
|
|
39
38
|
def self.init!
|
40
|
-
glob! File.basename(Middleman::Base.public),
|
39
|
+
glob! File.basename(Middleman::Base.public), []
|
41
40
|
glob! File.basename(Middleman::Base.views), Middleman::Base.supported_formats
|
42
41
|
end
|
42
|
+
|
43
|
+
def after_run
|
44
|
+
end
|
43
45
|
end
|
44
46
|
|
45
47
|
module Generators
|
@@ -1,15 +1,13 @@
|
|
1
|
-
class Middleman::Base
|
1
|
+
class << Middleman::Base
|
2
2
|
alias_method :pre_cache_buster_asset_url, :asset_url
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
http_path
|
12
|
-
end
|
3
|
+
def asset_url(path, prefix="", request=nil)
|
4
|
+
http_path = pre_cache_buster_asset_url(path, prefix, request)
|
5
|
+
if http_path.include?("://") || !%w(.css .png .jpg .js .gif).include?(File.extname(http_path))
|
6
|
+
http_path
|
7
|
+
else
|
8
|
+
real_path = File.join(self.public, prefix, path)
|
9
|
+
http_path << "?" + File.mtime(real_path).strftime("%s") if File.readable?(real_path)
|
10
|
+
http_path
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
@@ -12,20 +12,24 @@ module Middleman
|
|
12
12
|
END
|
13
13
|
end
|
14
14
|
end
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
class Builder
|
18
|
+
alias_method :pre_yui_after_run, :after_run
|
19
|
+
def after_run
|
20
|
+
pre_yui_after_run
|
21
|
+
|
22
|
+
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
23
|
+
Dir[File.join(Middleman::Base.build_dir, Middleman::Base.js_dir, "**", "*.js")].each do |path|
|
24
|
+
lines = IO.readlines(path)
|
25
|
+
if lines.length > 1
|
26
|
+
compressed_js = compressor.compress(lines.join($/))
|
27
|
+
File.open(path, 'w') { |f| f.write(compressed_js) }
|
28
|
+
say "<%= color('#{"[COMPRESSED]".rjust(12)}', :yellow) %> " + path.gsub(Middleman::Base.build_dir+"/", '')
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
+
end if Middleman::Base.environment == "build"
|
33
|
+
end
|
34
|
+
|
35
|
+
Middleman::Base.supported_formats << "js"
|
@@ -1,30 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if path.
|
15
|
-
|
1
|
+
::Compass.configuration do |config|
|
2
|
+
config.relative_assets = true
|
3
|
+
end
|
4
|
+
|
5
|
+
class << Middleman::Base
|
6
|
+
alias_method :pre_relative_asset_url, :asset_url
|
7
|
+
def asset_url(path, prefix="", request=nil)
|
8
|
+
path = pre_relative_asset_url(path, prefix, request)
|
9
|
+
if path.include?("://")
|
10
|
+
path
|
11
|
+
else
|
12
|
+
path = path[1,path.length-1] if path[0,1] == '/'
|
13
|
+
request_path = request.path_info.dup
|
14
|
+
request_path << self.class.index_file if path.match(%r{/$})
|
15
|
+
request_path.gsub!(%r{^/}, '')
|
16
|
+
parts = request_path.split('/')
|
17
|
+
|
18
|
+
if parts.length > 1
|
19
|
+
"../" * (parts.length - 1) + path
|
16
20
|
else
|
17
|
-
path
|
18
|
-
request_path = request.path_info.dup
|
19
|
-
request_path << options.index_file if path.match(%r{/$})
|
20
|
-
request_path.gsub!(%r{^/}, '')
|
21
|
-
parts = request_path.split('/')
|
22
|
-
|
23
|
-
if parts.length > 1
|
24
|
-
"../" * (parts.length - 1) + path
|
25
|
-
else
|
26
|
-
path
|
27
|
-
end
|
21
|
+
path
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "haml"
|
2
2
|
|
3
3
|
module Middleman
|
4
4
|
module Haml
|
@@ -62,71 +62,8 @@ module Middleman
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
66
|
-
module Sass
|
67
|
-
def self.included(base)
|
68
|
-
base.supported_formats << "sass"
|
69
|
-
end
|
70
|
-
|
71
|
-
def render_path(path)
|
72
|
-
if template_exists?(path, :sass)
|
73
|
-
begin
|
74
|
-
static_version = options.public + request.path_info
|
75
|
-
send_file(static_version) if File.exists? static_version
|
76
|
-
|
77
|
-
location_of_sass_file = options.environment == "build" ? File.join(options.build_dir, options.css_dir) : "public"
|
78
|
-
css_filename = File.join(Dir.pwd, location_of_sass_file) + request.path_info
|
79
|
-
sass(path.to_sym, Compass.sass_engine_options.merge({ :css_filename => css_filename }))
|
80
|
-
rescue Exception => e
|
81
|
-
sass_exception_string(e)
|
82
|
-
end
|
83
|
-
else
|
84
|
-
super
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Handle Sass errors
|
89
|
-
def sass_exception_string(e)
|
90
|
-
e_string = "#{e.class}: #{e.message}"
|
91
|
-
|
92
|
-
if e.is_a? ::Sass::SyntaxError
|
93
|
-
e_string << "\non line #{e.sass_line}"
|
94
|
-
|
95
|
-
if e.sass_filename
|
96
|
-
e_string << " of #{e.sass_filename}"
|
97
|
-
|
98
|
-
if File.exists?(e.sass_filename)
|
99
|
-
e_string << "\n\n"
|
100
|
-
|
101
|
-
min = [e.sass_line - 5, 0].max
|
102
|
-
begin
|
103
|
-
File.read(e.sass_filename).rstrip.split("\n")[
|
104
|
-
min .. e.sass_line + 5
|
105
|
-
].each_with_index do |line, i|
|
106
|
-
e_string << "#{min + i + 1}: #{line}\n"
|
107
|
-
end
|
108
|
-
rescue
|
109
|
-
e_string << "Couldn't read sass file: #{e.sass_filename}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
<<END
|
115
|
-
/*
|
116
|
-
#{e_string}
|
117
|
-
|
118
|
-
Backtrace:\n#{e.backtrace.join("\n")}
|
119
|
-
*/
|
120
|
-
body:before {
|
121
|
-
white-space: pre;
|
122
|
-
font-family: monospace;
|
123
|
-
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
124
|
-
END
|
125
|
-
end
|
126
|
-
end
|
127
65
|
end
|
128
66
|
|
129
67
|
class Middleman::Base
|
130
68
|
include Middleman::Haml::Renderer
|
131
|
-
include Middleman::Sass
|
132
69
|
end
|
data/lib/middleman/helpers.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
module Middleman
|
2
|
+
class Base
|
3
|
+
def self.asset_url(path, prefix="", request=nil)
|
4
|
+
base_url = File.join(self.http_prefix, prefix)
|
5
|
+
path.include?("://") ? path : File.join(base_url, path)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
2
9
|
module Helpers
|
3
10
|
def page_classes(*additional)
|
4
11
|
path = request.path_info
|
@@ -14,16 +21,15 @@ module Middleman
|
|
14
21
|
classes.join(' ')
|
15
22
|
end
|
16
23
|
|
24
|
+
def asset_url(path, prefix="")
|
25
|
+
self.class.asset_url(path, prefix, request)
|
26
|
+
end
|
27
|
+
|
17
28
|
def link_to(title, url="#", params={})
|
18
29
|
params.merge!(:href => url)
|
19
30
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
20
31
|
%Q{<a #{params}>#{title}</a>}
|
21
32
|
end
|
22
|
-
|
23
|
-
def asset_url(path, prefix="")
|
24
|
-
base_url = File.join(options.http_prefix, prefix)
|
25
|
-
path.include?("://") ? path : File.join(base_url, path)
|
26
|
-
end
|
27
33
|
|
28
34
|
def image_tag(path, params={})
|
29
35
|
params[:alt] ||= ""
|
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require 'sprockets'
|
3
|
+
require 'middleman/rack/sprockets+ruby19' # Sprockets ruby 1.9 duckpunch
|
4
|
+
rescue LoadError
|
5
|
+
puts "Sprockets not available. Install it with: gem install sprockets"
|
6
|
+
end
|
7
|
+
|
8
|
+
module Middleman
|
9
|
+
module Rack
|
10
|
+
class Sprockets
|
11
|
+
def initialize(app, options={})
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
path = env["PATH_INFO"]
|
17
|
+
source = File.join(Middleman::Base.views, path)
|
18
|
+
|
19
|
+
if path.match(/\.js$/) && File.exists?(source)
|
20
|
+
secretary = ::Sprockets::Secretary.new( :root => Middleman::Base.root,
|
21
|
+
:source_files => [ File.join("views", path) ],
|
22
|
+
:load_path => [ File.join("public", Middleman::Base.js_dir),
|
23
|
+
File.join("views", Middleman::Base.js_dir) ])
|
24
|
+
|
25
|
+
[200, { "Content-Type" => "text/javascript" }, [secretary.concatenation.to_s]]
|
26
|
+
else
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Middleman::Base.supported_formats << "js"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Rack
|
3
|
+
class Static
|
4
|
+
def initialize(app, options={})
|
5
|
+
@app = app
|
6
|
+
root = Middleman::Base.public
|
7
|
+
@file_server = ::Rack::File.new(root)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
path = env["PATH_INFO"]
|
12
|
+
file_path = File.join(Middleman::Base.public, path)
|
13
|
+
if path.include?("favicon.ico") || (File.exists?(file_path) && !File.directory?(file_path))
|
14
|
+
@file_server.call(env)
|
15
|
+
else
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "sass"
|
2
|
+
require 'compass'
|
3
|
+
|
4
|
+
module Middleman
|
5
|
+
module Sass
|
6
|
+
def self.included(base)
|
7
|
+
base.supported_formats << "sass"
|
8
|
+
end
|
9
|
+
|
10
|
+
def render_path(path)
|
11
|
+
if template_exists?(path, :sass)
|
12
|
+
begin
|
13
|
+
static_version = options.public + request.path_info
|
14
|
+
send_file(static_version) if File.exists? static_version
|
15
|
+
|
16
|
+
location_of_sass_file = options.environment == "build" ? File.join(options.build_dir, options.css_dir) : "public"
|
17
|
+
css_filename = File.join(Dir.pwd, location_of_sass_file) + request.path_info
|
18
|
+
sass(path.to_sym, ::Compass.sass_engine_options.merge({ :css_filename => css_filename }))
|
19
|
+
rescue Exception => e
|
20
|
+
sass_exception_string(e)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Handle Sass errors
|
28
|
+
def sass_exception_string(e)
|
29
|
+
e_string = "#{e.class}: #{e.message}"
|
30
|
+
|
31
|
+
if e.is_a? ::Sass::SyntaxError
|
32
|
+
e_string << "\non line #{e.sass_line}"
|
33
|
+
|
34
|
+
if e.sass_filename
|
35
|
+
e_string << " of #{e.sass_filename}"
|
36
|
+
|
37
|
+
if File.exists?(e.sass_filename)
|
38
|
+
e_string << "\n\n"
|
39
|
+
|
40
|
+
min = [e.sass_line - 5, 0].max
|
41
|
+
begin
|
42
|
+
File.read(e.sass_filename).rstrip.split("\n")[
|
43
|
+
min .. e.sass_line + 5
|
44
|
+
].each_with_index do |line, i|
|
45
|
+
e_string << "#{min + i + 1}: #{line}\n"
|
46
|
+
end
|
47
|
+
rescue
|
48
|
+
e_string << "Couldn't read sass file: #{e.sass_filename}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
<<END
|
54
|
+
/*
|
55
|
+
#{e_string}
|
56
|
+
|
57
|
+
Backtrace:\n#{e.backtrace.join("\n")}
|
58
|
+
*/
|
59
|
+
body:before {
|
60
|
+
white-space: pre;
|
61
|
+
font-family: monospace;
|
62
|
+
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
63
|
+
END
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Middleman::Base
|
69
|
+
include Middleman::Sass
|
70
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rack/test' # Use Rack::Test to access Sinatra without starting up a full server
|
2
|
+
|
1
3
|
# Monkey-patch to use a dynamic renderer
|
2
4
|
class Templater::Actions::File
|
3
5
|
def identical?
|
@@ -12,20 +14,12 @@ end
|
|
12
14
|
|
13
15
|
class Templater::Actions::Template
|
14
16
|
def render
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def identical?
|
23
|
-
if File.exists?(destination)
|
24
|
-
extension = File.extname(source)
|
25
|
-
return true if !%w(.sass .js .haml).include?(extension) && File.exists?(source) && File.mtime(source) < File.mtime(destination)
|
26
|
-
File.read(destination) == render
|
27
|
-
else
|
28
|
-
false
|
17
|
+
@render_cache ||= begin
|
18
|
+
# The default render just requests the page over Rack and writes the response
|
19
|
+
request_path = destination.gsub(File.join(Dir.pwd, Middleman::Base.build_dir), "")
|
20
|
+
browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman::Base))
|
21
|
+
browser.get(request_path)
|
22
|
+
browser.last_response.body
|
29
23
|
end
|
30
24
|
end
|
31
25
|
end
|
data/middleman.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{middleman}
|
8
|
-
s.version = "0.9.
|
8
|
+
s.version = "0.9.18"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Thomas Reynolds"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-22}
|
13
13
|
s.email = %q{tdreyno@gmail.com}
|
14
14
|
s.executables = ["mm-init", "mm-build", "mm-server"]
|
15
15
|
s.extra_rdoc_files = [
|
@@ -30,20 +30,22 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/middleman.rb",
|
31
31
|
"lib/middleman/base.rb",
|
32
32
|
"lib/middleman/builder.rb",
|
33
|
+
"lib/middleman/config.ru",
|
33
34
|
"lib/middleman/features/cache_buster.rb",
|
34
35
|
"lib/middleman/features/compass.rb",
|
35
|
-
"lib/middleman/features/content_for.rb",
|
36
36
|
"lib/middleman/features/growl.rb",
|
37
|
-
"lib/middleman/features/haml.rb",
|
38
37
|
"lib/middleman/features/maruku.rb",
|
39
38
|
"lib/middleman/features/minify_css.rb",
|
40
39
|
"lib/middleman/features/minify_javascript.rb",
|
41
40
|
"lib/middleman/features/relative_assets.rb",
|
42
41
|
"lib/middleman/features/slickmap.rb",
|
43
42
|
"lib/middleman/features/smush_pngs.rb",
|
44
|
-
"lib/middleman/
|
45
|
-
"lib/middleman/features/sprockets.rb",
|
43
|
+
"lib/middleman/haml.rb",
|
46
44
|
"lib/middleman/helpers.rb",
|
45
|
+
"lib/middleman/rack/sprockets+ruby19.rb",
|
46
|
+
"lib/middleman/rack/sprockets.rb",
|
47
|
+
"lib/middleman/rack/static.rb",
|
48
|
+
"lib/middleman/sass.rb",
|
47
49
|
"lib/middleman/template/init.rbt",
|
48
50
|
"lib/middleman/template/views/index.html.haml",
|
49
51
|
"lib/middleman/template/views/layout.html.haml",
|
@@ -53,13 +55,13 @@ Gem::Specification.new do |s|
|
|
53
55
|
"spec/builder_spec.rb",
|
54
56
|
"spec/cache_buster_spec.rb",
|
55
57
|
"spec/fixtures/sample/init.rb",
|
56
|
-
"spec/fixtures/sample/public/javascripts/empty-with-include.js",
|
57
58
|
"spec/fixtures/sample/public/javascripts/to-be-included.js",
|
58
59
|
"spec/fixtures/sample/public/static.html",
|
59
60
|
"spec/fixtures/sample/public/stylesheets/static.css",
|
60
61
|
"spec/fixtures/sample/views/_partial.haml",
|
61
62
|
"spec/fixtures/sample/views/index.html.haml",
|
62
63
|
"spec/fixtures/sample/views/inline-js.html.haml",
|
64
|
+
"spec/fixtures/sample/views/javascripts/empty-with-include.js",
|
63
65
|
"spec/fixtures/sample/views/layout.haml",
|
64
66
|
"spec/fixtures/sample/views/maruku.html.maruku",
|
65
67
|
"spec/fixtures/sample/views/services/index.html.haml",
|
@@ -88,6 +90,8 @@ Gem::Specification.new do |s|
|
|
88
90
|
s.specification_version = 3
|
89
91
|
|
90
92
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
93
|
+
s.add_runtime_dependency(%q<thin>, [">= 0"])
|
94
|
+
s.add_runtime_dependency(%q<shotgun>, [">= 0"])
|
91
95
|
s.add_runtime_dependency(%q<templater>, [">= 0"])
|
92
96
|
s.add_runtime_dependency(%q<sprockets>, [">= 0"])
|
93
97
|
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
@@ -99,6 +103,8 @@ Gem::Specification.new do |s|
|
|
99
103
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
100
104
|
s.add_development_dependency(%q<sdoc>, [">= 0"])
|
101
105
|
else
|
106
|
+
s.add_dependency(%q<thin>, [">= 0"])
|
107
|
+
s.add_dependency(%q<shotgun>, [">= 0"])
|
102
108
|
s.add_dependency(%q<templater>, [">= 0"])
|
103
109
|
s.add_dependency(%q<sprockets>, [">= 0"])
|
104
110
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
@@ -111,6 +117,8 @@ Gem::Specification.new do |s|
|
|
111
117
|
s.add_dependency(%q<sdoc>, [">= 0"])
|
112
118
|
end
|
113
119
|
else
|
120
|
+
s.add_dependency(%q<thin>, [">= 0"])
|
121
|
+
s.add_dependency(%q<shotgun>, [">= 0"])
|
114
122
|
s.add_dependency(%q<templater>, [">= 0"])
|
115
123
|
s.add_dependency(%q<sprockets>, [">= 0"])
|
116
124
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
@@ -123,3 +131,4 @@ Gem::Specification.new do |s|
|
|
123
131
|
s.add_dependency(%q<sdoc>, [">= 0"])
|
124
132
|
end
|
125
133
|
end
|
134
|
+
|
data/spec/cache_buster_spec.rb
CHANGED
@@ -4,25 +4,15 @@ base = ::Middleman::Base
|
|
4
4
|
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
|
5
5
|
|
6
6
|
describe "Cache Buster Feature" do
|
7
|
-
|
7
|
+
it "should not append query string if off" do
|
8
8
|
base.disable :cache_buster
|
9
|
-
base.
|
10
|
-
|
9
|
+
base.new
|
10
|
+
base.asset_url("stylesheets/static.css").should_not include("?")
|
11
11
|
end
|
12
12
|
|
13
|
-
it "should not append query string if off" do
|
14
|
-
@app.asset_url("stylesheets/static.css").should_not include("?")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "Cache Buster Feature" do
|
19
|
-
before do
|
20
|
-
base.enable :cache_buster
|
21
|
-
base.init!(true)
|
22
|
-
@app = base.new
|
23
|
-
end
|
24
|
-
|
25
13
|
it "should append query string if on" do
|
26
|
-
|
14
|
+
base.enable :cache_buster
|
15
|
+
base.new
|
16
|
+
base.asset_url("stylesheets/static.css").should include("?")
|
27
17
|
end
|
28
18
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require <to-be-included>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Reynolds
|
@@ -9,9 +9,29 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thin
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: shotgun
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
15
35
|
- !ruby/object:Gem::Dependency
|
16
36
|
name: templater
|
17
37
|
type: :runtime
|
@@ -137,20 +157,22 @@ files:
|
|
137
157
|
- lib/middleman.rb
|
138
158
|
- lib/middleman/base.rb
|
139
159
|
- lib/middleman/builder.rb
|
160
|
+
- lib/middleman/config.ru
|
140
161
|
- lib/middleman/features/cache_buster.rb
|
141
162
|
- lib/middleman/features/compass.rb
|
142
|
-
- lib/middleman/features/content_for.rb
|
143
163
|
- lib/middleman/features/growl.rb
|
144
|
-
- lib/middleman/features/haml.rb
|
145
164
|
- lib/middleman/features/maruku.rb
|
146
165
|
- lib/middleman/features/minify_css.rb
|
147
166
|
- lib/middleman/features/minify_javascript.rb
|
148
167
|
- lib/middleman/features/relative_assets.rb
|
149
168
|
- lib/middleman/features/slickmap.rb
|
150
169
|
- lib/middleman/features/smush_pngs.rb
|
151
|
-
- lib/middleman/
|
152
|
-
- lib/middleman/features/sprockets.rb
|
170
|
+
- lib/middleman/haml.rb
|
153
171
|
- lib/middleman/helpers.rb
|
172
|
+
- lib/middleman/rack/sprockets+ruby19.rb
|
173
|
+
- lib/middleman/rack/sprockets.rb
|
174
|
+
- lib/middleman/rack/static.rb
|
175
|
+
- lib/middleman/sass.rb
|
154
176
|
- lib/middleman/template/init.rbt
|
155
177
|
- lib/middleman/template/views/index.html.haml
|
156
178
|
- lib/middleman/template/views/layout.html.haml
|
@@ -160,13 +182,13 @@ files:
|
|
160
182
|
- spec/builder_spec.rb
|
161
183
|
- spec/cache_buster_spec.rb
|
162
184
|
- spec/fixtures/sample/init.rb
|
163
|
-
- spec/fixtures/sample/public/javascripts/empty-with-include.js
|
164
185
|
- spec/fixtures/sample/public/javascripts/to-be-included.js
|
165
186
|
- spec/fixtures/sample/public/static.html
|
166
187
|
- spec/fixtures/sample/public/stylesheets/static.css
|
167
188
|
- spec/fixtures/sample/views/_partial.haml
|
168
189
|
- spec/fixtures/sample/views/index.html.haml
|
169
190
|
- spec/fixtures/sample/views/inline-js.html.haml
|
191
|
+
- spec/fixtures/sample/views/javascripts/empty-with-include.js
|
170
192
|
- spec/fixtures/sample/views/layout.haml
|
171
193
|
- spec/fixtures/sample/views/maruku.html.maruku
|
172
194
|
- spec/fixtures/sample/views/services/index.html.haml
|
@@ -1,29 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'sprockets'
|
3
|
-
require 'middleman/features/sprockets+ruby19' # Sprockets ruby 1.9 duckpunch
|
4
|
-
rescue LoadError
|
5
|
-
puts "Sprockets not available. Install it with: gem install sprockets"
|
6
|
-
end
|
7
|
-
|
8
|
-
module Middleman
|
9
|
-
module Sprockets
|
10
|
-
def self.included(base)
|
11
|
-
base.supported_formats << "js"
|
12
|
-
end
|
13
|
-
|
14
|
-
def render_path(path)
|
15
|
-
source = File.join(options.public, path)
|
16
|
-
if File.extname(path) == '.js' && File.exists?(source)
|
17
|
-
secretary = ::Sprockets::Secretary.new( :asset_root => options.public,
|
18
|
-
:source_files => [source] )
|
19
|
-
secretary.concatenation.to_s
|
20
|
-
else
|
21
|
-
super
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class Middleman::Base
|
28
|
-
include Middleman::Sprockets
|
29
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
//= require "to-be-included"
|