simpler guard-based frontmatter, use rackmap everywhere (tests, server, build)

This commit is contained in:
Thomas Reynolds 2011-11-10 12:26:20 -08:00
parent 055f7c2a41
commit 2682bbf6ea
14 changed files with 104 additions and 120 deletions

View file

@ -29,7 +29,9 @@ Given /^the Server is running at "([^\"]*)"$/ do |app_path|
@server.set :show_exceptions, false @server.set :show_exceptions, false
root = File.dirname(File.dirname(File.dirname(__FILE__))) root = File.dirname(File.dirname(File.dirname(__FILE__)))
@server.set :root, File.join(root, "fixtures", app_path) @server.set :root, File.join(root, "fixtures", app_path)
@browser = Rack::Test::Session.new(Rack::MockSession.new(@server.new)) @app = @server.new!
app_rack = @server.build_new(@app)
@browser = Rack::Test::Session.new(Rack::MockSession.new(app_rack))
end end
When /^I go to "([^\"]*)"$/ do |url| When /^I go to "([^\"]*)"$/ do |url|

View file

@ -1,5 +1 @@
---
layout: false
---
I am real: one I am real: one

View file

@ -1,5 +1 @@
---
layout: false
---
I am real: two I am real: two

View file

@ -1,5 +1 @@
---
layout: false
---
I am real: I am real:

View file

@ -186,7 +186,6 @@ module Middleman::Base
# 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
request.path_info = self.class.path_to_index(request.path) request.path_info = self.class.path_to_index(request.path)
request_path = request.path_info.gsub("%20", " ") request_path = request.path_info.gsub("%20", " ")
found_template = resolve_template(request_path, :raise_exceptions => false) found_template = resolve_template(request_path, :raise_exceptions => false)
return status(404) unless found_template return status(404) unless found_template
@ -206,7 +205,7 @@ module Middleman::Base
else else
false false
end end
render_options = { :layout => local_layout } render_options = { :layout => local_layout }
render_options[:layout_engine] = options[:layout_engine] if options.has_key? :layout_engine render_options[:layout_engine] = options[:layout_engine] if options.has_key? :layout_engine

View file

@ -38,7 +38,9 @@ module Middleman
def self.shared_rack def self.shared_rack
@shared_rack ||= begin @shared_rack ||= begin
mock = ::Rack::MockSession.new(SHARED_SERVER) app = SHARED_SERVER.new!
app_rack = SHARED_SERVER.build_new(app)
mock = ::Rack::MockSession.new(app_rack)
sess = ::Rack::Test::Session.new(mock) sess = ::Rack::Test::Session.new(mock)
response = sess.get("__middleman__") response = sess.get("__middleman__")
sess sess

View file

@ -3,10 +3,9 @@ module Middleman::CoreExtensions::Compass
def registered(app) def registered(app)
# Where to look for fonts # Where to look for fonts
app.set :fonts_dir, "fonts" app.set :fonts_dir, "fonts"
app.define_hook :compass_config
app.define_hook :after_compass_config app.define_hook :after_compass_config
app.extend ClassMethods
require "compass" require "compass"
# Susy grids # Susy grids
@ -84,16 +83,10 @@ module Middleman::CoreExtensions::Compass
end end
end end
run_hook :after_compass_config, ::Compass.configuration run_hook :compass_config, ::Compass.configuration
run_hook :after_compass_config
end end
end end
alias :included :registered alias :included :registered
end end
module ClassMethods
# Add a block/proc to be run after features have been setup
def compass_config(&block)
after_compass_config(&block)
end
end
end end

View file

@ -20,7 +20,6 @@ module Middleman::CoreExtensions::Data
data.remove_file(file) data.remove_file(file)
end end
end end
end end
alias :included :registered alias :included :registered
end end
@ -35,14 +34,11 @@ module Middleman::CoreExtensions::Data
def initialize(app) def initialize(app)
@app = app @app = app
@local_data = {} @local_data = {}
setup
end
def setup
data_path = File.join(@app.root, @app.data_dir) data_path = File.join(@app.root, @app.data_dir)
local_path = File.join(data_path, "*.{yaml,yml,json}") local_path = File.join(data_path, "*.{yaml,yml,json}")
Dir[local_path].each do |f| Dir[local_path].each do |f|
touch_file(f)#.sub(data_path, "")) touch_file(f)
end end
end end

