mirror of
https://github.com/middleman/middleman.git
synced 2022-11-09 12:20:27 -05:00
rewrite and decouple
This commit is contained in:
parent
96e095215f
commit
4f11920bba
24 changed files with 522 additions and 327 deletions
7
Rakefile
7
Rakefile
|
@ -13,15 +13,10 @@ begin
|
||||||
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
||||||
gem.executables = %w(mm-init mm-build mm-server)
|
gem.executables = %w(mm-init mm-build mm-server)
|
||||||
gem.add_dependency("templater")
|
gem.add_dependency("templater")
|
||||||
gem.add_dependency("yui-compressor")
|
|
||||||
gem.add_dependency("sprockets")
|
gem.add_dependency("sprockets")
|
||||||
gem.add_dependency("sinatra")
|
gem.add_dependency("sinatra")
|
||||||
gem.add_dependency("foca-sinatra-content-for")
|
gem.add_dependency("foca-sinatra-content-for")
|
||||||
gem.add_dependency("brynary-rack-test")
|
gem.add_dependency("brynary-rack-test")
|
||||||
gem.add_dependency("markaby")
|
|
||||||
gem.add_dependency("sbfaulkner-sinatra-markaby")
|
|
||||||
gem.add_dependency("maruku")
|
|
||||||
gem.add_dependency("wbzyl-sinatra-maruku")
|
|
||||||
gem.add_dependency("haml", ">=2.1.0")
|
gem.add_dependency("haml", ">=2.1.0")
|
||||||
gem.add_dependency("chriseppstein-compass")
|
gem.add_dependency("chriseppstein-compass")
|
||||||
end
|
end
|
||||||
|
@ -30,7 +25,7 @@ begin
|
||||||
rubyforge.doc_task = "rdoc"
|
rubyforge.doc_task = "rdoc"
|
||||||
end
|
end
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'spec/rake/spectask'
|
require 'spec/rake/spectask'
|
||||||
|
|
48
bin/mm-build
48
bin/mm-build
|
@ -1,12 +1,11 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
# Require app
|
|
||||||
require 'templater'
|
require 'templater'
|
||||||
|
|
||||||
MIDDLEMAN_BUILDER = true
|
|
||||||
require 'middleman'
|
|
||||||
require 'rack-test'
|
require 'rack-test'
|
||||||
|
|
||||||
|
# Require app
|
||||||
|
require 'middleman/builder'
|
||||||
|
|
||||||
module Generators
|
module Generators
|
||||||
extend Templater::Manifold
|
extend Templater::Manifold
|
||||||
desc "Build a staticmatic site"
|
desc "Build a staticmatic site"
|
||||||
|
@ -69,50 +68,11 @@ module Generators
|
||||||
add :build, Builder
|
add :build, Builder
|
||||||
end
|
end
|
||||||
|
|
||||||
class BuildConfig
|
|
||||||
def self.render(source, destination)
|
|
||||||
renderer.render(source, destination)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.renderer
|
|
||||||
@@renderer ||= BuildRenderer
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.renderer=(val)
|
|
||||||
@@renderer = val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Monkey-patch to use a dynamic renderer
|
# Monkey-patch to use a dynamic renderer
|
||||||
class Templater::Actions::Template
|
class Templater::Actions::Template
|
||||||
def render
|
def render
|
||||||
BuildConfig.render(source, destination)
|
::Middleman::Builder.render(source, destination)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Default render through middleman
|
|
||||||
class BuildRenderer
|
|
||||||
def self.render(source, destination)
|
|
||||||
request_path = destination.gsub(File.join(Dir.pwd, 'build'), "")
|
|
||||||
browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman))
|
|
||||||
browser.get(request_path)
|
|
||||||
browser.last_response.body
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SprocketsRenderer < BuildRenderer
|
|
||||||
def self.render(source, destination)
|
|
||||||
if File.extname(source) == '.js'
|
|
||||||
secretary = Sprockets::Secretary.new( :asset_root => "public",
|
|
||||||
:load_path => ["public/assets/javascripts/**/*.js"],
|
|
||||||
:source_files => [source] )
|
|
||||||
compressor = YUI::JavaScriptCompressor.new(:munge => true)
|
|
||||||
compressor.compress(secretary.concatenation.to_s)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
BuildConfig.renderer = SprocketsRenderer
|
|
||||||
|
|
||||||
Generators.run_cli(Dir.pwd, 'mm-build', 1, %w(build --force).concat(ARGV))
|
Generators.run_cli(Dir.pwd, 'mm-build', 1, %w(build --force).concat(ARGV))
|
|
@ -9,6 +9,9 @@ module Generators
|
||||||
desc "Creates a new staticmatic scaffold."
|
desc "Creates a new staticmatic scaffold."
|
||||||
first_argument :location, :required => true, :desc => "Project location"
|
first_argument :location, :required => true, :desc => "Project location"
|
||||||
|
|
||||||
|
# css_dir
|
||||||
|
# images_dir
|
||||||
|
|
||||||
def destination_root
|
def destination_root
|
||||||
File.expand_path(location)
|
File.expand_path(location)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
require File.join(File.dirname(__FILE__), '..', 'lib', 'middleman')
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'middleman')
|
||||||
|
|
||||||
# Start Middleman
|
# Start Middleman
|
||||||
Middleman.set :server, %w[thin webrick]
|
Middleman::Base.set({ :server => %w[thin webrick],
|
||||||
Middleman.run!(:root => Dir.pwd)
|
:root => Dir.pwd })
|
||||||
|
Middleman::Base.init!
|
3
deps.rip
3
deps.rip
|
@ -1,10 +1,7 @@
|
||||||
git://github.com/jnicklas/templater.git
|
git://github.com/jnicklas/templater.git
|
||||||
git://github.com/sstephenson/ruby-yui-compressor.git
|
|
||||||
git://github.com/sstephenson/sprockets.git
|
git://github.com/sstephenson/sprockets.git
|
||||||
git://github.com/sinatra/sinatra.git
|
git://github.com/sinatra/sinatra.git
|
||||||
git://github.com/nex3/haml.git
|
git://github.com/nex3/haml.git
|
||||||
git://github.com/chriseppstein/compass.git
|
git://github.com/chriseppstein/compass.git
|
||||||
git://github.com/foca/sinatra-content-for.git
|
git://github.com/foca/sinatra-content-for.git
|
||||||
git://github.com/brynary/rack-test.git
|
git://github.com/brynary/rack-test.git
|
||||||
git://github.com/sbfaulkner/sinatra-markaby.git
|
|
||||||
git://github.com/wbzyl/sinatra-maruku.git
|
|
138
lib/middleman.rb
138
lib/middleman.rb
|
@ -1,136 +1,4 @@
|
||||||
require 'haml'
|
libdir = File.dirname(__FILE__)
|
||||||
require 'compass' #must be loaded before sinatra
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
||||||
require 'sinatra/base'
|
|
||||||
|
|
||||||
require 'sprockets'
|
require 'middleman/base'
|
||||||
# Sprockets ruby 1.9 hack
|
|
||||||
require 'middleman/sprockets+ruby19'
|
|
||||||
|
|
||||||
require "yui/compressor"
|
|
||||||
|
|
||||||
# Include content_for support
|
|
||||||
require 'sinatra-content-for'
|
|
||||||
|
|
||||||
class Middleman < Sinatra::Base
|
|
||||||
set :app_file, __FILE__
|
|
||||||
set :static, true
|
|
||||||
set :root, Dir.pwd
|
|
||||||
set :environment, defined?(MIDDLEMAN_BUILDER) ? :build : :development
|
|
||||||
set :default_ext, 'html'
|
|
||||||
set :supported_formats, %w(haml erb builder)
|
|
||||||
|
|
||||||
helpers Sinatra::ContentFor
|
|
||||||
|
|
||||||
def self.run!(options={}, &block)
|
|
||||||
set options
|
|
||||||
handler = detect_rack_handler
|
|
||||||
handler_name = handler.name.gsub(/.*::/, '')
|
|
||||||
puts "== The Middleman is standing watch on port #{port}"
|
|
||||||
handler.run self, :Host => host, :Port => port do |server|
|
|
||||||
trap(:INT) do
|
|
||||||
## Use thins' hard #stop! if available, otherwise just #stop
|
|
||||||
server.respond_to?(:stop!) ? server.stop! : server.stop
|
|
||||||
puts "\n== The Middleman has ended his patrol"
|
|
||||||
end
|
|
||||||
|
|
||||||
if block_given?
|
|
||||||
block.call
|
|
||||||
## Use thins' hard #stop! if available, otherwise just #stop
|
|
||||||
server.respond_to?(:stop!) ? server.stop! : server.stop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Errno::EADDRINUSE => e
|
|
||||||
puts "== The Middleman is already standing watch on port #{port}!"
|
|
||||||
end
|
|
||||||
|
|
||||||
configure do
|
|
||||||
Compass.configuration do |config|
|
|
||||||
config.project_path = Dir.pwd
|
|
||||||
config.sass_dir = File.join(File.basename(self.views), "stylesheets")
|
|
||||||
config.output_style = :nested
|
|
||||||
config.css_dir = File.join(File.basename(self.public), "stylesheets")
|
|
||||||
config.images_dir = File.join(File.basename(self.public), "images")
|
|
||||||
config.http_images_path = "/images"
|
|
||||||
config.http_stylesheets_path = "/stylesheets"
|
|
||||||
config.add_import_path(config.sass_dir)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# include helpers
|
|
||||||
class_eval File.read(File.join(File.dirname(__FILE__), 'middleman', 'helpers.rb'))
|
|
||||||
|
|
||||||
# Check for local config
|
|
||||||
local_config = File.join(self.root, "init.rb")
|
|
||||||
if File.exists? local_config
|
|
||||||
puts "== Local config at: #{local_config}"
|
|
||||||
class_eval File.read(local_config)
|
|
||||||
end
|
|
||||||
|
|
||||||
configure do
|
|
||||||
Compass.configure_sass_plugin!
|
|
||||||
end
|
|
||||||
|
|
||||||
configure :build do
|
|
||||||
Compass.configuration do |config|
|
|
||||||
config.output_style = :compressed
|
|
||||||
end
|
|
||||||
|
|
||||||
module Minified
|
|
||||||
module Javascript
|
|
||||||
include ::Haml::Filters::Base
|
|
||||||
def render_with_options(text, options)
|
|
||||||
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
|
||||||
data = compressor.compress(text)
|
|
||||||
<<END
|
|
||||||
<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script>
|
|
||||||
END
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# CSS files
|
|
||||||
get %r{/(.*).css} do |path|
|
|
||||||
content_type 'text/css', :charset => 'utf-8'
|
|
||||||
begin
|
|
||||||
static_version = File.join(Dir.pwd, 'public') + request.path_info
|
|
||||||
send_file(static_version) if File.exists? static_version
|
|
||||||
|
|
||||||
location_of_sass_file = defined?(MIDDLEMAN_BUILDER) ? "build" : "views"
|
|
||||||
css_filename = File.join(Dir.pwd, location_of_sass_file) + request.path_info
|
|
||||||
sass(path.to_sym, Compass.sass_engine_options.merge({ :css_filename => css_filename }))
|
|
||||||
rescue Exception => e
|
|
||||||
sass_exception_string(e)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# All other files
|
|
||||||
get /(.*)/ do |path|
|
|
||||||
path << "index.#{options.default_ext}" if path.match(%r{/$})
|
|
||||||
path.gsub!(%r{^/}, '')
|
|
||||||
path_without_ext = path.gsub(File.extname(path), '')
|
|
||||||
|
|
||||||
result = nil
|
|
||||||
begin
|
|
||||||
options.supported_formats.detect do |renderer|
|
|
||||||
if File.exists?(File.join(options.views, "#{path}.#{renderer}"))
|
|
||||||
result = send(renderer.to_sym, path.to_sym)
|
|
||||||
elsif File.exists?(File.join(options.views, "#{path_without_ext}.#{renderer}"))
|
|
||||||
result = send(renderer.to_sym, path_without_ext.to_sym)
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Haml::Error => e
|
|
||||||
result = "Haml Error: #{e}"
|
|
||||||
result << "<pre>Backtrace: #{e.backtrace.join("\n")}</pre>"
|
|
||||||
end
|
|
||||||
|
|
||||||
result || pass
|
|
||||||
end
|
|
||||||
|
|
||||||
get %r{/(.*\.xml)} do |path|
|
|
||||||
content_type 'text/xml', :charset => 'utf-8'
|
|
||||||
haml(path.to_sym, :layout => false)
|
|
||||||
end
|
|
||||||
end
|
|
118
lib/middleman/base.rb
Normal file
118
lib/middleman/base.rb
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
||||||
|
require 'haml'
|
||||||
|
require 'sinatra/base'
|
||||||
|
require 'middleman/helpers'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
class Base < Sinatra::Base
|
||||||
|
set :app_file, __FILE__
|
||||||
|
set :root, Dir.pwd
|
||||||
|
set :environment, :development
|
||||||
|
set :index_file, 'index.html'
|
||||||
|
set :css_dir, "stylesheets"
|
||||||
|
set :images_dir, "images"
|
||||||
|
|
||||||
|
enable :compass
|
||||||
|
enable :content_for
|
||||||
|
enable :sprockets
|
||||||
|
#enable :slickmap
|
||||||
|
disable :cache_buster
|
||||||
|
disable :minify_css
|
||||||
|
disable :minify_javascript
|
||||||
|
disable :relative_assets
|
||||||
|
disable :markaby
|
||||||
|
disable :maruku
|
||||||
|
|
||||||
|
# include helpers
|
||||||
|
helpers Middleman::Helpers
|
||||||
|
|
||||||
|
configure :build do
|
||||||
|
enable :minify_css
|
||||||
|
enable :minify_javascript
|
||||||
|
enable :cache_buster
|
||||||
|
disable :slickmap
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_exists?(path, renderer=nil)
|
||||||
|
template_path = path.dup
|
||||||
|
template_path << ".#{renderer}" if renderer
|
||||||
|
File.exists? File.join(options.views, template_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Base case renderer (do nothing), Should be over-ridden
|
||||||
|
module StaticRender
|
||||||
|
def render_path(path)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
include StaticRender
|
||||||
|
|
||||||
|
# All other files
|
||||||
|
disable :static
|
||||||
|
not_found do
|
||||||
|
path = request.path
|
||||||
|
path << options.index_file if path.match(%r{/$})
|
||||||
|
path.gsub!(%r{^/}, '')
|
||||||
|
|
||||||
|
if content = render_path(path)
|
||||||
|
content_type media_type(File.extname(path)), :charset => 'utf-8'
|
||||||
|
status 200
|
||||||
|
content
|
||||||
|
else
|
||||||
|
# Otherwise, send the static file
|
||||||
|
path = File.join(options.public, request.path)
|
||||||
|
if File.exists?(path)
|
||||||
|
status 200
|
||||||
|
send_file(path)
|
||||||
|
else
|
||||||
|
status 404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.run!(options={}, &block)
|
||||||
|
set options
|
||||||
|
handler = detect_rack_handler
|
||||||
|
handler_name = handler.name.gsub(/.*::/, '')
|
||||||
|
puts "== The Middleman is standing watch on port #{port}"
|
||||||
|
handler.run self, :Host => host, :Port => port do |server|
|
||||||
|
trap(:INT) do
|
||||||
|
## Use thins' hard #stop! if available, otherwise just #stop
|
||||||
|
server.respond_to?(:stop!) ? server.stop! : server.stop
|
||||||
|
puts "\n== The Middleman has ended his patrol"
|
||||||
|
end
|
||||||
|
|
||||||
|
if block_given?
|
||||||
|
block.call
|
||||||
|
## Use thins' hard #stop! if available, otherwise just #stop
|
||||||
|
server.respond_to?(:stop!) ? server.stop! : server.stop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Errno::EADDRINUSE => e
|
||||||
|
puts "== The Middleman is already standing watch on port #{port}!"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.init!
|
||||||
|
# Check for local config
|
||||||
|
local_config = File.join(self.root, "init.rb")
|
||||||
|
if File.exists? local_config
|
||||||
|
puts "== Local config at: #{local_config}"
|
||||||
|
class_eval File.read(local_config)
|
||||||
|
end
|
||||||
|
|
||||||
|
require "middleman/features/haml"
|
||||||
|
|
||||||
|
# loop over enabled feature
|
||||||
|
features_path = File.expand_path("features/*.rb", File.dirname(__FILE__))
|
||||||
|
Dir[features_path].each do |f|
|
||||||
|
feature_name = File.basename(f, '.rb')
|
||||||
|
option_name = :"#{feature_name}?"
|
||||||
|
if respond_to?(option_name) && send(option_name) === true
|
||||||
|
require "middleman/features/#{feature_name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
run!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
lib/middleman/builder.rb
Normal file
14
lib/middleman/builder.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require 'middleman'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
class Builder
|
||||||
|
def self.render_file(source, destination)
|
||||||
|
# Middleman.set :environment, :build
|
||||||
|
|
||||||
|
request_path = destination.gsub(File.join(Dir.pwd, 'build'), "")
|
||||||
|
browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman))
|
||||||
|
browser.get(request_path)
|
||||||
|
browser.last_response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
lib/middleman/features/cache_buster.rb
Normal file
9
lib/middleman/features/cache_buster.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
# def cache_buster
|
||||||
|
# if File.readable?(real_path)
|
||||||
|
# File.mtime(real_path).strftime("%s")
|
||||||
|
# else
|
||||||
|
# $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
|
||||||
|
# end
|
||||||
|
# end
|
26
lib/middleman/features/compass.rb
Normal file
26
lib/middleman/features/compass.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'compass'
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
configure do
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
config.project_path = Dir.pwd
|
||||||
|
config.sass_dir = File.join(File.basename(self.views), self.css_dir)
|
||||||
|
config.output_style = minify_css ? :compressed : :nested
|
||||||
|
config.css_dir = File.join(File.basename(self.public), self.css_dir)
|
||||||
|
config.images_dir = File.join(File.basename(self.public), self.images_dir)
|
||||||
|
# File.expand_path(self.images_dir, self.public)
|
||||||
|
|
||||||
|
if !cache_buster?
|
||||||
|
config.asset_cache_buster do
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config.http_images_path = "/#{self.images_dir}"
|
||||||
|
config.http_stylesheets_path = "/#{self.css_dir}"
|
||||||
|
config.add_import_path(config.sass_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
::Compass.configure_sass_plugin!
|
||||||
|
end
|
||||||
|
end
|
9
lib/middleman/features/content_for.rb
Normal file
9
lib/middleman/features/content_for.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
begin
|
||||||
|
require 'sinatra/content_for'
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
helpers Sinatra::ContentFor
|
||||||
|
end
|
||||||
|
rescue LoadError
|
||||||
|
puts "Sinatra::ContentFor not available. Install it with: gem install sinatra-content-for"
|
||||||
|
end
|
2
lib/middleman/features/growl.rb
Normal file
2
lib/middleman/features/growl.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Errors to growl
|
||||||
|
# Build complete to growl
|
120
lib/middleman/features/haml.rb
Normal file
120
lib/middleman/features/haml.rb
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
module Middleman
|
||||||
|
module Haml
|
||||||
|
def render_path(path)
|
||||||
|
if template_exists?(path, :haml)
|
||||||
|
result = nil
|
||||||
|
begin
|
||||||
|
result = haml(path.to_sym, :layout => File.extname(path) != ".xml")
|
||||||
|
rescue ::Haml::Error => e
|
||||||
|
result = "Haml Error: #{e}"
|
||||||
|
result << "<pre>Backtrace: #{e.backtrace.join("\n")}</pre>"
|
||||||
|
end
|
||||||
|
result
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# module Helpers
|
||||||
|
# def haml_partial(name, options = {})
|
||||||
|
# item_name = name.to_sym
|
||||||
|
# counter_name = "#{name}_counter".to_sym
|
||||||
|
# if collection = options.delete(:collection)
|
||||||
|
# collection.enum_for(:each_with_index).collect do |item,index|
|
||||||
|
# haml_partial name, options.merge(:locals => {item_name => item, counter_name => index+1})
|
||||||
|
# end.join
|
||||||
|
# elsif object = options.delete(:object)
|
||||||
|
# haml_partial name, options.merge(:locals => {item_name => object, counter_name => nil})
|
||||||
|
# else
|
||||||
|
# haml "_#{name}".to_sym, options.merge(:layout => false)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# module Table
|
||||||
|
# include ::Haml::Filters::Base
|
||||||
|
#
|
||||||
|
# def render(text)
|
||||||
|
# output = '<div class="table"><table cellspacing="0" cellpadding="0">'
|
||||||
|
# line_num = 0
|
||||||
|
# text.each_line do |line|
|
||||||
|
# line_num += 1
|
||||||
|
# next if line.strip.empty?
|
||||||
|
# output << %Q{<tr class="#{(line_num % 2 == 0) ? "even" : "odd" }#{(line_num == 1) ? " first" : "" }">}
|
||||||
|
#
|
||||||
|
# columns = line.split("|").map { |p| p.strip }
|
||||||
|
# columns.each_with_index do |col, i|
|
||||||
|
# output << %Q{<td class="col#{i+1}">#{col}</td>}
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# output << "</tr>"
|
||||||
|
# end
|
||||||
|
# output + "</table></div>"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
module Sass
|
||||||
|
def render_path(path)
|
||||||
|
path = path.dup.gsub('.css', '')
|
||||||
|
if template_exists?(path, :sass)
|
||||||
|
begin
|
||||||
|
static_version = options.public + request.path_info
|
||||||
|
send_file(static_version) if File.exists? static_version
|
||||||
|
|
||||||
|
location_of_sass_file = defined?(MIDDLEMAN_BUILDER) ? "build" : "views"
|
||||||
|
css_filename = File.join(Dir.pwd, location_of_sass_file) + request.path_info
|
||||||
|
sass(path.to_sym, Compass.sass_engine_options.merge({ :css_filename => css_filename }))
|
||||||
|
rescue Exception => e
|
||||||
|
sass_exception_string(e)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle Sass errors
|
||||||
|
def sass_exception_string(e)
|
||||||
|
e_string = "#{e.class}: #{e.message}"
|
||||||
|
|
||||||
|
if e.is_a? ::Sass::SyntaxError
|
||||||
|
e_string << "\non line #{e.sass_line}"
|
||||||
|
|
||||||
|
if e.sass_filename
|
||||||
|
e_string << " of #{e.sass_filename}"
|
||||||
|
|
||||||
|
if File.exists?(e.sass_filename)
|
||||||
|
e_string << "\n\n"
|
||||||
|
|
||||||
|
min = [e.sass_line - 5, 0].max
|
||||||
|
begin
|
||||||
|
File.read(e.sass_filename).rstrip.split("\n")[
|
||||||
|
min .. e.sass_line + 5
|
||||||
|
].each_with_index do |line, i|
|
||||||
|
e_string << "#{min + i + 1}: #{line}\n"
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
e_string << "Couldn't read sass file: #{e.sass_filename}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
<<END
|
||||||
|
/*
|
||||||
|
#{e_string}
|
||||||
|
|
||||||
|
Backtrace:\n#{e.backtrace.join("\n")}
|
||||||
|
*/
|
||||||
|
body:before {
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monospace;
|
||||||
|
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
||||||
|
END
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
include Middleman::Haml
|
||||||
|
include Middleman::Sass
|
||||||
|
end
|
39
lib/middleman/features/markaby.rb
Normal file
39
lib/middleman/features/markaby.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
begin
|
||||||
|
require 'markaby'
|
||||||
|
rescue LoadError
|
||||||
|
puts "Markaby not available. Install it with: gem install markaby"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Markaby
|
||||||
|
def render_path(path)
|
||||||
|
if template_exists?(path, :mab)
|
||||||
|
markaby path.to_sym
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def markaby(template=nil, options={}, locals = {}, &block)
|
||||||
|
options, template = template, nil if template.is_a?(Hash)
|
||||||
|
template = lambda { block } if template.nil?
|
||||||
|
render :mab, template, options, locals
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def render_mab(template, data, options, locals, &block)
|
||||||
|
filename = options.delete(:filename) || '<MARKABY>'
|
||||||
|
line = options.delete(:line) || 1
|
||||||
|
mab = ::Markaby::Builder.new(locals)
|
||||||
|
if data.respond_to?(:to_str)
|
||||||
|
eval(data.to_str, binding, filename, line)
|
||||||
|
elsif data.kind_of?(Proc)
|
||||||
|
data.call(mab)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
include Middlman::Markaby
|
||||||
|
end
|
||||||
|
end
|
38
lib/middleman/features/maruku.rb
Normal file
38
lib/middleman/features/maruku.rb
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
begin
|
||||||
|
require 'maruku'
|
||||||
|
rescue LoadError
|
||||||
|
puts "Maruku not available. Install it with: gem install maruku"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Maruku
|
||||||
|
def render_path(path)
|
||||||
|
if template_exists?(path, :maruku)
|
||||||
|
maruku path.to_sym
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def maruku(template, options={}, locals={})
|
||||||
|
render :maruku, template, options, locals
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def render_maruku(data, options, locals, &block)
|
||||||
|
maruku_src = render_erb(data, options, locals, &block)
|
||||||
|
instance = ::Maruku.new(maruku_src, options)
|
||||||
|
if block_given?
|
||||||
|
# render layout
|
||||||
|
instance.to_html_document
|
||||||
|
else
|
||||||
|
# render template
|
||||||
|
instance.to_html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
include Middlman::Maruku
|
||||||
|
end
|
||||||
|
end
|
2
lib/middleman/features/minify_css.rb
Normal file
2
lib/middleman/features/minify_css.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Otherwise use YUI
|
||||||
|
# Fine a way to minify inline/css
|
31
lib/middleman/features/minify_javascript.rb
Normal file
31
lib/middleman/features/minify_javascript.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
require "yui/compressor"
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Minified
|
||||||
|
module Javascript
|
||||||
|
include ::Haml::Filters::Base
|
||||||
|
def render_with_options(text, options)
|
||||||
|
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
||||||
|
data = compressor.compress(text)
|
||||||
|
<<END
|
||||||
|
<script type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}>#{data.chomp}</script>
|
||||||
|
END
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Compressor
|
||||||
|
def render_path(path)
|
||||||
|
if template_exists?(path, :js)
|
||||||
|
compressor = YUI::JavaScriptCompressor.new(:munge => true)
|
||||||
|
compressor.compress(super)
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
include Middleman::Compressor
|
||||||
|
end
|
||||||
|
end
|
20
lib/middleman/features/relative_assets.rb
Normal file
20
lib/middleman/features/relative_assets.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
# config.relative_assets = true
|
||||||
|
|
||||||
|
def asset_url(path)
|
||||||
|
if path.include?("://")
|
||||||
|
path
|
||||||
|
else
|
||||||
|
request_path = request.path_info.dup
|
||||||
|
request_path << "index.html" if path.match(%r{/$})
|
||||||
|
request_path.gsub!(%r{^/}, '')
|
||||||
|
parts = request_path.split('/')
|
||||||
|
|
||||||
|
if parts.length > 1
|
||||||
|
"../" * (parts.length - 1) + path
|
||||||
|
else
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
5
lib/middleman/features/slickmap.rb
Normal file
5
lib/middleman/features/slickmap.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'slickmap'
|
||||||
|
|
||||||
|
get '/sitemap.html' do
|
||||||
|
haml :sitemap, :layout => false
|
||||||
|
end
|
25
lib/middleman/features/sprockets.rb
Normal file
25
lib/middleman/features/sprockets.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
begin
|
||||||
|
require 'sprockets'
|
||||||
|
require 'middleman/features/sprockets+ruby19' # Sprockets ruby 1.9 duckpunch
|
||||||
|
rescue LoadError
|
||||||
|
puts "Sprockets not available. Install it with: gem install sprockets"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Sprockets
|
||||||
|
def render_path(path)
|
||||||
|
source = File.join(options.public, path)
|
||||||
|
if File.extname(path) == '.js' && File.exists?(source)
|
||||||
|
secretary = ::Sprockets::Secretary.new( :asset_root => options.public,
|
||||||
|
:source_files => [source] )
|
||||||
|
secretary.concatenation.to_s
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
include Middleman::Sprockets
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,139 +1,60 @@
|
||||||
module Table
|
module Middleman
|
||||||
include Haml::Filters::Base
|
module Helpers
|
||||||
|
def find_and_include_related_css_file
|
||||||
|
path = request.path_info.dup
|
||||||
|
path << "index.html" if path.match(%r{/$})
|
||||||
|
path.gsub!(%r{^/}, '')
|
||||||
|
path.gsub!(File.extname(path), '')
|
||||||
|
path.gsub!('/', '-')
|
||||||
|
|
||||||
def render(text)
|
sass_file = File.join(File.basename(self.class.views), "stylesheets", "#{path}.sass")
|
||||||
output = '<div class="table"><table cellspacing="0" cellpadding="0">'
|
if File.exists? sass_file
|
||||||
line_num = 0
|
stylesheet_link_tag "stylesheets/#{path}.css"
|
||||||
text.each_line do |line|
|
|
||||||
line_num += 1
|
|
||||||
next if line.strip.empty?
|
|
||||||
output << %Q{<tr class="#{(line_num % 2 == 0) ? "even" : "odd" }#{(line_num == 1) ? " first" : "" }">}
|
|
||||||
|
|
||||||
columns = line.split("|").map { |p| p.strip }
|
|
||||||
columns.each_with_index do |col, i|
|
|
||||||
output << %Q{<td class="col#{i+1}">#{col}</td>}
|
|
||||||
end
|
|
||||||
|
|
||||||
output << "</tr>"
|
|
||||||
end
|
|
||||||
output + "</table></div>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_and_include_related_sass_file
|
|
||||||
path = request.path_info.dup
|
|
||||||
path << "index.html" if path.match(%r{/$})
|
|
||||||
path.gsub!(%r{^/}, '')
|
|
||||||
path.gsub!(File.extname(path), '')
|
|
||||||
path.gsub!('/', '-')
|
|
||||||
|
|
||||||
sass_file = File.join(File.basename(self.class.views), "stylesheets", "#{path}.sass")
|
|
||||||
if File.exists? sass_file
|
|
||||||
stylesheet_link_tag "stylesheets/#{path}.css"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_to(title, url="#", params={})
|
|
||||||
params.merge!(:href => url)
|
|
||||||
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
|
||||||
%Q{<a #{params}>#{title}</a>}
|
|
||||||
end
|
|
||||||
|
|
||||||
def page_classes(*additional)
|
|
||||||
path = request.path_info
|
|
||||||
path << "index.html" if path.match(%r{/$})
|
|
||||||
path.gsub!(%r{^/}, '')
|
|
||||||
|
|
||||||
classes = []
|
|
||||||
parts = path.split('.')[0].split('/')
|
|
||||||
parts.each_with_index { |path, i| classes << parts.first(i+1).join('_') }
|
|
||||||
|
|
||||||
classes << "index" if classes.empty?
|
|
||||||
classes += additional unless additional.empty?
|
|
||||||
classes.join(' ')
|
|
||||||
end
|
|
||||||
|
|
||||||
def haml_partial(name, options = {})
|
|
||||||
item_name = name.to_sym
|
|
||||||
counter_name = "#{name}_counter".to_sym
|
|
||||||
if collection = options.delete(:collection)
|
|
||||||
collection.enum_for(:each_with_index).collect do |item,index|
|
|
||||||
haml_partial name, options.merge(:locals => {item_name => item, counter_name => index+1})
|
|
||||||
end.join
|
|
||||||
elsif object = options.delete(:object)
|
|
||||||
haml_partial name, options.merge(:locals => {item_name => object, counter_name => nil})
|
|
||||||
else
|
|
||||||
haml "_#{name}".to_sym, options.merge(:layout => false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# def cache_buster
|
|
||||||
# if File.readable?(real_path)
|
|
||||||
# File.mtime(real_path).strftime("%s")
|
|
||||||
# else
|
|
||||||
# $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
def asset_url(path)
|
|
||||||
path.include?("://") ? path : "/#{path}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def image_tag(path, options={})
|
|
||||||
options[:alt] ||= ""
|
|
||||||
capture_haml do
|
|
||||||
haml_tag :img, options.merge(:src => asset_url(path))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def javascript_include_tag(path, options={})
|
|
||||||
capture_haml do
|
|
||||||
haml_tag :script, options.merge(:src => asset_url(path), :type => "text/javascript")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def stylesheet_link_tag(path, options={})
|
|
||||||
options[:rel] ||= "stylesheet"
|
|
||||||
capture_haml do
|
|
||||||
haml_tag :link, options.merge(:href => asset_url(path), :type => "text/css")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Handle Sass errors
|
|
||||||
def sass_exception_string(e)
|
|
||||||
e_string = "#{e.class}: #{e.message}"
|
|
||||||
|
|
||||||
if e.is_a? Sass::SyntaxError
|
|
||||||
e_string << "\non line #{e.sass_line}"
|
|
||||||
|
|
||||||
if e.sass_filename
|
|
||||||
e_string << " of #{e.sass_filename}"
|
|
||||||
|
|
||||||
if File.exists?(e.sass_filename)
|
|
||||||
e_string << "\n\n"
|
|
||||||
|
|
||||||
min = [e.sass_line - 5, 0].max
|
|
||||||
begin
|
|
||||||
File.read(e.sass_filename).rstrip.split("\n")[
|
|
||||||
min .. e.sass_line + 5
|
|
||||||
].each_with_index do |line, i|
|
|
||||||
e_string << "#{min + i + 1}: #{line}\n"
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
e_string << "Couldn't read sass file: #{e.sass_filename}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
<<END
|
|
||||||
/*
|
|
||||||
#{e_string}
|
|
||||||
|
|
||||||
Backtrace:\n#{e.backtrace.join("\n")}
|
def page_classes(*additional)
|
||||||
*/
|
path = request.path_info
|
||||||
body:before {
|
path << "index.html" if path.match(%r{/$})
|
||||||
white-space: pre;
|
path.gsub!(%r{^/}, '')
|
||||||
font-family: monospace;
|
|
||||||
content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
|
classes = []
|
||||||
END
|
parts = path.split('.')[0].split('/')
|
||||||
|
parts.each_with_index { |path, i| classes << parts.first(i+1).join('_') }
|
||||||
|
|
||||||
|
classes << "index" if classes.empty?
|
||||||
|
classes += additional unless additional.empty?
|
||||||
|
classes.join(' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to(title, url="#", params={})
|
||||||
|
params.merge!(:href => url)
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
%Q{<a #{params}>#{title}</a>}
|
||||||
|
end
|
||||||
|
|
||||||
|
def asset_url(path)
|
||||||
|
path.include?("://") ? path : "/#{path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def image_tag(path, options={})
|
||||||
|
options[:alt] ||= ""
|
||||||
|
params = options.merge(:src => asset_url(path))
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<img #{params} />"
|
||||||
|
end
|
||||||
|
|
||||||
|
def javascript_include_tag(path, options={})
|
||||||
|
params = options.merge(:src => asset_url(path), :type => "text/javascript")
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<script #{params}></script>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def stylesheet_link_tag(path, options={})
|
||||||
|
options[:rel] ||= "stylesheet"
|
||||||
|
params = options.merge(:href => asset_url(path), :type => "text/css")
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<link #{params} />"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,4 +0,0 @@
|
||||||
# Include markaby support
|
|
||||||
require 'sinatra-markaby'
|
|
||||||
Middleman.helpers Sinatra::Markaby
|
|
||||||
Middleman.supported_formats << "mab"
|
|
|
@ -1,4 +0,0 @@
|
||||||
# Include maruku support
|
|
||||||
require 'sinatra-maruku'
|
|
||||||
Middleman.helpers Sinatra::Maruku
|
|
||||||
Middleman.supported_formats << "maruku"
|
|
Loading…
Reference in a new issue