parent
43ac01af5c
commit
cf39b2e2cb
49 changed files with 1372 additions and 0 deletions
20
LICENSE
Normal file
20
LICENSE
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (c) 2009 Thomas Reynolds
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
84
Rakefile
Normal file
84
Rakefile
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'jeweler'
|
||||||
|
Jeweler::Tasks.new do |gem|
|
||||||
|
gem.name = "middleman"
|
||||||
|
gem.summary = %Q{A static site generator utilizing Haml, Sass and providing YUI compression and cache busting}
|
||||||
|
gem.email = "tdreyno@gmail.com"
|
||||||
|
gem.homepage = "http://wiki.github.com/tdreyno/middleman"
|
||||||
|
gem.authors = ["Thomas Reynolds"]
|
||||||
|
gem.rubyforge_project = "middleman"
|
||||||
|
gem.executables = %w(mm-init mm-build mm-server)
|
||||||
|
gem.add_dependency("thin")
|
||||||
|
gem.add_dependency("shotgun")
|
||||||
|
gem.add_dependency("templater")
|
||||||
|
gem.add_dependency("sprockets")
|
||||||
|
gem.add_dependency("sinatra")
|
||||||
|
gem.add_dependency("sinatra-content-for")
|
||||||
|
gem.add_dependency("rack-test")
|
||||||
|
gem.add_dependency("yui-compressor")
|
||||||
|
gem.add_dependency("haml", ">=2.1.0")
|
||||||
|
gem.add_dependency("compass")
|
||||||
|
gem.add_development_dependency("rspec")
|
||||||
|
gem.add_development_dependency("sdoc")
|
||||||
|
end
|
||||||
|
|
||||||
|
Jeweler::RubyforgeTasks.new do |rubyforge|
|
||||||
|
rubyforge.doc_task = "rdoc"
|
||||||
|
end
|
||||||
|
|
||||||
|
Jeweler::GemcutterTasks.new
|
||||||
|
rescue LoadError
|
||||||
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'spec/rake/spectask'
|
||||||
|
Spec::Rake::SpecTask.new(:spec) do |spec|
|
||||||
|
spec.libs << 'lib' << 'spec'
|
||||||
|
spec.spec_files = FileList['spec/**/*_spec.rb']
|
||||||
|
end
|
||||||
|
|
||||||
|
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
||||||
|
spec.libs << 'lib' << 'spec'
|
||||||
|
spec.pattern = 'spec/**/*_spec.rb'
|
||||||
|
spec.rcov = true
|
||||||
|
end
|
||||||
|
|
||||||
|
task :spec => :check_dependencies
|
||||||
|
|
||||||
|
task :default => :spec
|
||||||
|
|
||||||
|
require 'rake/rdoctask'
|
||||||
|
require 'sdoc'
|
||||||
|
|
||||||
|
Rake::RDocTask.new do |rdoc|
|
||||||
|
if File.exist?('VERSION')
|
||||||
|
version = File.read('VERSION')
|
||||||
|
else
|
||||||
|
version = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
# rdoc.template = 'direct'
|
||||||
|
|
||||||
|
rdoc.rdoc_dir = 'rdoc'
|
||||||
|
rdoc.title = "middleman #{version}"
|
||||||
|
rdoc.rdoc_files.include('README*')
|
||||||
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||||
|
rdoc.rdoc_files.exclude('lib/middleman/features/sprockets+ruby19.rb')
|
||||||
|
rdoc.rdoc_files.exclude('lib/middleman/templater+dynamic_renderer.rb')
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Build and publish documentation using GitHub Pages."
|
||||||
|
task :pages do
|
||||||
|
if !`git status`.include?('nothing to commit')
|
||||||
|
abort "dirty index - not publishing!"
|
||||||
|
end
|
||||||
|
|
||||||
|
Rake::Task[:rerdoc].invoke
|
||||||
|
`git checkout gh-pages`
|
||||||
|
`ls -1 | grep -v rdoc | xargs rm -rf; mv rdoc/* .; rm -rf rdoc`
|
||||||
|
`git commit -a -m "update docs"; git push origin gh-pages`
|
||||||
|
`git checkout master`
|
||||||
|
end
|
1
VERSION
Normal file
1
VERSION
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0.9.20
|
12
bin/mm-build
Executable file
12
bin/mm-build
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
ENV['MM_ENV'] = "build"
|
||||||
|
|
||||||
|
# Require app
|
||||||
|
require File.join(File.dirname(__FILE__), "..", "lib", "middleman")
|
||||||
|
require 'middleman/builder'
|
||||||
|
|
||||||
|
#Middleman::Base.init!
|
||||||
|
Middleman::Builder.init!
|
||||||
|
|
||||||
|
Middleman::Generators.run_cli(Dir.pwd, 'mm-build', 1, %w(build --force).concat(ARGV))
|
36
bin/mm-init
Executable file
36
bin/mm-init
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
require 'templater'
|
||||||
|
|
||||||
|
module Generators
|
||||||
|
extend Templater::Manifold
|
||||||
|
desc "Generator for streamlining staticmatic"
|
||||||
|
|
||||||
|
class NewSite < Templater::Generator
|
||||||
|
desc "Creates a new middleman scaffold."
|
||||||
|
first_argument :location, :required => true, :desc => "Project location"
|
||||||
|
|
||||||
|
option :css_dir, :desc => 'The path to the css files'
|
||||||
|
option :js_dir, :desc => 'The path to the javascript files'
|
||||||
|
option :images_dir, :desc => 'The path to the image files'
|
||||||
|
|
||||||
|
def destination_root
|
||||||
|
File.expand_path(location)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.source_root
|
||||||
|
File.join(File.dirname(__FILE__), '..', 'lib', 'middleman', 'template')
|
||||||
|
end
|
||||||
|
|
||||||
|
template :init, "init.rb"
|
||||||
|
glob! :views
|
||||||
|
glob! :public
|
||||||
|
|
||||||
|
empty_directory :stylesheets, "public/stylesheets"#, File.join("public", css_dir)
|
||||||
|
empty_directory :javascripts, "public/javascripts"#, File.join("public", js_dir)
|
||||||
|
empty_directory :images, "public/images"#, File.join("public", images_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
add :setup, NewSite
|
||||||
|
end
|
||||||
|
|
||||||
|
Generators.run_cli(Dir.pwd, 'mm-init', 1, %w(setup).concat(ARGV))
|
43
bin/mm-server
Executable file
43
bin/mm-server
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
|
# Require Middleman
|
||||||
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'middleman')
|
||||||
|
|
||||||
|
env = ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development'
|
||||||
|
options = { :Port => 4567, :AccessLog => [] }
|
||||||
|
|
||||||
|
OptionParser.new { |opts|
|
||||||
|
opts.banner = "Usage: mm-server [rack options]"
|
||||||
|
opts.separator ""
|
||||||
|
opts.separator "Rack options:"
|
||||||
|
opts.on("-p", "--port PORT", "use PORT (default: 4567)") { |port|
|
||||||
|
options[:Port] = port
|
||||||
|
}
|
||||||
|
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
||||||
|
env = e
|
||||||
|
}
|
||||||
|
opts.on("--debug", "Debug mode") {
|
||||||
|
::Middleman::Base.set :logging, true
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.parse! ARGV
|
||||||
|
}
|
||||||
|
|
||||||
|
ENV['RACK_ENV'] = env
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
set :root, Dir.pwd
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'shotgun'
|
||||||
|
config = File.join(File.dirname(__FILE__), '..', 'lib', 'middleman', 'config.ru')
|
||||||
|
app = Shotgun.new(config, lambda { |inner_app| Middleman::Base })
|
||||||
|
|
||||||
|
require 'thin'
|
||||||
|
Thin::Logging.silent = true
|
||||||
|
|
||||||
|
Rack::Handler::Thin.run app, options do |inst|
|
||||||
|
puts "== The Middleman is standing watch on port #{options[:Port]}"
|
||||||
|
end
|
7
deps.rip
Normal file
7
deps.rip
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
git://github.com/jnicklas/templater.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
|
4
lib/middleman.rb
Normal file
4
lib/middleman.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
libdir = File.dirname(__FILE__)
|
||||||
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
||||||
|
|
||||||
|
require 'middleman/base'
|
137
lib/middleman/base.rb
Normal file
137
lib/middleman/base.rb
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
# Be nice to other library systems, like the wonderful Rip
|
||||||
|
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
||||||
|
|
||||||
|
# We're riding on Sinatra, so let's include it
|
||||||
|
require 'sinatra/base'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
class Base < Sinatra::Base
|
||||||
|
set :app_file, __FILE__
|
||||||
|
set :root, Dir.pwd
|
||||||
|
set :reload, false
|
||||||
|
set :logging, false
|
||||||
|
set :environment, ENV['MM_ENV'] || :development
|
||||||
|
set :supported_formats, %w(erb)
|
||||||
|
set :index_file, "index.html"
|
||||||
|
set :js_dir, "javascripts"
|
||||||
|
set :css_dir, "stylesheets"
|
||||||
|
set :images_dir, "images"
|
||||||
|
set :build_dir, "build"
|
||||||
|
set :http_prefix, "/"
|
||||||
|
|
||||||
|
use Rack::ConditionalGet if environment == :development
|
||||||
|
|
||||||
|
@@features = []
|
||||||
|
|
||||||
|
def self.enable(*opts)
|
||||||
|
@@features << opts
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.disable(*opts)
|
||||||
|
@@features -= opts
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
# Rack helper for adding mime-types during local preview
|
||||||
|
def self.mime(ext, type)
|
||||||
|
ext = ".#{ext}" unless ext.to_s[0] == ?.
|
||||||
|
::Rack::Mime::MIME_TYPES[ext.to_s] = type
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convenience function to discover if a tempalte exists for the requested renderer (haml, sass, etc)
|
||||||
|
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)
|
||||||
|
if template_exists?(path, :erb)
|
||||||
|
erb(path.to_sym)
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
include StaticRender
|
||||||
|
|
||||||
|
# This will match all requests not overridden in the project's init.rb
|
||||||
|
not_found do
|
||||||
|
# Normalize the path and add index if we're looking at a directory
|
||||||
|
path = request.path
|
||||||
|
path << options.index_file if path.match(%r{/$})
|
||||||
|
path.gsub!(%r{^/}, '')
|
||||||
|
|
||||||
|
# If the enabled renderers succeed, return the content, mime-type and an HTTP 200
|
||||||
|
if content = render_path(path)
|
||||||
|
content_type media_type(File.extname(path)), :charset => 'utf-8'
|
||||||
|
status 200
|
||||||
|
content
|
||||||
|
else
|
||||||
|
status 404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Haml is required & includes helpers
|
||||||
|
require "middleman/haml"
|
||||||
|
require "middleman/sass"
|
||||||
|
require 'sinatra/content_for'
|
||||||
|
require 'middleman/helpers'
|
||||||
|
require 'middleman/rack/static'
|
||||||
|
require 'middleman/rack/sprockets'
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
helpers Sinatra::ContentFor
|
||||||
|
helpers Middleman::Helpers
|
||||||
|
|
||||||
|
use Middleman::Rack::Static
|
||||||
|
use Middleman::Rack::Sprockets
|
||||||
|
|
||||||
|
enable :compass
|
||||||
|
require "middleman/features/compass"
|
||||||
|
@@features -= [:compass]
|
||||||
|
|
||||||
|
# Features disabled by default
|
||||||
|
disable :slickmap
|
||||||
|
disable :cache_buster
|
||||||
|
disable :minify_css
|
||||||
|
disable :minify_javascript
|
||||||
|
disable :relative_assets
|
||||||
|
disable :maruku
|
||||||
|
disable :smush_pngs
|
||||||
|
|
||||||
|
# Default build features
|
||||||
|
configure :build do
|
||||||
|
enable :minify_css
|
||||||
|
enable :minify_javascript
|
||||||
|
enable :cache_buster
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.new(*args, &bk)
|
||||||
|
# Check for and evaluate local configuration
|
||||||
|
local_config = File.join(self.root, "init.rb")
|
||||||
|
if File.exists? local_config
|
||||||
|
puts "== Reading: Local config" if logging?
|
||||||
|
class_eval File.read(local_config)
|
||||||
|
end
|
||||||
|
|
||||||
|
# loop over enabled feature
|
||||||
|
@@features.flatten.each do |feature_name|
|
||||||
|
next unless send(:"#{feature_name}?")
|
||||||
|
puts "== Enabling: #{feature_name.capitalize}" if logging?
|
||||||
|
require "middleman/features/#{feature_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
config.http_images_path = self.http_images_path rescue File.join(self.http_prefix, self.images_dir)
|
||||||
|
config.http_stylesheets_path = self.http_css_path rescue File.join(self.http_prefix, self.css_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
53
lib/middleman/builder.rb
Normal file
53
lib/middleman/builder.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
require 'templater'
|
||||||
|
require 'middleman/templater+dynamic_renderer.rb'
|
||||||
|
|
||||||
|
# Placeholder for any methods the builder needs to abstract to allow feature integration
|
||||||
|
module Middleman
|
||||||
|
class Builder < ::Templater::Generator
|
||||||
|
# Define source and desintation
|
||||||
|
def self.source_root; Dir.pwd; end
|
||||||
|
def destination_root; File.join(Dir.pwd, Middleman::Base.build_dir); end
|
||||||
|
|
||||||
|
# Override template to ask middleman for the correct extension to output
|
||||||
|
def self.template(name, *args, &block)
|
||||||
|
return if args[0].include?('layout')
|
||||||
|
|
||||||
|
args.first.split('/').each do |part|
|
||||||
|
return if part[0,1] == '_'
|
||||||
|
end
|
||||||
|
|
||||||
|
if (args[0] === args[1])
|
||||||
|
args[1] = args[0].gsub("#{File.basename(Middleman::Base.views)}/", "")
|
||||||
|
.gsub("#{File.basename(Middleman::Base.public)}/", "")
|
||||||
|
if File.extname(args[1]) != ".js"
|
||||||
|
args[1] = args[1].gsub!(File.extname(args[1]), "") if File.basename(args[1]).split('.').length > 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
super(name, *args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.file(name, *args, &block)
|
||||||
|
if (args[0] === args[1])
|
||||||
|
args[1] = args[0].gsub("#{File.basename(Middleman::Base.views)}/", "")
|
||||||
|
.gsub("#{File.basename(Middleman::Base.public)}/", "")
|
||||||
|
end
|
||||||
|
super(name, *args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.init!
|
||||||
|
glob! File.basename(Middleman::Base.public), []
|
||||||
|
glob! File.basename(Middleman::Base.views), Middleman::Base.supported_formats
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Generators
|
||||||
|
extend ::Templater::Manifold
|
||||||
|
desc "Build a static site"
|
||||||
|
|
||||||
|
add :build, ::Middleman::Builder
|
||||||
|
end
|
||||||
|
end
|
2
lib/middleman/config.ru
Normal file
2
lib/middleman/config.ru
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
require 'middleman'
|
||||||
|
run Middleman::Base
|
18
lib/middleman/features/cache_buster.rb
Normal file
18
lib/middleman/features/cache_buster.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class << Middleman::Base
|
||||||
|
alias_method :pre_cache_buster_asset_url, :asset_url
|
||||||
|
def asset_url(path, prefix="", request=nil)
|
||||||
|
http_path = pre_cache_buster_asset_url(path, prefix, request)
|
||||||
|
if http_path.include?("://") || !%w(.css .png .jpg .js .gif).include?(File.extname(http_path))
|
||||||
|
http_path
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
prefix = self.images_dir if prefix == self.http_images_path
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
|
||||||
|
real_path = File.join(self.environment == "build" ? self.build_dir : self.public, prefix, path)
|
||||||
|
http_path << "?" + File.mtime(real_path).strftime("%s") if File.readable?(real_path)
|
||||||
|
http_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
lib/middleman/features/compass.rb
Normal file
18
lib/middleman/features/compass.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class Middleman::Base
|
||||||
|
configure do
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
images_location = (self.environment == "build") ? self.build_dir : self.public
|
||||||
|
|
||||||
|
config.project_path = Dir.pwd
|
||||||
|
config.sass_dir = File.join(File.basename(self.views), self.css_dir)
|
||||||
|
config.output_style = :nested
|
||||||
|
config.css_dir = File.join(File.basename(images_location), self.css_dir)
|
||||||
|
config.images_dir = File.join(File.basename(images_location), self.images_dir)
|
||||||
|
# File.expand_path(self.images_dir, self.public)
|
||||||
|
|
||||||
|
config.add_import_path(config.sass_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
::Compass.configure_sass_plugin!
|
||||||
|
end
|
||||||
|
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
|
39
lib/middleman/features/maruku.rb
Normal file
39
lib/middleman/features/maruku.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
begin
|
||||||
|
require 'maruku'
|
||||||
|
rescue LoadError
|
||||||
|
puts "Maruku not available. Install it with: gem install maruku"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Maruku
|
||||||
|
def self.included(base)
|
||||||
|
base.supported_formats << "maruku"
|
||||||
|
base.set :maruku, {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_path(path)
|
||||||
|
if template_exists?(path, :maruku)
|
||||||
|
render :maruku, path.to_sym
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def render_maruku(template, data, options, locals, &block)
|
||||||
|
maruku_src = render_erb(template, 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 Middleman::Maruku
|
||||||
|
end
|
||||||
|
end
|
9
lib/middleman/features/minify_css.rb
Normal file
9
lib/middleman/features/minify_css.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Otherwise use YUI
|
||||||
|
# Fine a way to minify inline/css
|
||||||
|
class Middleman::Base
|
||||||
|
configure do
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
config.output_style = :compressed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
35
lib/middleman/features/minify_javascript.rb
Normal file
35
lib/middleman/features/minify_javascript.rb
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
class Builder
|
||||||
|
alias_method :pre_yui_after_run, :after_run
|
||||||
|
def after_run
|
||||||
|
pre_yui_after_run
|
||||||
|
|
||||||
|
compressor = ::YUI::JavaScriptCompressor.new(:munge => true)
|
||||||
|
Dir[File.join(Middleman::Base.build_dir, Middleman::Base.js_dir, "**", "*.js")].each do |path|
|
||||||
|
lines = IO.readlines(path)
|
||||||
|
if lines.length > 1
|
||||||
|
compressed_js = compressor.compress(lines.join($/))
|
||||||
|
File.open(path, 'w') { |f| f.write(compressed_js) }
|
||||||
|
say "<%= color('#{"[COMPRESSED]".rjust(12)}', :yellow) %> " + path.gsub(Middleman::Base.build_dir+"/", '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end if Middleman::Base.environment == "build"
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Base.supported_formats << "js"
|
30
lib/middleman/features/relative_assets.rb
Normal file
30
lib/middleman/features/relative_assets.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
::Compass.configuration do |config|
|
||||||
|
config.relative_assets = true
|
||||||
|
end
|
||||||
|
|
||||||
|
class << Middleman::Base
|
||||||
|
alias_method :pre_relative_asset_url, :asset_url
|
||||||
|
def asset_url(path, prefix="", request=nil)
|
||||||
|
begin
|
||||||
|
prefix = self.images_dir if prefix == self.http_images_path
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
|
||||||
|
path = pre_relative_asset_url(path, prefix, request)
|
||||||
|
if path.include?("://")
|
||||||
|
path
|
||||||
|
else
|
||||||
|
path = path[1,path.length-1] if path[0,1] == '/'
|
||||||
|
request_path = request.path_info.dup
|
||||||
|
request_path << self.class.index_file 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
|
119
lib/middleman/features/slickmap.rb
Normal file
119
lib/middleman/features/slickmap.rb
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
begin
|
||||||
|
require 'slickmap'
|
||||||
|
::Compass.configure_sass_plugin!
|
||||||
|
rescue LoadError
|
||||||
|
puts "Slickmap not available. Install it with: gem install compass-slickmap"
|
||||||
|
end
|
||||||
|
|
||||||
|
if Middleman::Base.environment == "build"
|
||||||
|
Middleman::Builder.template :slickmap, "sitemap.html", "sitemap.html"
|
||||||
|
end
|
||||||
|
|
||||||
|
Entry = Struct.new(:dir, :children)
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
def build_sitemap(&block)
|
||||||
|
@@utility = []
|
||||||
|
[recurse_sitemap(Middleman::Base.views, &block), @@utility]
|
||||||
|
end
|
||||||
|
|
||||||
|
def recurse_sitemap(path, &block)
|
||||||
|
bad_ext = path.split('.html')[1]
|
||||||
|
path = path.gsub(bad_ext, '') if bad_ext
|
||||||
|
entry = Entry.new(path, [])
|
||||||
|
|
||||||
|
#no "." or ".." dirs
|
||||||
|
Dir[File.join(path, "*")].each do |e|
|
||||||
|
next if !File.directory?(e) && !e.include?(".html")
|
||||||
|
if File.directory?(e)
|
||||||
|
entry.children << recurse_sitemap(e, &block)
|
||||||
|
elsif block_given?
|
||||||
|
how_to_handle = block.call(e)
|
||||||
|
if how_to_handle == :valid
|
||||||
|
entry.children << recurse_sitemap(e, &block)
|
||||||
|
elsif how_to_handle == :utility
|
||||||
|
bad_ext = e.split('.html')[1]
|
||||||
|
e = e.gsub(bad_ext, '') if bad_ext
|
||||||
|
@@utility << e.gsub(Middleman::Base.views + "/", '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
entry
|
||||||
|
end
|
||||||
|
|
||||||
|
helpers do
|
||||||
|
def sitemap_node(n, first=false)
|
||||||
|
if n.children.length < 1
|
||||||
|
if !first && File.extname(n.dir).length > 0
|
||||||
|
haml_tag :li do
|
||||||
|
path = n.dir.gsub(self.class.views, '')
|
||||||
|
haml_concat link_to(File.basename(path), path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
haml_tag(:li, :id => first ? "home" : nil) do
|
||||||
|
if first
|
||||||
|
haml_concat link_to("Homepage", "/" + self.class.index_file)
|
||||||
|
else
|
||||||
|
# we are a dir
|
||||||
|
index = n.children.find { |c| c.dir.include?(self.class.index_file) }
|
||||||
|
haml_concat link_to(index.dir.gsub(self.class.views + "/", '').gsub("/" + File.basename(index.dir), '').capitalize, index.dir.gsub(self.class.views, ''))
|
||||||
|
end
|
||||||
|
|
||||||
|
other_children = n.children.select { |c| !c.dir.include?(self.class.index_file) }
|
||||||
|
if other_children.length > 0
|
||||||
|
if first
|
||||||
|
other_children.each { |i| sitemap_node(i) }
|
||||||
|
else
|
||||||
|
haml_tag :ul do
|
||||||
|
other_children.each { |i| sitemap_node(i) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/sitemap.html' do
|
||||||
|
# Return :utility to put it util top menu. False to ignore
|
||||||
|
@tree, @utility = build_sitemap do |file_name|
|
||||||
|
:valid
|
||||||
|
end
|
||||||
|
haml :sitemap, :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
|
use_in_file_templates!
|
||||||
|
end
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
@@ sitemap
|
||||||
|
!!!
|
||||||
|
%html{ :xmlns => "http://www.w3.org/1999/xhtml" }
|
||||||
|
%head
|
||||||
|
%meta{ :content => "text/html; charset=utf-8", "http-equiv" => "Content-type" }
|
||||||
|
%title Sitemap
|
||||||
|
%style{ :type => "text/css" }
|
||||||
|
:sass
|
||||||
|
@import slickmap.sass
|
||||||
|
+slickmap
|
||||||
|
:javascript
|
||||||
|
window.onload = function() {
|
||||||
|
document.getElementById('primaryNav').className = "col" + document.querySelectorAll("#primaryNav > li:not(#home)").length;
|
||||||
|
};
|
||||||
|
|
||||||
|
%body
|
||||||
|
.logo
|
||||||
|
%h1= @project_name || "Sitemap"
|
||||||
|
- if @project_subtitle
|
||||||
|
%h2= @project_subtitle
|
||||||
|
|
||||||
|
- if @utility.length > 0
|
||||||
|
%ul#utilityNav
|
||||||
|
- @utility.each do |u|
|
||||||
|
%li= link_to u, u
|
||||||
|
|
||||||
|
%ul#primaryNav
|
||||||
|
- sitemap_node(@tree, true)
|
58
lib/middleman/features/smush_pngs.rb
Normal file
58
lib/middleman/features/smush_pngs.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
require 'json'
|
||||||
|
require 'open-uri'
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'httpclient'
|
||||||
|
rescue LoadError
|
||||||
|
puts "httpclient not available. Install it with: gem install httpclient"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module SmushPngs
|
||||||
|
def self.included(base)
|
||||||
|
base.supported_formats << "png"
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_path(file)
|
||||||
|
if File.extname(file) == ".png"
|
||||||
|
file = File.join(options.public, file)
|
||||||
|
optimized = optimized_image_data_for(file)
|
||||||
|
|
||||||
|
begin
|
||||||
|
raise "Error: got larger" if size(file) < optimized.size
|
||||||
|
raise "Error: empty file downloaded" if optimized.size < 20
|
||||||
|
|
||||||
|
optimized
|
||||||
|
rescue
|
||||||
|
File.read(file)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def size(file)
|
||||||
|
File.exist?(file) ? File.size(file) : 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def optimized_image_data_for(file)
|
||||||
|
# I leave these urls here, just in case it stops working again...
|
||||||
|
# url = "http://smush.it/ws.php" # original, redirects to somewhere else..
|
||||||
|
url = 'http://ws1.adq.ac4.yahoo.com/ysmush.it/ws.php'
|
||||||
|
# url = "http://developer.yahoo.com/yslow/smushit/ws.php" # official but does not work
|
||||||
|
# url = "http://smushit.com/ysmush.it/ws.php" # used at the new page but does not hande uploads
|
||||||
|
# url = "http://smushit.eperf.vip.ac4.yahoo.com/ysmush.it/ws.php" # used at the new page but does not hande uploads
|
||||||
|
response = HTTPClient.post url, { 'files[]' => File.new(file) }
|
||||||
|
response = JSON.parse(response.body.content)
|
||||||
|
raise "smush.it: #{response['error']}" if response['error']
|
||||||
|
image_url = response['dest']
|
||||||
|
raise "no dest path found" unless image_url
|
||||||
|
open(image_url) { |source| source.read() }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
include Middleman::SmushPngs
|
||||||
|
end
|
||||||
|
end
|
69
lib/middleman/haml.rb
Normal file
69
lib/middleman/haml.rb
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
require "haml"
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Haml
|
||||||
|
module Renderer
|
||||||
|
def self.included(base)
|
||||||
|
base.supported_formats << "haml"
|
||||||
|
base.helpers Middleman::Haml::Helpers
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Middleman::Base
|
||||||
|
include Middleman::Haml::Renderer
|
||||||
|
end
|
55
lib/middleman/helpers.rb
Normal file
55
lib/middleman/helpers.rb
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
module Middleman
|
||||||
|
class Base
|
||||||
|
def self.asset_url(path, prefix="", request=nil)
|
||||||
|
base_url = File.join(self.http_prefix, prefix)
|
||||||
|
path.include?("://") ? path : File.join(base_url, path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Helpers
|
||||||
|
def page_classes(*additional)
|
||||||
|
path = request.path_info
|
||||||
|
path << options.index_file 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 asset_url(path, prefix="")
|
||||||
|
self.class.asset_url(path, prefix, request)
|
||||||
|
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 image_tag(path, params={})
|
||||||
|
params[:alt] ||= ""
|
||||||
|
prefix = options.http_images_path rescue options.images_dir
|
||||||
|
params = params.merge(:src => asset_url(path, prefix))
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<img #{params} />"
|
||||||
|
end
|
||||||
|
|
||||||
|
def javascript_include_tag(path, params={})
|
||||||
|
params = params.merge(:src => asset_url(path, options.js_dir), :type => "text/javascript")
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<script #{params}></script>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def stylesheet_link_tag(path, params={})
|
||||||
|
params[:rel] ||= "stylesheet"
|
||||||
|
params = params.merge(:href => asset_url(path, options.css_dir), :type => "text/css")
|
||||||
|
params = params.map { |k,v| %Q{#{k}="#{v}"}}.join(' ')
|
||||||
|
"<link #{params} />"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
lib/middleman/rack/sprockets+ruby19.rb
Normal file
29
lib/middleman/rack/sprockets+ruby19.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module Sprockets
|
||||||
|
class SourceFile
|
||||||
|
def source_lines
|
||||||
|
@lines ||= begin
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
comments = []
|
||||||
|
File.open(pathname.absolute_location, 'rb') do |file|
|
||||||
|
file.each do |line|
|
||||||
|
lines << line = SourceLine.new(self, line, file.lineno)
|
||||||
|
|
||||||
|
if line.begins_pdoc_comment? || comments.any?
|
||||||
|
comments << line
|
||||||
|
end
|
||||||
|
|
||||||
|
if line.ends_multiline_comment?
|
||||||
|
if line.ends_pdoc_comment?
|
||||||
|
comments.each { |l| l.comment! }
|
||||||
|
end
|
||||||
|
comments.clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lines
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
lib/middleman/rack/sprockets.rb
Normal file
34
lib/middleman/rack/sprockets.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
begin
|
||||||
|
require 'sprockets'
|
||||||
|
require 'middleman/rack/sprockets+ruby19' # Sprockets ruby 1.9 duckpunch
|
||||||
|
rescue LoadError
|
||||||
|
puts "Sprockets not available. Install it with: gem install sprockets"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Rack
|
||||||
|
class Sprockets
|
||||||
|
def initialize(app, options={})
|
||||||
|
@app = app
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
path = env["PATH_INFO"]
|
||||||
|
source = File.join(Middleman::Base.views, path)
|
||||||
|
|
||||||
|
if path.match(/\.js$/) && File.exists?(source)
|
||||||
|
secretary = ::Sprockets::Secretary.new( :root => Middleman::Base.root,
|
||||||
|
:source_files => [ File.join("views", path) ],
|
||||||
|
:load_path => [ File.join("public", Middleman::Base.js_dir),
|
||||||
|
File.join("views", Middleman::Base.js_dir) ])
|
||||||
|
|
||||||
|
[200, { "Content-Type" => "text/javascript" }, [secretary.concatenation.to_s]]
|
||||||
|
else
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Middleman::Base.supported_formats << "js"
|
21
lib/middleman/rack/static.rb
Normal file
21
lib/middleman/rack/static.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
module Middleman
|
||||||
|
module Rack
|
||||||
|
class Static
|
||||||
|
def initialize(app, options={})
|
||||||
|
@app = app
|
||||||
|
root = Middleman::Base.public
|
||||||
|
@file_server = ::Rack::File.new(root)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
path = env["PATH_INFO"]
|
||||||
|
file_path = File.join(Middleman::Base.public, path)
|
||||||
|
if path.include?("favicon.ico") || (File.exists?(file_path) && !File.directory?(file_path))
|
||||||
|
@file_server.call(env)
|
||||||
|
else
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
70
lib/middleman/sass.rb
Normal file
70
lib/middleman/sass.rb
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
require "sass"
|
||||||
|
require 'compass'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
module Sass
|
||||||
|
def self.included(base)
|
||||||
|
base.supported_formats << "sass"
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_path(path)
|
||||||
|
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 = options.environment == "build" ? File.join(options.build_dir, options.css_dir) : "public"
|
||||||
|
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::Sass
|
||||||
|
end
|
22
lib/middleman/template/init.rbt
Normal file
22
lib/middleman/template/init.rbt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<% if css_dir %>set :css_dir, "<%= css_dir -%>"<% end %>
|
||||||
|
<% if js_dir %>set :js_dir, "<%= js_dir -%>"<% end %>
|
||||||
|
<% if images_dir %>set :images_dir, "<%= images_dir -%>"<% end %>
|
||||||
|
|
||||||
|
# Helpers
|
||||||
|
helpers do
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generic configuration
|
||||||
|
# enable :slickmap
|
||||||
|
|
||||||
|
# Build-specific configuration
|
||||||
|
configure :build do
|
||||||
|
# For example, change the Compass output style for deployment
|
||||||
|
# enable :minified_css
|
||||||
|
|
||||||
|
# Or use a different image path
|
||||||
|
# set :http_path, "/Content/images/"
|
||||||
|
|
||||||
|
# Disable cache buster
|
||||||
|
# disable :cache_buster
|
||||||
|
end
|
4
lib/middleman/template/views/index.html.haml
Normal file
4
lib/middleman/template/views/index.html.haml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- content_for :head do
|
||||||
|
%title Custom head title
|
||||||
|
|
||||||
|
%h1 The Middleman is watching.
|
7
lib/middleman/template/views/layout.html.haml
Normal file
7
lib/middleman/template/views/layout.html.haml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
%html
|
||||||
|
%head
|
||||||
|
%title The Middleman!
|
||||||
|
= yield_content :head
|
||||||
|
|
||||||
|
%body
|
||||||
|
= yield
|
1
lib/middleman/template/views/stylesheets/site.css.sass
Normal file
1
lib/middleman/template/views/stylesheets/site.css.sass
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@import compass/reset.sass
|
25
lib/middleman/templater+dynamic_renderer.rb
Normal file
25
lib/middleman/templater+dynamic_renderer.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'rack/test' # Use Rack::Test to access Sinatra without starting up a full server
|
||||||
|
|
||||||
|
# Monkey-patch to use a dynamic renderer
|
||||||
|
class Templater::Actions::File
|
||||||
|
def identical?
|
||||||
|
if exists?
|
||||||
|
return true if File.mtime(source) < File.mtime(destination)
|
||||||
|
FileUtils.identical?(source, destination)
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Templater::Actions::Template
|
||||||
|
def render
|
||||||
|
@render_cache ||= begin
|
||||||
|
# The default render just requests the page over Rack and writes the response
|
||||||
|
request_path = destination.gsub(File.join(Dir.pwd, Middleman::Base.build_dir), "")
|
||||||
|
browser = Rack::Test::Session.new(Rack::MockSession.new(Middleman::Base))
|
||||||
|
browser.get(request_path)
|
||||||
|
browser.last_response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
134
middleman.gemspec
Normal file
134
middleman.gemspec
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
# Generated by jeweler
|
||||||
|
# DO NOT EDIT THIS FILE DIRECTLY
|
||||||
|
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = %q{middleman}
|
||||||
|
s.version = "0.9.20"
|
||||||
|
|
||||||
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
|
s.authors = ["Thomas Reynolds"]
|
||||||
|
s.date = %q{2009-10-22}
|
||||||
|
s.email = %q{tdreyno@gmail.com}
|
||||||
|
s.executables = ["mm-init", "mm-build", "mm-server"]
|
||||||
|
s.extra_rdoc_files = [
|
||||||
|
"LICENSE",
|
||||||
|
"README.rdoc"
|
||||||
|
]
|
||||||
|
s.files = [
|
||||||
|
".document",
|
||||||
|
".gitignore",
|
||||||
|
"LICENSE",
|
||||||
|
"README.rdoc",
|
||||||
|
"Rakefile",
|
||||||
|
"VERSION",
|
||||||
|
"bin/mm-build",
|
||||||
|
"bin/mm-init",
|
||||||
|
"bin/mm-server",
|
||||||
|
"deps.rip",
|
||||||
|
"lib/middleman.rb",
|
||||||
|
"lib/middleman/base.rb",
|
||||||
|
"lib/middleman/builder.rb",
|
||||||
|
"lib/middleman/config.ru",
|
||||||
|
"lib/middleman/features/cache_buster.rb",
|
||||||
|
"lib/middleman/features/compass.rb",
|
||||||
|
"lib/middleman/features/growl.rb",
|
||||||
|
"lib/middleman/features/maruku.rb",
|
||||||
|
"lib/middleman/features/minify_css.rb",
|
||||||
|
"lib/middleman/features/minify_javascript.rb",
|
||||||
|
"lib/middleman/features/relative_assets.rb",
|
||||||
|
"lib/middleman/features/slickmap.rb",
|
||||||
|
"lib/middleman/features/smush_pngs.rb",
|
||||||
|
"lib/middleman/haml.rb",
|
||||||
|
"lib/middleman/helpers.rb",
|
||||||
|
"lib/middleman/rack/sprockets+ruby19.rb",
|
||||||
|
"lib/middleman/rack/sprockets.rb",
|
||||||
|
"lib/middleman/rack/static.rb",
|
||||||
|
"lib/middleman/sass.rb",
|
||||||
|
"lib/middleman/template/init.rbt",
|
||||||
|
"lib/middleman/template/views/index.html.haml",
|
||||||
|
"lib/middleman/template/views/layout.html.haml",
|
||||||
|
"lib/middleman/template/views/stylesheets/site.css.sass",
|
||||||
|
"lib/middleman/templater+dynamic_renderer.rb",
|
||||||
|
"middleman.gemspec",
|
||||||
|
"spec/builder_spec.rb",
|
||||||
|
"spec/cache_buster_spec.rb",
|
||||||
|
"spec/fixtures/sample/init.rb",
|
||||||
|
"spec/fixtures/sample/public/javascripts/to-be-included.js",
|
||||||
|
"spec/fixtures/sample/public/static.html",
|
||||||
|
"spec/fixtures/sample/public/stylesheets/static.css",
|
||||||
|
"spec/fixtures/sample/views/_partial.haml",
|
||||||
|
"spec/fixtures/sample/views/index.html.haml",
|
||||||
|
"spec/fixtures/sample/views/inline-js.html.haml",
|
||||||
|
"spec/fixtures/sample/views/javascripts/empty-with-include.js",
|
||||||
|
"spec/fixtures/sample/views/layout.haml",
|
||||||
|
"spec/fixtures/sample/views/maruku.html.maruku",
|
||||||
|
"spec/fixtures/sample/views/services/index.html.haml",
|
||||||
|
"spec/fixtures/sample/views/stylesheets/site.css.sass",
|
||||||
|
"spec/generator_spec.rb",
|
||||||
|
"spec/relative_assets_spec.rb",
|
||||||
|
"spec/spec_helper.rb"
|
||||||
|
]
|
||||||
|
s.homepage = %q{http://wiki.github.com/tdreyno/middleman}
|
||||||
|
s.rdoc_options = ["--charset=UTF-8"]
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
s.rubyforge_project = %q{middleman}
|
||||||
|
s.rubygems_version = %q{1.3.5}
|
||||||
|
s.summary = %q{A static site generator utilizing Haml, Sass and providing YUI compression and cache busting}
|
||||||
|
s.test_files = [
|
||||||
|
"spec/builder_spec.rb",
|
||||||
|
"spec/cache_buster_spec.rb",
|
||||||
|
"spec/fixtures/sample/init.rb",
|
||||||
|
"spec/generator_spec.rb",
|
||||||
|
"spec/relative_assets_spec.rb",
|
||||||
|
"spec/spec_helper.rb"
|
||||||
|
]
|
||||||
|
|
||||||
|
if s.respond_to? :specification_version then
|
||||||
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||||
|
s.specification_version = 3
|
||||||
|
|
||||||
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||||
|
s.add_runtime_dependency(%q<thin>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<shotgun>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<templater>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<sprockets>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<sinatra-content-for>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<rack-test>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<yui-compressor>, [">= 0"])
|
||||||
|
s.add_runtime_dependency(%q<haml>, [">= 2.1.0"])
|
||||||
|
s.add_runtime_dependency(%q<compass>, [">= 0"])
|
||||||
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
||||||
|
s.add_development_dependency(%q<sdoc>, [">= 0"])
|
||||||
|
else
|
||||||
|
s.add_dependency(%q<thin>, [">= 0"])
|
||||||
|
s.add_dependency(%q<shotgun>, [">= 0"])
|
||||||
|
s.add_dependency(%q<templater>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sprockets>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sinatra-content-for>, [">= 0"])
|
||||||
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
||||||
|
s.add_dependency(%q<yui-compressor>, [">= 0"])
|
||||||
|
s.add_dependency(%q<haml>, [">= 2.1.0"])
|
||||||
|
s.add_dependency(%q<compass>, [">= 0"])
|
||||||
|
s.add_dependency(%q<rspec>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sdoc>, [">= 0"])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s.add_dependency(%q<thin>, [">= 0"])
|
||||||
|
s.add_dependency(%q<shotgun>, [">= 0"])
|
||||||
|
s.add_dependency(%q<templater>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sprockets>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sinatra-content-for>, [">= 0"])
|
||||||
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
||||||
|
s.add_dependency(%q<yui-compressor>, [">= 0"])
|
||||||
|
s.add_dependency(%q<haml>, [">= 2.1.0"])
|
||||||
|
s.add_dependency(%q<compass>, [">= 0"])
|
||||||
|
s.add_dependency(%q<rspec>, [">= 0"])
|
||||||
|
s.add_dependency(%q<sdoc>, [">= 0"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
60
spec/builder_spec.rb
Normal file
60
spec/builder_spec.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
describe "Builder" do
|
||||||
|
def project_file(*parts)
|
||||||
|
File.expand_path(File.join(File.dirname(__FILE__), "..", *parts))
|
||||||
|
end
|
||||||
|
|
||||||
|
before :all do
|
||||||
|
@root_dir = project_file("spec", "fixtures", "sample")
|
||||||
|
end
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
build_cmd = project_file("bin", "mm-build")
|
||||||
|
`cd #{@root_dir} && #{build_cmd}`
|
||||||
|
end
|
||||||
|
|
||||||
|
after :each do
|
||||||
|
FileUtils.rm_rf(File.join(@root_dir, "build"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build haml files" do
|
||||||
|
File.exists?("#{@root_dir}/build/index.html").should be_true
|
||||||
|
File.read("#{@root_dir}/build/index.html").should include("<h1>Welcome</h1>")
|
||||||
|
end
|
||||||
|
|
||||||
|
xit "should build maruku files" do
|
||||||
|
File.exists?("#{@root_dir}/build/maruku.html").should be_true
|
||||||
|
File.read("#{@root_dir}/build/maruku.html").should include("<h1 class='header' id='hello_maruku'>Hello Maruku</h1>")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build static files" do
|
||||||
|
File.exists?("#{@root_dir}/build/static.html").should be_true
|
||||||
|
File.read("#{@root_dir}/build/static.html").should include("Static, no code!")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build subdirectory files" do
|
||||||
|
File.exists?("#{@root_dir}/build/services/index.html").should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build sass files" do
|
||||||
|
File.exists?("#{@root_dir}/build/stylesheets/site.css").should be_true
|
||||||
|
File.read("#{@root_dir}/build/stylesheets/site.css").should include("html,body,div,span,applet,object,iframe")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should build static css files" do
|
||||||
|
File.exists?("#{@root_dir}/build/stylesheets/static.css").should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not build partial files" do
|
||||||
|
File.exists?("#{@root_dir}/build/_partial.html").should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should minify inline javascript" do
|
||||||
|
File.readlines("#{@root_dir}/build/inline-js.html").length.should == 9
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should combine javascript" do
|
||||||
|
File.read("#{@root_dir}/build/javascripts/empty-with-include.js").should include("combo")
|
||||||
|
end
|
||||||
|
end
|
18
spec/cache_buster_spec.rb
Normal file
18
spec/cache_buster_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require File.join(File.dirname(__FILE__), "spec_helper")
|
||||||
|
|
||||||
|
base = ::Middleman::Base
|
||||||
|
base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
|
||||||
|
|
||||||
|
describe "Cache Buster Feature" do
|
||||||
|
it "should not append query string if off" do
|
||||||
|
base.disable :cache_buster
|
||||||
|
base.new
|
||||||
|
base.asset_url("stylesheets/static.css").should_not include("?")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should append query string if on" do
|
||||||
|
base.enable :cache_buster
|
||||||
|
base.new
|
||||||
|
base.asset_url("stylesheets/static.css").should include("?")
|
||||||
|
end
|
||||||
|
end
|
1
spec/fixtures/sample/init.rb
vendored
Normal file
1
spec/fixtures/sample/init.rb
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
enable :maruku
|
1
spec/fixtures/sample/public/javascripts/to-be-included.js
vendored
Normal file
1
spec/fixtures/sample/public/javascripts/to-be-included.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
function() { return "combo"; };
|
1
spec/fixtures/sample/public/static.html
vendored
Normal file
1
spec/fixtures/sample/public/static.html
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Static, no code!
|
2
spec/fixtures/sample/public/stylesheets/static.css
vendored
Normal file
2
spec/fixtures/sample/public/stylesheets/static.css
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
body {
|
||||||
|
font-size: 12px; }
|
1
spec/fixtures/sample/views/_partial.haml
vendored
Normal file
1
spec/fixtures/sample/views/_partial.haml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%p Test
|
1
spec/fixtures/sample/views/index.html.haml
vendored
Normal file
1
spec/fixtures/sample/views/index.html.haml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%h1 Welcome
|
7
spec/fixtures/sample/views/inline-js.html.haml
vendored
Normal file
7
spec/fixtures/sample/views/inline-js.html.haml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
:javascript
|
||||||
|
;(function() {
|
||||||
|
this;
|
||||||
|
should();
|
||||||
|
all.be();
|
||||||
|
on = { one: line };
|
||||||
|
});
|
1
spec/fixtures/sample/views/javascripts/empty-with-include.js
vendored
Normal file
1
spec/fixtures/sample/views/javascripts/empty-with-include.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//= require <to-be-included>
|
6
spec/fixtures/sample/views/layout.haml
vendored
Normal file
6
spec/fixtures/sample/views/layout.haml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
%html
|
||||||
|
%head
|
||||||
|
%link{ :href => "/stylesheets/site.css", :rel => "stylesheet", :type => "text/css" }
|
||||||
|
%title My Sample Site
|
||||||
|
%body
|
||||||
|
= yield
|
1
spec/fixtures/sample/views/maruku.html.maruku
vendored
Normal file
1
spec/fixtures/sample/views/maruku.html.maruku
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Hello Maruku {.header}
|
1
spec/fixtures/sample/views/services/index.html.haml
vendored
Normal file
1
spec/fixtures/sample/views/services/index.html.haml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
%h2 Services
|
1
spec/fixtures/sample/views/stylesheets/site.css.sass
vendored
Normal file
1
spec/fixtures/sample/views/stylesheets/site.css.sass
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@import compass/reset.sass
|
34
spec/generator_spec.rb
Normal file
34
spec/generator_spec.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
describe "Generator" do
|
||||||
|
def project_file(*parts)
|
||||||
|
File.expand_path(File.join(File.dirname(__FILE__), "..", *parts))
|
||||||
|
end
|
||||||
|
|
||||||
|
before :all do
|
||||||
|
@root_dir = project_file("spec", "fixtures", "generator-test")
|
||||||
|
end
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
init_cmd = project_file("bin", "mm-init")
|
||||||
|
`cd #{File.dirname(@root_dir)} && #{init_cmd} #{File.basename(@root_dir)}`
|
||||||
|
end
|
||||||
|
|
||||||
|
after :each do
|
||||||
|
FileUtils.rm_rf(@root_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should copy template files" do
|
||||||
|
template_dir = project_file("lib", "template", "**/*")
|
||||||
|
Dir[template_dir].each do |f|
|
||||||
|
next if File.directory?(f)
|
||||||
|
File.exists?("#{@root_dir}/#{f.split('template/')[1]}").should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create empty directories" do
|
||||||
|
%w(views/stylesheets public/stylesheets public/javascripts public/images).each do |d|
|
||||||
|
File.exists?("#{@root_dir}/#{d}").should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
spec/relative_assets_spec.rb
Normal file
28
spec/relative_assets_spec.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# require File.join(File.dirname(__FILE__), "spec_helper")
|
||||||
|
#
|
||||||
|
# base = ::Middleman::Base
|
||||||
|
# base.set :root, File.join(File.dirname(__FILE__), "fixtures", "sample")
|
||||||
|
#
|
||||||
|
# describe "Relative Assets Feature" do
|
||||||
|
# before do
|
||||||
|
# base.disable :relative_assets
|
||||||
|
# base.init!
|
||||||
|
# @app = base.new
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it "should not contain ../ if off" do
|
||||||
|
# @app.asset_url("stylesheets/static.css").should_not include("?")
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# describe "Relative Assets Feature" do
|
||||||
|
# before do
|
||||||
|
# base.enable :relative_assets
|
||||||
|
# base.init!
|
||||||
|
# @app = base.new
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it "should contain ../ if on" do
|
||||||
|
# @app.asset_url("stylesheets/static.css").should include("?")
|
||||||
|
# end
|
||||||
|
# end
|
10
spec/spec_helper.rb
Normal file
10
spec/spec_helper.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
require 'rubygems'
|
||||||
|
require 'spec'
|
||||||
|
|
||||||
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
||||||
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||||
|
require 'middleman'
|
||||||
|
|
||||||
|
Spec::Runner.configure do |config|
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue