middleman-more 3.0.0.beta.2 → 3.0.0.beta.3
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/features/asset_hash.feature +24 -24
- data/features/ignore_already_minified.feature +39 -4
- data/features/markdown.feature +3 -12
- data/features/markdown_redcarpet.feature +37 -0
- data/features/minify_css.feature +72 -10
- data/features/minify_javascript.feature +108 -10
- data/features/slim.feature +15 -1
- data/fixtures/markdown-app/config.rb +0 -9
- data/lib/middleman-more.rb +1 -74
- data/lib/middleman-more/core_extensions/compass.rb +49 -48
- data/lib/middleman-more/core_extensions/sprockets.rb +10 -2
- data/lib/middleman-more/extensions/asset_hash.rb +9 -23
- data/lib/middleman-more/extensions/cache_buster.rb +51 -53
- data/lib/middleman-more/extensions/gzip.rb +14 -0
- data/lib/middleman-more/extensions/minify_css.rb +60 -70
- data/lib/middleman-more/extensions/minify_javascript.rb +70 -77
- data/lib/middleman-more/extensions/relative_assets.rb +47 -47
- data/lib/middleman-more/register_extensions.rb +82 -0
- data/lib/middleman-more/renderers/coffee_script.rb +22 -0
- data/lib/middleman-more/renderers/haml.rb +24 -19
- data/lib/middleman-more/renderers/liquid.rb +28 -23
- data/lib/middleman-more/renderers/markdown.rb +50 -42
- data/lib/middleman-more/renderers/sass.rb +70 -63
- data/lib/middleman-more/renderers/slim.rb +27 -19
- data/middleman-more.gemspec +6 -7
- metadata +34 -43
- data/fixtures/already-minified-app/config.rb +0 -2
- data/fixtures/already-minified-app/source/javascripts/test.min.js +0 -10
- data/fixtures/already-minified-app/source/stylesheets/test.min.css +0 -10
- data/fixtures/minify-css-app/config.rb +0 -0
- data/fixtures/passthrough-app/config.rb +0 -17
- data/fixtures/slim-app/config.rb +0 -1
- data/fixtures/slim-app/source/slim.html.slim +0 -7
data/features/slim.feature
CHANGED
@@ -2,6 +2,20 @@ Feature: Support slim templating language
|
|
2
2
|
In order to offer an alternative to Haml
|
3
3
|
|
4
4
|
Scenario: Rendering Slim
|
5
|
-
Given
|
5
|
+
Given an empty app
|
6
|
+
And a file named "config.rb" with:
|
7
|
+
"""
|
8
|
+
"""
|
9
|
+
And a file named "source/slim.html.slim" with:
|
10
|
+
"""
|
11
|
+
doctype 5
|
12
|
+
html lang='en'
|
13
|
+
head
|
14
|
+
meta charset="utf-8"
|
15
|
+
|
16
|
+
body
|
17
|
+
h1 Welcome to Slim
|
18
|
+
"""
|
19
|
+
And the Server is running at "empty_app"
|
6
20
|
When I go to "/slim.html"
|
7
21
|
Then I should see "<h1>Welcome to Slim</h1>"
|
data/lib/middleman-more.rb
CHANGED
@@ -3,77 +3,4 @@ libdir = File.expand_path(File.dirname(__FILE__))
|
|
3
3
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
4
4
|
|
5
5
|
require "middleman-core"
|
6
|
-
|
7
|
-
# Top-level Middleman object
|
8
|
-
module Middleman
|
9
|
-
|
10
|
-
# Custom Renderers
|
11
|
-
module Renderers
|
12
|
-
autoload :Haml, "middleman-more/renderers/haml"
|
13
|
-
autoload :Sass, "middleman-more/renderers/sass"
|
14
|
-
autoload :Markdown, "middleman-more/renderers/markdown"
|
15
|
-
autoload :Liquid, "middleman-more/renderers/liquid"
|
16
|
-
autoload :Slim, "middleman-more/renderers/slim"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Core (automatic) extensions
|
20
|
-
module CoreExtensions
|
21
|
-
# Compass framework for Sass
|
22
|
-
autoload :Compass, "middleman-more/core_extensions/compass"
|
23
|
-
|
24
|
-
# Sprockets 2
|
25
|
-
autoload :Sprockets, "middleman-more/core_extensions/sprockets"
|
26
|
-
end
|
27
|
-
|
28
|
-
# User-activatable extensions
|
29
|
-
module Extensions
|
30
|
-
# RelativeAssets allow any asset path in dynamic templates to be either
|
31
|
-
# relative to the root of the project or use an absolute URL.
|
32
|
-
autoload :RelativeAssets, "middleman-more/extensions/relative_assets"
|
33
|
-
|
34
|
-
# CacheBuster adds a query string to assets in dynamic templates to avoid
|
35
|
-
# browser caches failing to update to your new content.
|
36
|
-
autoload :CacheBuster, "middleman-more/extensions/cache_buster"
|
37
|
-
|
38
|
-
# AssetHash appends a hash of the file contents to the assets filename
|
39
|
-
# to avoid browser caches failing to update to your new content.
|
40
|
-
autoload :AssetHash, "middleman-more/extensions/asset_hash"
|
41
|
-
|
42
|
-
# MinifyCss uses the YUI compressor to shrink CSS files
|
43
|
-
autoload :MinifyCss, "middleman-more/extensions/minify_css"
|
44
|
-
|
45
|
-
# MinifyJavascript uses the YUI compressor to shrink JS files
|
46
|
-
autoload :MinifyJavascript, "middleman-more/extensions/minify_javascript"
|
47
|
-
|
48
|
-
# GZIP assets and pages during build
|
49
|
-
autoload :Gzip, "middleman-more/extensions/gzip"
|
50
|
-
end
|
51
|
-
|
52
|
-
# Setup renderers
|
53
|
-
require "coffee_script"
|
54
|
-
Application.register Middleman::Renderers::Haml
|
55
|
-
Application.register Middleman::Renderers::Sass
|
56
|
-
Application.register Middleman::Renderers::Markdown
|
57
|
-
Application.register Middleman::Renderers::Liquid
|
58
|
-
Application.register Middleman::Renderers::Slim
|
59
|
-
|
60
|
-
# Compass framework
|
61
|
-
Application.register Middleman::CoreExtensions::Compass
|
62
|
-
|
63
|
-
# Sprockets asset handling
|
64
|
-
Application.register Middleman::CoreExtensions::Sprockets
|
65
|
-
|
66
|
-
# Register the optional extensions
|
67
|
-
Extensions.register(:cache_buster) {
|
68
|
-
::Middleman::Extensions::CacheBuster }
|
69
|
-
Extensions.register(:minify_css) {
|
70
|
-
::Middleman::Extensions::MinifyCss }
|
71
|
-
Extensions.register(:minify_javascript) {
|
72
|
-
::Middleman::Extensions::MinifyJavascript }
|
73
|
-
Extensions.register(:relative_assets) {
|
74
|
-
::Middleman::Extensions::RelativeAssets }
|
75
|
-
Extensions.register(:gzip) {
|
76
|
-
::Middleman::Extensions::Gzip }
|
77
|
-
Extensions.register(:asset_hash) {
|
78
|
-
::Middleman::Extensions::AssetHash }
|
79
|
-
end
|
6
|
+
require "middleman-more/register_extensions"
|
@@ -1,60 +1,61 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Middleman
|
2
|
+
module CoreExtensions
|
3
|
+
|
4
|
+
# Forward the settings on config.rb and the result of registered
|
5
|
+
# extensions to Compass
|
6
|
+
module Compass
|
4
7
|
|
5
|
-
|
6
|
-
|
8
|
+
# Extension registered
|
9
|
+
class << self
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
# Once registered
|
12
|
+
def registered(app)
|
13
|
+
# Require the library
|
14
|
+
require "compass"
|
15
|
+
|
16
|
+
# Where to look for fonts
|
17
|
+
app.set :fonts_dir, "fonts"
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
app.define_hook :after_compass_config
|
19
|
+
# Hooks to manually update the compass config after we're
|
20
|
+
# done with it
|
21
|
+
app.define_hook :compass_config
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# Correctly support HTTP paths with generated sprites
|
30
|
-
# if config.respond_to? :http_generated_images_path
|
31
|
-
# config.http_generated_images_path = if app.respond_to? :http_generated_images_path
|
32
|
-
# app.http_generated_images_path
|
33
|
-
# else
|
34
|
-
# File.join(app.http_prefix || "/", app.images_dir)
|
35
|
-
# end
|
36
|
-
# end
|
23
|
+
app.after_configuration do
|
24
|
+
::Compass.configuration do |config|
|
25
|
+
config.project_path = source_dir
|
26
|
+
config.environment = :development
|
27
|
+
config.cache_path = File.join(root, ".sass-cache")
|
28
|
+
config.sass_dir = css_dir
|
29
|
+
config.css_dir = css_dir
|
30
|
+
config.javascripts_dir = js_dir
|
31
|
+
config.fonts_dir = fonts_dir
|
32
|
+
config.images_dir = images_dir
|
33
|
+
config.http_path = http_prefix
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
# Disable this initially, the cache_buster extension will
|
36
|
+
# re-enable it if requested.
|
37
|
+
config.asset_cache_buster :none
|
38
|
+
|
39
|
+
# Disable this initially, the relative_assets extension will
|
40
|
+
# re-enable it if requested.
|
41
|
+
config.relative_assets = false
|
42
|
+
|
43
|
+
# Default output style
|
44
|
+
config.output_style = :nested
|
41
45
|
|
42
|
-
|
43
|
-
|
46
|
+
if respond_to?(:asset_host) && asset_host.is_a?(Proc)
|
47
|
+
config.asset_host(&asset_host)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Call hook
|
52
|
+
run_hook :compass_config, ::Compass.configuration
|
44
53
|
end
|
45
54
|
end
|
46
|
-
|
47
|
-
# if build?
|
48
|
-
# ::Compass.configuration do |config|
|
49
|
-
# config.environment = :production
|
50
|
-
# config.project_path = File.join(root, build_dir)
|
51
|
-
# end
|
52
|
-
# end
|
53
|
-
|
54
|
-
run_hook :compass_config, ::Compass.configuration
|
55
|
-
run_hook :after_compass_config
|
55
|
+
alias :included :registered
|
56
56
|
end
|
57
|
+
|
57
58
|
end
|
58
|
-
|
59
|
+
|
59
60
|
end
|
60
61
|
end
|
@@ -52,8 +52,6 @@ module Middleman::CoreExtensions::Sprockets
|
|
52
52
|
@app = app
|
53
53
|
super app.source_dir
|
54
54
|
|
55
|
-
digest = Digest::SHA1
|
56
|
-
|
57
55
|
# Make the app context available to Sprockets
|
58
56
|
context_class.send(:define_method, :app) { app }
|
59
57
|
context_class.class_eval do
|
@@ -75,6 +73,16 @@ module Middleman::CoreExtensions::Sprockets
|
|
75
73
|
append_path app.css_dir
|
76
74
|
end
|
77
75
|
|
76
|
+
# Override Sprockets' default digest function to *not*
|
77
|
+
# change depending on the exact Sprockets version. It still takes
|
78
|
+
# into account "version" which is a user-suppliable version
|
79
|
+
# number that can be used to force assets to have a new
|
80
|
+
# hash.
|
81
|
+
def digest
|
82
|
+
@digest ||= Digest::SHA1.new.update(version.to_s)
|
83
|
+
@digest.dup
|
84
|
+
end
|
85
|
+
|
78
86
|
# During development, don't use the asset cache
|
79
87
|
def find_asset(path, options = {})
|
80
88
|
expire_index! if @app.development?
|
@@ -3,14 +3,16 @@ module Middleman::Extensions
|
|
3
3
|
module AssetHash
|
4
4
|
class << self
|
5
5
|
def registered(app, options)
|
6
|
-
exts = options[:exts] || %w(.
|
6
|
+
exts = options[:exts] || %w(.jpg .jpeg .png .gif .js .css)
|
7
|
+
|
8
|
+
# Allow specifying regexes to ignore, plus always ignore apple touch icons
|
9
|
+
ignore = Array(options[:ignore]) << /^apple-touch-icon/
|
7
10
|
|
8
11
|
app.ready do
|
9
12
|
sitemap.register_resource_list_manipulator(
|
10
13
|
:asset_hash,
|
11
|
-
AssetHashManager.new(self, exts)
|
14
|
+
AssetHashManager.new(self, exts, ignore)
|
12
15
|
)
|
13
|
-
|
14
16
|
use Middleware, :exts => exts, :middleman_app => self
|
15
17
|
end
|
16
18
|
end
|
@@ -18,16 +20,17 @@ module Middleman::Extensions
|
|
18
20
|
end
|
19
21
|
|
20
22
|
class AssetHashManager
|
21
|
-
def initialize(app, exts)
|
23
|
+
def initialize(app, exts, ignore)
|
22
24
|
@app = app
|
23
25
|
@exts = exts
|
26
|
+
@ignore = ignore
|
24
27
|
end
|
25
28
|
|
26
29
|
# Update the main sitemap resource list
|
27
30
|
# @return [void]
|
28
31
|
def manipulate_resource_list(resources)
|
29
32
|
resources.each do |resource|
|
30
|
-
if @exts.include? resource.
|
33
|
+
if @exts.include?(resource.ext) && @ignore.none? {|ignore| resource.path =~ ignore }
|
31
34
|
# figure out the path Sprockets would use for this asset
|
32
35
|
if resource.ext == '.js'
|
33
36
|
sprockets_path = resource.path.sub(@app.js_dir,'').sub(/^\//,'')
|
@@ -69,7 +72,7 @@ module Middleman::Extensions
|
|
69
72
|
dirpath = Pathname.new(File.dirname(path))
|
70
73
|
|
71
74
|
if path =~ /(^\/$)|(\.(htm|html|php|css|js)$)/
|
72
|
-
body = extract_response_text(response)
|
75
|
+
body = ::Middleman::Util.extract_response_text(response)
|
73
76
|
|
74
77
|
if body
|
75
78
|
# TODO: This regex will change some paths in plan HTML (not in a tag) - is that OK?
|
@@ -94,23 +97,6 @@ module Middleman::Extensions
|
|
94
97
|
end
|
95
98
|
[status, headers, response]
|
96
99
|
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
def extract_response_text(response)
|
101
|
-
case(response)
|
102
|
-
when String
|
103
|
-
response
|
104
|
-
when Array
|
105
|
-
response.join
|
106
|
-
when Rack::Response
|
107
|
-
response.body.join
|
108
|
-
when Rack::File
|
109
|
-
File.read(response.path)
|
110
|
-
else
|
111
|
-
response.to_s
|
112
|
-
end
|
113
|
-
end
|
114
100
|
end
|
115
101
|
end
|
116
102
|
|
@@ -1,73 +1,71 @@
|
|
1
1
|
# Extension namespace
|
2
|
-
module Middleman
|
2
|
+
module Middleman
|
3
|
+
module Extensions
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
# The Cache Buster extension
|
6
|
+
module CacheBuster
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
# Setup extension
|
9
|
+
class << self
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
# Once registered
|
12
|
+
def registered(app)
|
13
|
+
# Add instance methods to context
|
14
|
+
app.send :include, InstanceMethods
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
# After compass is setup, make it use the registered cache buster
|
17
|
+
app.compass_config do |config|
|
18
|
+
config.asset_cache_buster do |path, real_path|
|
19
|
+
real_path = real_path.path if real_path.is_a? File
|
20
|
+
real_path = real_path.gsub(File.join(root, build_dir), source)
|
21
|
+
if File.readable?(real_path)
|
22
|
+
File.mtime(real_path).strftime("%s")
|
23
|
+
else
|
24
|
+
$stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
29
|
+
alias :included :registered
|
27
30
|
end
|
28
|
-
alias :included :registered
|
29
|
-
end
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
# Cache buster instance methods
|
33
|
+
module InstanceMethods
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
# asset_url override if we're using cache busting
|
36
|
+
# @param [String] path
|
37
|
+
# @param [String] prefix
|
38
|
+
def asset_url(path, prefix="")
|
39
|
+
http_path = super
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
41
|
+
if http_path.include?("://") || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path))
|
42
|
+
http_path
|
43
|
+
else
|
44
|
+
if respond_to?(:http_images_path) && prefix == http_images_path
|
45
|
+
prefix = images_dir
|
46
|
+
end
|
47
47
|
|
48
|
-
|
48
|
+
real_path_static = File.join(prefix, path)
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
50
|
+
if build?
|
51
|
+
real_path_dynamic = File.join(build_dir, prefix, path)
|
52
|
+
real_path_dynamic = File.expand_path(real_path_dynamic, root)
|
53
|
+
http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
|
54
|
+
elsif resource = sitemap.find_resource_by_path(real_path_static)
|
55
|
+
if !resource.template?
|
56
|
+
http_path << "?" + File.mtime(resource.source_file).strftime("%s")
|
57
|
+
else
|
58
|
+
# It's a template, possible with partials. We can't really
|
59
|
+
# know when it's updated, so generate fresh cache buster every
|
60
|
+
# time during developement
|
61
|
+
http_path << "?" + Time.now.strftime("%s")
|
62
|
+
end
|
62
63
|
end
|
63
|
-
end
|
64
64
|
|
65
|
-
|
65
|
+
http_path
|
66
|
+
end
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
70
|
-
|
71
|
-
# Register the extension
|
72
|
-
# register :cache_buster, CacheBuster
|
73
|
-
end
|
71
|
+
end
|
@@ -39,12 +39,26 @@ module Middleman::Extensions
|
|
39
39
|
def gzip_file(path, builder)
|
40
40
|
input_file = File.open(path, 'r').read
|
41
41
|
output_filename = path + '.gz'
|
42
|
+
input_file_time = File.mtime(path)
|
43
|
+
|
44
|
+
# Check if the right file's already there
|
45
|
+
if File.exist?(output_filename) && File.mtime(output_filename) == input_file_time
|
46
|
+
return
|
47
|
+
end
|
48
|
+
|
42
49
|
File.open(output_filename, 'w') do |f|
|
43
50
|
gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
|
51
|
+
gz.mtime = input_file_time.to_i
|
44
52
|
gz.write input_file
|
45
53
|
gz.close
|
46
54
|
end
|
47
55
|
|
56
|
+
# Make the file times match, both for Nginx's gzip_static extension
|
57
|
+
# and so we can ID existing files. Also, so even if the GZ files are
|
58
|
+
# wiped out by build --clean and recreated, we won't rsync them over
|
59
|
+
# again because they'll end up with the same mtime.
|
60
|
+
File.utime(File.atime(output_filename), input_file_time, output_filename)
|
61
|
+
|
48
62
|
old_size = File.size(path)
|
49
63
|
new_size = File.size(output_filename)
|
50
64
|
|