View file

@ -65,7 +65,7 @@ module Middleman::CoreExtensions::Features
end end
# Load features before starting server # Load features before starting server
def new def new!
# Check for and evaluate local configuration # Check for and evaluate local configuration
local_config = File.join(self.root, "config.rb") local_config = File.join(self.root, "config.rb")
if File.exists? local_config if File.exists? local_config

View file

@ -6,42 +6,36 @@ module Middleman::CoreExtensions::FrontMatter
def registered(app) def registered(app)
app.extend ClassMethods app.extend ClassMethods
::Tilt::register RDiscountTemplate, 'markdown', 'mkd', 'md' app.file_changed do |file|
::Tilt::register RedcarpetTemplate, 'markdown', 'mkd', 'md' data.touch_file(file)
::Tilt::register MarukuTemplate, 'markdown', 'mkd', 'md' end
::Tilt::register KramdownTemplate, 'markdown', 'mkd', 'md'
app.set :markdown_engine_prefix, ::Middleman::CoreExtensions::FrontMatter
::Tilt::register RedClothTemplate, 'textile' app.file_deleted do |file|
::Tilt.prefer(RedClothTemplate) data.remove_file(file)
end
::Tilt::register ERBTemplate, 'erb', 'rhtml'
::Tilt.prefer(ERBTemplate)
::Tilt::register LiquidTemplate, 'liquid'
::Tilt.prefer(LiquidTemplate)
::Tilt::register SlimTemplate, 'slim'
::Tilt.prefer(SlimTemplate)
::Tilt::register HamlTemplate, 'haml'
::Tilt.prefer(HamlTemplate)
app.after_configuration do app.after_configuration do
app.before_processing(:front_matter, 0) do |result| app.before_processing(:front_matter, 0) do |result|
if result && Tilt.mappings.has_key?(result[1].to_s) if result && Tilt.mappings.has_key?(result[1].to_s)
extensionless_path, template_engine = result extensionless_path, template_engine = result
full_file_path = "#{extensionless_path}.#{template_engine}" full_file_path = "#{extensionless_path}.#{template_engine}"
system_path = File.join(settings.views, full_file_path)
data, content = app.parse_front_matter(File.read(system_path)) if app.frontmatter.has_data?(full_file_path)
result = app.frontmatter.data(full_file_path)
request['custom_options'] = {} data = result.first.dup
%w(layout layout_engine).each do |opt|
if data.has_key?(opt) request['custom_options'] = {}
request['custom_options'][opt.to_sym] = data.delete(opt) %w(layout layout_engine).each do |opt|
if data.has_key?(opt)
request['custom_options'][opt.to_sym] = data.delete(opt)
end
end end
app.settings.templates[extensionless_path] = [result[1], extensionless_path, 1]
else
data = {}
end end
# Forward remaining data to helpers # Forward remaining data to helpers
app.data_content("page", data) app.data_content("page", data)
end end
@ -51,7 +45,62 @@ module Middleman::CoreExtensions::FrontMatter
end end
end end
alias :included :registered alias :included :registered
end
module ClassMethods
def frontmatter
@frontmatter ||= FrontmatterData.new(self)
end
end
class FrontmatterData
def initialize(app)
@app = app
@source ||= File.expand_path(@app.views, @app.root)
@local_data = {}
views_dir = @app.views
views_dir = File.join(@app.root, @app.views) unless views_dir.include?(@app.root)
Dir[File.join(views_dir, "**/*")].each do |file|
next if file.match(/\/\./) ||
(file.match(/\/_/) && !file.match(/\/__/)) ||
File.directory?(file)
touch_file(file)
end
end
def has_data?(path)
@local_data.has_key?(path.to_s)
end
def touch_file(file)
content = File.read(file)
file = file.sub(@source, "")
result = parse_front_matter(content)
if result
@local_data[file] = result
end
end
def remove_file(file)
file = file.sub(@source, "")
if @local_data.has_key?(file)
@local_data.delete(file)
end
end
def data(path)
if @local_data.has_key?(path.to_s)
@local_data[path.to_s]
else
nil
end
end
private
def parse_front_matter(content) def parse_front_matter(content)
yaml_regex = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m yaml_regex = /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
if content =~ yaml_regex if content =~ yaml_regex
@ -59,61 +108,15 @@ module Middleman::CoreExtensions::FrontMatter
data = YAML.load($1) data = YAML.load($1)
rescue => e rescue => e
puts "YAML Exception: #{e.message}" puts "YAML Exception: #{e.message}"
return false
end end
content = content.split(yaml_regex).last content = content.split(yaml_regex).last
else
return false
end end
data ||= {}
[data, content] [data, content]
end end
end end
module ClassMethods
def parse_front_matter(content)
Middleman::CoreExtensions::FrontMatter.parse_front_matter(content)
end
end
module YamlAware
def prepare
@frontmatter, @data = Middleman::CoreExtensions::FrontMatter.parse_front_matter(@data)
super
end
end
class RDiscountTemplate < ::Tilt::RDiscountTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class MarukuTemplate < ::Tilt::MarukuTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class RedClothTemplate < ::Tilt::RedClothTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class KramdownTemplate < ::Tilt::KramdownTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class ERBTemplate < ::Tilt::ERBTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class ErubisTemplate < ::Tilt::ErubisTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class LiquidTemplate < ::Tilt::LiquidTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class HamlTemplate < ::Tilt::HamlTemplate
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
class SlimTemplate < ::Slim::Template
include Middleman::CoreExtensions::FrontMatter::YamlAware
end
end end

