middleman 3.0.0.alpha.5 → 3.0.0.alpha.6
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/CHANGELOG.md +3 -2
- data/README.md +7 -7
- data/bin/middleman +3 -2
- data/features/builder.feature +4 -0
- data/features/cli.feature +10 -11
- data/features/nested_layouts.feature +24 -0
- data/features/sitemap_traversal.features +56 -0
- data/fixtures/empty-app/not-config.rb +0 -0
- data/fixtures/nested-layout-app/config.rb +1 -0
- data/fixtures/nested-layout-app/source/data-one.html.erb +5 -0
- data/fixtures/nested-layout-app/source/data-two.html.erb +5 -0
- data/fixtures/nested-layout-app/source/index.html.erb +1 -0
- data/fixtures/nested-layout-app/source/layouts/inner.erb +4 -0
- data/fixtures/nested-layout-app/source/layouts/master.erb +3 -0
- data/fixtures/nested-layout-app/source/layouts/outer.erb +4 -0
- data/fixtures/traversal-app/config.rb +2 -0
- data/fixtures/traversal-app/source/index.html.erb +0 -0
- data/fixtures/traversal-app/source/layout.erb +13 -0
- data/fixtures/traversal-app/source/proxied.html.erb +0 -0
- data/fixtures/traversal-app/source/root.html.erb +0 -0
- data/fixtures/traversal-app/source/sub/index.html.erb +0 -0
- data/fixtures/traversal-app/source/sub/sibling.html.erb +0 -0
- data/fixtures/traversal-app/source/sub/sibling2.html.erb +0 -0
- data/fixtures/traversal-app/source/sub/sub2/index.html.erb +0 -0
- data/fixtures/traversal-app/source/sub/sub3/deep.html.erb +0 -0
- data/lib/middleman.rb +0 -3
- data/lib/middleman/base.rb +3 -28
- data/lib/middleman/cli/server.rb +0 -1
- data/lib/middleman/core_extensions/builder.rb +1 -7
- data/lib/middleman/core_extensions/default_helpers.rb +27 -1
- data/lib/middleman/core_extensions/extensions.rb +20 -4
- data/lib/middleman/core_extensions/file_watcher.rb +25 -8
- data/lib/middleman/core_extensions/front_matter.rb +5 -12
- data/lib/middleman/core_extensions/rendering.rb +10 -0
- data/lib/middleman/core_extensions/sitemap.rb +4 -0
- data/lib/middleman/guard.rb +11 -11
- data/lib/middleman/sitemap/page.rb +55 -0
- data/lib/middleman/sitemap/template.rb +9 -3
- data/lib/middleman/step_definitions.rb +0 -1
- data/lib/middleman/templates/default.rb +7 -2
- data/lib/middleman/templates/default/source/images/background.png +0 -0
- data/lib/middleman/templates/default/source/images/middleman.png +0 -0
- data/lib/middleman/templates/default/source/index.html.erb +9 -4
- data/lib/middleman/templates/default/source/javascripts/all.js +1 -0
- data/lib/middleman/templates/default/source/layouts/layout.erb +19 -0
- data/lib/middleman/templates/default/source/stylesheets/_animate.scss +23 -0
- data/lib/middleman/templates/default/source/stylesheets/_normalize.scss +431 -0
- data/lib/middleman/templates/default/source/stylesheets/all.css.scss +40 -0
- data/lib/middleman/templates/shared/config.tt +4 -16
- data/lib/middleman/version.rb +1 -1
- data/middleman-x86-mingw32.gemspec +1 -1
- data/middleman.gemspec +1 -1
- metadata +54 -13
- data/features/generator.feature +0 -8
- data/lib/middleman/extensions/sitemap_tree.rb +0 -38
- data/lib/middleman/step_definitions/generator_steps.rb +0 -26
- data/lib/middleman/templates/default/source/layout.erb +0 -19
- data/lib/middleman/templates/default/source/stylesheets/site.css.scss +0 -32
@@ -31,9 +31,12 @@
|
|
31
31
|
# Using for version parsing
|
32
32
|
require "rubygems"
|
33
33
|
|
34
|
+
# Namespace extensions module
|
34
35
|
module Middleman::CoreExtensions::Extensions
|
35
36
|
|
37
|
+
# Register extension
|
36
38
|
class << self
|
39
|
+
# @private
|
37
40
|
def included(app)
|
38
41
|
# app.set :default_extensions, []
|
39
42
|
app.define_hook :after_configuration
|
@@ -43,18 +46,31 @@ module Middleman::CoreExtensions::Extensions
|
|
43
46
|
|
44
47
|
app.extend ClassMethods
|
45
48
|
app.send :include, InstanceMethods
|
49
|
+
app.delegate :configure, :to => :"self.class"
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
53
|
+
# Class methods
|
49
54
|
module ClassMethods
|
55
|
+
# Add a callback to run in a specific environment
|
56
|
+
#
|
57
|
+
# @param [String, Symbol] env The environment to run in
|
58
|
+
# @return [void]
|
50
59
|
def configure(env, &block)
|
51
60
|
send("#{env}_config", &block)
|
52
61
|
end
|
53
62
|
|
63
|
+
# Alias `extensions` to access registered extensions
|
64
|
+
#
|
65
|
+
# @return [Array<Module]
|
54
66
|
def extensions
|
55
67
|
@extensions ||= []
|
56
68
|
end
|
57
69
|
|
70
|
+
# Register a new extension
|
71
|
+
#
|
72
|
+
# @param [Array<Module>] new_extensions Extension modules to register
|
73
|
+
# @return [Array<Module]
|
58
74
|
def register(*new_extensions)
|
59
75
|
@extensions ||= []
|
60
76
|
@extensions += new_extensions
|
@@ -65,12 +81,16 @@ module Middleman::CoreExtensions::Extensions
|
|
65
81
|
end
|
66
82
|
end
|
67
83
|
|
84
|
+
# Instance methods
|
68
85
|
module InstanceMethods
|
69
86
|
# This method is available in the project's `config.rb`.
|
70
87
|
# It takes a underscore-separated symbol, finds the appropriate
|
71
88
|
# feature module and includes it.
|
72
89
|
#
|
73
90
|
# activate :lorem
|
91
|
+
#
|
92
|
+
# @param [Symbol, Module] feature Which extension to activate
|
93
|
+
# @return [void]
|
74
94
|
def activate(feature)
|
75
95
|
ext = ::Middleman::Extensions.load(feature.to_sym)
|
76
96
|
|
@@ -83,10 +103,6 @@ module Middleman::CoreExtensions::Extensions
|
|
83
103
|
self.class.register(ext)
|
84
104
|
end
|
85
105
|
end
|
86
|
-
|
87
|
-
def configure(env, &block)
|
88
|
-
self.class.configure(env, &block)
|
89
|
-
end
|
90
106
|
|
91
107
|
# Load features before starting server
|
92
108
|
def initialize
|
@@ -1,11 +1,17 @@
|
|
1
1
|
require "find"
|
2
2
|
|
3
|
+
# API for watching file change events
|
3
4
|
module Middleman::CoreExtensions::FileWatcher
|
5
|
+
# Setup extension
|
4
6
|
class << self
|
7
|
+
# @private
|
5
8
|
def registered(app)
|
6
9
|
app.extend ClassMethods
|
7
10
|
app.send :include, InstanceMethods
|
8
11
|
|
12
|
+
app.delegate :file_changed, :file_deleted, :to => :"self.class"
|
13
|
+
|
14
|
+
# Before parsing config, load the data/ directory
|
9
15
|
app.before_configuration do
|
10
16
|
data_path = File.join(root, data_dir)
|
11
17
|
Find.find(data_path) do |path|
|
@@ -14,6 +20,7 @@ module Middleman::CoreExtensions::FileWatcher
|
|
14
20
|
end if File.exists?(data_path)
|
15
21
|
end
|
16
22
|
|
23
|
+
# After config, load everything else
|
17
24
|
app.ready do
|
18
25
|
Find.find(root) do |path|
|
19
26
|
next if File.directory?(path)
|
@@ -24,13 +31,22 @@ module Middleman::CoreExtensions::FileWatcher
|
|
24
31
|
alias :included :registered
|
25
32
|
end
|
26
33
|
|
34
|
+
# Class methods
|
27
35
|
module ClassMethods
|
36
|
+
# Add callback to be run on file change
|
37
|
+
#
|
38
|
+
# @param [nil,Regexp] matcher A Regexp to match the change path against
|
39
|
+
# @return [Array<Proc>]
|
28
40
|
def file_changed(matcher=nil, &block)
|
29
41
|
@_file_changed ||= []
|
30
42
|
@_file_changed << [block, matcher] if block_given?
|
31
43
|
@_file_changed
|
32
44
|
end
|
33
45
|
|
46
|
+
# Add callback to be run on file deletion
|
47
|
+
#
|
48
|
+
# @param [nil,Regexp] matcher A Regexp to match the deleted path against
|
49
|
+
# @return [Array<Proc>]
|
34
50
|
def file_deleted(matcher=nil, &block)
|
35
51
|
@_file_deleted ||= []
|
36
52
|
@_file_deleted << [block, matcher] if block_given?
|
@@ -38,11 +54,12 @@ module Middleman::CoreExtensions::FileWatcher
|
|
38
54
|
end
|
39
55
|
end
|
40
56
|
|
57
|
+
# Instance methods
|
41
58
|
module InstanceMethods
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
59
|
+
# Notify callbacks that a file changed
|
60
|
+
#
|
61
|
+
# @param [String] path The file that changed
|
62
|
+
# @return [void]
|
46
63
|
def file_did_change(path)
|
47
64
|
file_changed.each do |callback, matcher|
|
48
65
|
next if path.match(%r{^#{build_dir}/})
|
@@ -50,11 +67,11 @@ module Middleman::CoreExtensions::FileWatcher
|
|
50
67
|
instance_exec(path, &callback)
|
51
68
|
end
|
52
69
|
end
|
53
|
-
|
54
|
-
def file_deleted(*args)
|
55
|
-
self.class.file_deleted(*args)
|
56
|
-
end
|
57
70
|
|
71
|
+
# Notify callbacks that a file was deleted
|
72
|
+
#
|
73
|
+
# @param [String] path The file that was deleted
|
74
|
+
# @return [void]
|
58
75
|
def file_did_delete(path)
|
59
76
|
file_deleted.each do |callback, matcher|
|
60
77
|
next if path.match(%r{^#{build_dir}/})
|
@@ -7,6 +7,7 @@ module Middleman::CoreExtensions::FrontMatter
|
|
7
7
|
app.set :frontmatter_extensions, %w(.htm .html .php)
|
8
8
|
app.extend ClassMethods
|
9
9
|
app.send :include, InstanceMethods
|
10
|
+
app.delegate :frontmatter_changed, :to => :"self.class"
|
10
11
|
end
|
11
12
|
alias :included :registered
|
12
13
|
end
|
@@ -37,28 +38,20 @@ module Middleman::CoreExtensions::FrontMatter
|
|
37
38
|
provides_metadata matcher do |path|
|
38
39
|
relative_path = path.sub(source_dir, "")
|
39
40
|
|
40
|
-
|
41
|
+
fmdata = if frontmatter.has_data?(relative_path)
|
41
42
|
frontmatter.data(relative_path)[0]
|
42
43
|
else
|
43
44
|
{}
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
data_content("page", data)
|
48
|
-
|
47
|
+
data = {}
|
49
48
|
%w(layout layout_engine).each do |opt|
|
50
|
-
if
|
51
|
-
data[opt.to_sym] = data.delete(opt)
|
52
|
-
end
|
49
|
+
data[opt.to_sym] = fmdata[opt] if fmdata.has_key?(opt)
|
53
50
|
end
|
54
51
|
|
55
|
-
{ :options => data }
|
52
|
+
{ :options => data, :page => fmdata }
|
56
53
|
end
|
57
54
|
end
|
58
|
-
|
59
|
-
def frontmatter_changed(*args, &block)
|
60
|
-
self.class.frontmatter_changed(*args, &block)
|
61
|
-
end
|
62
55
|
|
63
56
|
def frontmatter_did_change(path)
|
64
57
|
frontmatter_changed.each do |callback, matcher|
|
@@ -44,6 +44,8 @@ module Middleman::CoreExtensions::Rendering
|
|
44
44
|
# the template don't persist for other templates.
|
45
45
|
context = self.dup
|
46
46
|
|
47
|
+
@current_locs = locs, @current_opts = opts
|
48
|
+
|
47
49
|
while ::Tilt[path]
|
48
50
|
content = render_individual_file(path, locs, opts, context)
|
49
51
|
path = File.basename(path, File.extname(path))
|
@@ -60,6 +62,8 @@ module Middleman::CoreExtensions::Rendering
|
|
60
62
|
ensure
|
61
63
|
@current_engine = engine_was
|
62
64
|
@content_blocks = nil
|
65
|
+
@current_locs = nil
|
66
|
+
@current_opts = nil
|
63
67
|
end
|
64
68
|
|
65
69
|
# Sinatra/Padrino render method signature.
|
@@ -198,6 +202,12 @@ module Middleman::CoreExtensions::Rendering
|
|
198
202
|
|
199
203
|
layout_path
|
200
204
|
end
|
205
|
+
|
206
|
+
def wrap_layout(layout_name, &block)
|
207
|
+
content = capture(&block) if block_given?
|
208
|
+
layout_path = locate_layout(layout_name, current_engine)
|
209
|
+
concat render_individual_file(layout_path, @current_locs || {}, @current_opts || {}, self) { content }
|
210
|
+
end
|
201
211
|
|
202
212
|
def current_engine
|
203
213
|
@current_engine ||= nil
|
data/lib/middleman/guard.rb
CHANGED
@@ -41,12 +41,6 @@ module Guard
|
|
41
41
|
def initialize(watchers = [], options = {})
|
42
42
|
super
|
43
43
|
@options = options
|
44
|
-
|
45
|
-
# Trap the interupt signal and shut down Guard (and thus the server) smoothly
|
46
|
-
trap(kill_command) do
|
47
|
-
::Guard.stop
|
48
|
-
exit!(0)
|
49
|
-
end
|
50
44
|
end
|
51
45
|
|
52
46
|
# Start Middleman in a fork
|
@@ -81,7 +75,7 @@ module Guard
|
|
81
75
|
puts "== The Middleman is shutting down"
|
82
76
|
if ::Middleman::JRUBY
|
83
77
|
else
|
84
|
-
Process.kill(
|
78
|
+
Process.kill(::Middleman::WINDOWS ? :KILL : :TERM, @server_job)
|
85
79
|
Process.wait @server_job
|
86
80
|
@server_job = nil
|
87
81
|
end
|
@@ -113,6 +107,10 @@ module Guard
|
|
113
107
|
paths.each { |path| tell_server(:delete => path) }
|
114
108
|
end
|
115
109
|
|
110
|
+
def self.kill_command
|
111
|
+
::Middleman::WINDOWS ? 1 : :INT
|
112
|
+
end
|
113
|
+
|
116
114
|
private
|
117
115
|
# Whether the passed files are config.rb or lib/*.rb
|
118
116
|
# @param [Array<String>] paths Array of paths to check
|
@@ -129,9 +127,11 @@ module Guard
|
|
129
127
|
uri = URI.parse("http://#{@options[:host]}:#{@options[:port]}/__middleman__")
|
130
128
|
Net::HTTP.post_form(uri, {}.merge(params))
|
131
129
|
end
|
132
|
-
|
133
|
-
def kill_command
|
134
|
-
::Middleman::WINDOWS ? 1 : :INT
|
135
|
-
end
|
136
130
|
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Trap the interupt signal and shut down Guard (and thus the server) smoothly
|
134
|
+
trap(::Guard::Middleman.kill_command) do
|
135
|
+
::Guard.stop
|
136
|
+
exit!(0)
|
137
137
|
end
|
@@ -99,6 +99,61 @@ module Middleman::Sitemap
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
+
def directory_index?
|
103
|
+
path.include?(app.index_file) || path =~ /\/$/
|
104
|
+
end
|
105
|
+
|
106
|
+
def parent
|
107
|
+
parts = path.split("/")
|
108
|
+
if path.include?(app.index_file)
|
109
|
+
parts.pop
|
110
|
+
else
|
111
|
+
end
|
112
|
+
|
113
|
+
return nil if parts.length < 1
|
114
|
+
|
115
|
+
parts.pop
|
116
|
+
parts.push(app.index_file)
|
117
|
+
|
118
|
+
parent_path = "/" + parts.join("/")
|
119
|
+
|
120
|
+
if store.exists?(parent_path)
|
121
|
+
store.page(parent_path)
|
122
|
+
else
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def children
|
128
|
+
return [] unless directory_index?
|
129
|
+
|
130
|
+
base_path = path.sub("#{app.index_file}", "")
|
131
|
+
prefix = /^#{base_path.sub("/", "\\/")}/
|
132
|
+
|
133
|
+
store.all_paths.select do |sub_path|
|
134
|
+
sub_path =~ prefix
|
135
|
+
end.select do |sub_path|
|
136
|
+
path != sub_path
|
137
|
+
end.select do |sub_path|
|
138
|
+
relative_path = sub_path.sub(prefix, "")
|
139
|
+
parts = relative_path.split("/")
|
140
|
+
if parts.length == 1
|
141
|
+
true
|
142
|
+
elsif parts.length == 2
|
143
|
+
parts.last == app.index_file
|
144
|
+
else
|
145
|
+
false
|
146
|
+
end
|
147
|
+
end.map do |p|
|
148
|
+
store.page(p)
|
149
|
+
end.reject { |p| p.ignored? }
|
150
|
+
end
|
151
|
+
|
152
|
+
def siblings
|
153
|
+
return [] unless parent
|
154
|
+
parent.children.reject { |p| p == self }
|
155
|
+
end
|
156
|
+
|
102
157
|
protected
|
103
158
|
def app
|
104
159
|
@store.app
|
@@ -36,7 +36,7 @@ module Middleman::Sitemap
|
|
36
36
|
|
37
37
|
def metadata
|
38
38
|
metadata = app.cache.fetch(:metadata, source_file) do
|
39
|
-
data = { :options => {}, :locals => {} }
|
39
|
+
data = { :options => {}, :locals => {}, :page => {} }
|
40
40
|
|
41
41
|
app.provides_metadata.each do |callback, matcher|
|
42
42
|
next if !matcher.nil? && !source_file.match(matcher)
|
@@ -57,8 +57,14 @@ module Middleman::Sitemap
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def render(opts={}, locs={}, &block)
|
60
|
-
|
61
|
-
|
60
|
+
md = metadata.dup
|
61
|
+
opts = options.deep_merge(md[:options]).deep_merge(opts)
|
62
|
+
locs = locals.deep_merge(md[:locals]).deep_merge(locs)
|
63
|
+
|
64
|
+
# Forward remaining data to helpers
|
65
|
+
if md.has_key?(:page)
|
66
|
+
app.data_content("page", md[:page])
|
67
|
+
end
|
62
68
|
|
63
69
|
blocks.compact.each do |block|
|
64
70
|
app.instance_eval(&block)
|
@@ -5,7 +5,6 @@ ENV['PATH'] = "#{MIDDLEMAN_BIN_PATH}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
|
5
5
|
require "aruba/cucumber"
|
6
6
|
require "middleman/step_definitions/middleman_steps"
|
7
7
|
require "middleman/step_definitions/builder_steps"
|
8
|
-
require "middleman/step_definitions/generator_steps"
|
9
8
|
require "middleman/step_definitions/server_steps"
|
10
9
|
|
11
10
|
Before do
|
@@ -12,11 +12,16 @@ class Middleman::Templates::Default < Middleman::Templates::Base
|
|
12
12
|
def build_scaffold!
|
13
13
|
template "shared/config.tt", File.join(location, "config.rb")
|
14
14
|
copy_file "default/source/index.html.erb", File.join(location, "source/index.html.erb")
|
15
|
-
copy_file "default/source/layout.erb", File.join(location, "source/layout.erb")
|
15
|
+
copy_file "default/source/layouts/layout.erb", File.join(location, "source/layouts/layout.erb")
|
16
16
|
empty_directory File.join(location, "source", options[:css_dir])
|
17
|
-
copy_file "default/source/stylesheets/
|
17
|
+
copy_file "default/source/stylesheets/all.css.scss", File.join(location, "source", options[:css_dir], "all.css.scss")
|
18
|
+
copy_file "default/source/stylesheets/_animate.scss", File.join(location, "source", options[:css_dir], "_animate.scss")
|
19
|
+
copy_file "default/source/stylesheets/_normalize.scss", File.join(location, "source", options[:css_dir], "_normalize.scss")
|
18
20
|
empty_directory File.join(location, "source", options[:js_dir])
|
21
|
+
copy_file "default/source/javascripts/all.js", File.join(location, "source", options[:js_dir], "all.js")
|
19
22
|
empty_directory File.join(location, "source", options[:images_dir])
|
23
|
+
copy_file "default/source/images/background.png", File.join(location, "source", options[:images_dir], "background.png")
|
24
|
+
copy_file "default/source/images/middleman.png", File.join(location, "source", options[:images_dir], "middleman.png")
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
Binary file
|
Binary file
|
@@ -1,5 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
---
|
2
|
+
title: Welcome to Middleman
|
3
|
+
---
|
4
4
|
|
5
|
-
<
|
5
|
+
<div class="welcome">
|
6
|
+
<h1>Middleman is Watching</h1>
|
7
|
+
<p class="doc">
|
8
|
+
<%= link_to "Read Online Documentation", "http://middlemanapp.com/" %>
|
9
|
+
</p><!-- .doc -->
|
10
|
+
</div><!-- .welcome -->
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require_tree .
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
|
6
|
+
<!-- Always force latest IE rendering engine or request Chrome Frame -->
|
7
|
+
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
8
|
+
|
9
|
+
<!-- Use title if it's in the page YAML frontmatter -->
|
10
|
+
<title><%= data.page.title || "The Middleman" %></title>
|
11
|
+
|
12
|
+
<%= stylesheet_link_tag "all" %>
|
13
|
+
<%= javascript_include_tag "all" %>
|
14
|
+
</head>
|
15
|
+
|
16
|
+
<body class="<%= page_classes %>">
|
17
|
+
<%= yield %>
|
18
|
+
</body>
|
19
|
+
</html>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.welcome {
|
2
|
+
-webkit-animation-name: welcome;
|
3
|
+
-webkit-animation-duration: .9s;
|
4
|
+
}
|
5
|
+
|
6
|
+
@-webkit-keyframes welcome {
|
7
|
+
from {
|
8
|
+
-webkit-transform: scale(0);
|
9
|
+
opacity: 0;
|
10
|
+
}
|
11
|
+
50% {
|
12
|
+
-webkit-transform: scale(0);
|
13
|
+
opacity: 0;
|
14
|
+
}
|
15
|
+
82.5% {
|
16
|
+
-webkit-transform: scale(1.03);
|
17
|
+
-webkit-animation-timing-function: ease-out;
|
18
|
+
opacity: 1;
|
19
|
+
}
|
20
|
+
to {
|
21
|
+
-webkit-transform: scale(1);
|
22
|
+
}
|
23
|
+
}
|