rewrite and decouple
This commit is contained in:
parent
96e095215f
commit
4f11920bba
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.executables = %w(mm-init mm-build mm-server)
|
||||
gem.add_dependency("templater")
|
||||
gem.add_dependency("yui-compressor")
|
||||
gem.add_dependency("sprockets")
|
||||
gem.add_dependency("sinatra")
|
||||
gem.add_dependency("foca-sinatra-content-for")
|
||||
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("chriseppstein-compass")
|
||||
end
|
||||
|
@ -30,7 +25,7 @@ begin
|
|||
rubyforge.doc_task = "rdoc"
|
||||
end
|
||||
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
|
||||
|
||||
require 'spec/rake/spectask'
|
||||
|
|
48
bin/mm-build
48
bin/mm-build
|
@ -1,12 +1,11 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# Require app
|
||||
require 'templater'
|
||||
|
||||
MIDDLEMAN_BUILDER = true
|
||||
require 'middleman'
|
||||
require 'rack-test'
|
||||
|
||||
# Require app
|
||||
require 'middleman/builder'
|
||||
|
||||
module Generators
|
||||
extend Templater::Manifold
|
||||
desc "Build a staticmatic site"
|
||||
|
@ -69,50 +68,11 @@ module Generators
|
|||
add :build, Builder
|
||||
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
|
||||
class Templater::Actions::Template
|
||||
def render
|
||||
BuildConfig.render(source, destination)
|
||||
::Middleman::Builder.render(source, destination)
|
||||
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))
|
|
@ -9,6 +9,9 @@ module Generators
|
|||
desc "Creates a new staticmatic scaffold."
|
||||
first_argument :location, :required => true, :desc => "Project location"
|
||||
|
||||
# css_dir
|
||||
# images_dir
|
||||
|
||||
def destination_root
|
||||
File.expand_path(location)
|
||||
end
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
require File.join(File.dirname(__FILE__), '..', 'lib', 'middleman')
|
||||
|
||||
# Start Middleman
|
||||
Middleman.set :server, %w[thin webrick]
|
||||
Middleman.run!(:root => Dir.pwd)
|
||||
Middleman::Base.set({ :server => %w[thin webrick],
|
||||
: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/sstephenson/ruby-yui-compressor.git
|
||||
git://github.com/sstephenson/sprockets.git
|
||||
git://github.com/sinatra/sinatra.git
|
||||
git://github.com/nex3/haml.git
|
||||
git://github.com/chriseppstein/compass.git
|
||||
git://github.com/foca/sinatra-content-for.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'
|
||||
require 'compass' #must be loaded before sinatra
|
||||
require 'sinatra/base'
|
||||
libdir = File.dirname(__FILE__)
|
||||
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
||||
|
||||
require 'sprockets'
|
||||
# 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
|
||||
require 'middleman/base'
|
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
|
||||
include Haml::Filters::Base
|
||||
module Middleman
|
||||
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)
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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 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
|
|
@ -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