View file

@ -18,14 +18,15 @@ module Middleman::CoreExtensions::RackMap
# Creates a Rack::Builder instance with all the middleware set up and # Creates a Rack::Builder instance with all the middleware set up and
# an instance of this class as end point. # an instance of this class as end point.
def build(builder, *args, &bk) def build_new(inst=false)
builder = Rack::Builder.new
setup_default_middleware builder setup_default_middleware builder
setup_middleware builder setup_middleware builder
maps.each { |p,b| builder.map(p, &b) } maps.each { |p,b| builder.map(p, &b) }
app = self app = self
builder.map "/" do builder.map "/" do
run app.new!(*args, &bk) run (inst || app.new!)
end end
builder builder

View file

@ -45,19 +45,21 @@ module Middleman::CoreExtensions::Routing
def page(url, options={}, &block) def page(url, options={}, &block)
has_block = block_given? has_block = block_given?
options[:layout] = layout if options[:layout].nil? options[:layout] = layout if options[:layout].nil?
if options.has_key?(:proxy) if options.has_key?(:proxy)
reroute(url, options[:proxy]) reroute(url, options[:proxy])
if options.has_key?(:ignore) && options[:ignore] if options.has_key?(:ignore) && options[:ignore]
ignore(options[:proxy]) ignore(options[:proxy])
end end
options.delete(:proxy)
else else
if options.has_key?(:ignore) && options[:ignore] if options.has_key?(:ignore) && options[:ignore]
ignore(url) ignore(url)
end end
end end
paths_for_url(url).each do |p| paths_for_url(url).each do |p|
get(p) do get(p) do
if settings.sitemap.path_is_proxy?(url) if settings.sitemap.path_is_proxy?(url)

View file

@ -50,10 +50,6 @@ module Middleman::CoreExtensions::Sitemap
build_static_map build_static_map
end end
def setup?
@is_setup
end
# Check to see if we know about a specific path # Check to see if we know about a specific path
def path_exists?(path) def path_exists?(path)
path = path.sub(/^\//, "") path = path.sub(/^\//, "")

View file

@ -41,7 +41,9 @@ Gem::Specification.new do |s|
s.add_dependency("hooks", ["~> 0.2.0"]) s.add_dependency("hooks", ["~> 0.2.0"])
s.add_dependency("guard", ["~> 0.8.8"]) s.add_dependency("guard", ["~> 0.8.8"])
s.add_dependency("eventmachine", ["1.0.0.beta.4"]) s.add_dependency("rb-fsevent")
s.add_dependency("rb-inotify")
# s.add_dependency("eventmachine", ["1.0.0.beta.4"])
# s.add_dependency("middleman-livereload", ["~> 0.2.0"]) # s.add_dependency("middleman-livereload", ["~> 0.2.0"])
# Development and test # Development and test