tdreyno-staticmatic 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/Rakefile +12 -0
- data/bin/staticmatic +12 -0
- data/lib/staticmatic/actionpack_support/mime.rb +5 -0
- data/lib/staticmatic/actionpack_support/remove_partial_benchmark.rb +6 -0
- data/lib/staticmatic/autoload.rb +18 -0
- data/lib/staticmatic/base.rb +171 -0
- data/lib/staticmatic/builder.rb +102 -0
- data/lib/staticmatic/config.rb +47 -0
- data/lib/staticmatic/creator.rb +18 -0
- data/lib/staticmatic/deprecation.rb +26 -0
- data/lib/staticmatic/helpers/asset_tag_helper.rb +37 -0
- data/lib/staticmatic/helpers/deprecated_helpers.rb +48 -0
- data/lib/staticmatic/helpers/page_helper.rb +9 -0
- data/lib/staticmatic/helpers/url_helper.rb +19 -0
- data/lib/staticmatic/previewer.rb +65 -0
- data/lib/staticmatic/rescue.rb +14 -0
- data/lib/staticmatic/template_handlers/haml.rb +19 -0
- data/lib/staticmatic/template_handlers/liquid.rb +13 -0
- data/lib/staticmatic/template_handlers/markdown.rb +13 -0
- data/lib/staticmatic/template_handlers/sass.rb +13 -0
- data/lib/staticmatic/template_handlers/textile.rb +13 -0
- data/lib/staticmatic/templates/default/Rakefile +3 -0
- data/lib/staticmatic/templates/default/config.rb +3 -0
- data/lib/staticmatic/templates/default/src/helpers/site_helper.rb +5 -0
- data/lib/staticmatic/templates/default/src/layouts/site.html.haml +6 -0
- data/lib/staticmatic/templates/default/src/pages/index.html.haml +1 -0
- data/lib/staticmatic/templates/default/src/stylesheets/site.css.sass +3 -0
- data/lib/staticmatic/templates/rescues/default_error.html.erb +2 -0
- data/lib/staticmatic/templates/rescues/template_error.html.erb +19 -0
- data/lib/staticmatic.rb +28 -0
- data/lib/tasks/staticmatic.rb +9 -0
- data/staticmatic.gemspec +53 -0
- data/vendor/html-scanner/html/document.rb +68 -0
- data/vendor/html-scanner/html/node.rb +530 -0
- data/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/vendor/html-scanner/html/selector.rb +828 -0
- data/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/vendor/html-scanner/html/version.rb +11 -0
- metadata +127 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (C) 2008 Stephen Bartholomew
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
9
|
+
|
10
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
11
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
12
|
+
end
|
data/bin/staticmatic
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
autoload :Builder, 'staticmatic/builder'
|
3
|
+
autoload :Creator, 'staticmatic/creator'
|
4
|
+
autoload :Config, 'staticmatic/config'
|
5
|
+
autoload :Deprecation, 'staticmatic/deprecation'
|
6
|
+
autoload :Previewer, 'staticmatic/previewer'
|
7
|
+
autoload :Rescue, 'staticmatic/rescue'
|
8
|
+
|
9
|
+
module Helpers
|
10
|
+
autoload :AssetTagHelper, 'staticmatic/helpers/asset_tag_helper'
|
11
|
+
autoload :DeprecatedHelpers, 'staticmatic/helpers/deprecated_helpers'
|
12
|
+
autoload :PageHelper, 'staticmatic/helpers/page_helper'
|
13
|
+
autoload :UrlHelper, 'staticmatic/helpers/url_helper'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'staticmatic/actionpack_support/mime'
|
18
|
+
require 'staticmatic/actionpack_support/remove_partial_benchmark'
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
class Base
|
3
|
+
include StaticMatic::Rescue
|
4
|
+
include StaticMatic::Deprecation
|
5
|
+
|
6
|
+
attr_accessor :logger
|
7
|
+
attr_accessor :root_dir
|
8
|
+
attr_accessor :build_dir
|
9
|
+
attr_accessor :src_dir
|
10
|
+
attr_accessor :template
|
11
|
+
attr_accessor :request
|
12
|
+
|
13
|
+
def initialize(root_dir)
|
14
|
+
@root_dir = root_dir
|
15
|
+
@src_dir = "#{@root_dir}/src"
|
16
|
+
@build_dir = "#{@root_dir}/build"
|
17
|
+
load_helpers
|
18
|
+
initialize_config
|
19
|
+
initialize_logger
|
20
|
+
initialize_template
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_config
|
24
|
+
StaticMatic::Config.setup
|
25
|
+
config_file = File.join(@root_dir, "config.rb")
|
26
|
+
require config_file if File.exists? config_file
|
27
|
+
|
28
|
+
Haml::Template.options = StaticMatic::Config[:haml_options] if defined?(Haml::Template)
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize_logger
|
32
|
+
@logger = Logger.new($stderr)
|
33
|
+
@logger.level = Logger::INFO
|
34
|
+
@logger
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize_template
|
38
|
+
@template = ActionView::Base.new([], {}, self)
|
39
|
+
@template.template_format = :html
|
40
|
+
@template.finder.view_paths = [@src_dir]
|
41
|
+
@template.instance_variable_set("@staticmatic", self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def render(template, options = {})
|
45
|
+
@template.template_format = determine_format_for(template)
|
46
|
+
template = strip_extension(template)
|
47
|
+
|
48
|
+
begin
|
49
|
+
@template.render_file(full_template_path(template), true)
|
50
|
+
rescue Exception => e
|
51
|
+
rescue_from_error(e)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Render the given template within the current layout
|
56
|
+
def render_with_layout(template)
|
57
|
+
@template.instance_variable_set("@relative_path_to_root", "#{calculate_relative_path_to_root(full_template_path(template))}")
|
58
|
+
content_for_layout = render(template)
|
59
|
+
|
60
|
+
@template.instance_variable_set("@current_page", template)
|
61
|
+
@template.instance_variable_set("@content_for_layout", content_for_layout)
|
62
|
+
|
63
|
+
layout = @template.instance_variable_get("@layout")
|
64
|
+
|
65
|
+
# Clean @layout variable for next request
|
66
|
+
@template.instance_variable_set("@layout", nil)
|
67
|
+
|
68
|
+
layout ||= determine_default_layout
|
69
|
+
|
70
|
+
render("layouts/#{layout}")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Load all helpers from src/helpers/
|
74
|
+
def load_helpers
|
75
|
+
Dir["#{@src_dir}/helpers/**/*_helper.rb"].each do |helper|
|
76
|
+
load helper
|
77
|
+
module_name = File.basename(helper, '.rb').gsub(/(^|\_)./) { |c| c.upcase }.gsub(/\_/, '')
|
78
|
+
ActionView::Base.class_eval("include #{module_name}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return the source directory for a given template
|
83
|
+
#
|
84
|
+
# Default is pages/
|
85
|
+
#
|
86
|
+
def template_directory_for(template)
|
87
|
+
template_directory = "pages"
|
88
|
+
|
89
|
+
%w(stylesheets layouts).each do |directory|
|
90
|
+
template_directory = "" if template.match(/^(\/)?#{directory}/)
|
91
|
+
end
|
92
|
+
|
93
|
+
template_directory
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return the format for a given template path
|
97
|
+
#
|
98
|
+
# For example: application.css.sass -> :css
|
99
|
+
#
|
100
|
+
def determine_format_for(template)
|
101
|
+
ext_matches = template.match /\.([a-z0-9]+)/
|
102
|
+
|
103
|
+
# For templates that have only handler extensions, default for backwards compatibility
|
104
|
+
if ext_matches
|
105
|
+
unless template.match(/\.([a-z0-9]+)\./)
|
106
|
+
case ext_matches[1]
|
107
|
+
when "sass"
|
108
|
+
extension = :css
|
109
|
+
when "haml"
|
110
|
+
extension = :html
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
extension = ext_matches[1].to_sym unless extension
|
115
|
+
else
|
116
|
+
extension = :html
|
117
|
+
end
|
118
|
+
|
119
|
+
extension
|
120
|
+
end
|
121
|
+
|
122
|
+
# Default layout is 'site' but we'll also accept 'application'
|
123
|
+
def determine_default_layout
|
124
|
+
layout = "site"
|
125
|
+
|
126
|
+
Dir["#{@src_dir}/layouts/**"].each do |layout_file|
|
127
|
+
layout = "application" if layout_file.match /application/
|
128
|
+
end
|
129
|
+
|
130
|
+
layout
|
131
|
+
end
|
132
|
+
|
133
|
+
# Remove the extension from a given template path
|
134
|
+
def strip_extension(template)
|
135
|
+
template.gsub(File.extname(template), '')
|
136
|
+
end
|
137
|
+
|
138
|
+
# Checks to see if a template exists within a given path
|
139
|
+
#
|
140
|
+
# Current only used by the previewer as ActionView handles the actual checking
|
141
|
+
def can_render?(template)
|
142
|
+
@template.template_format = determine_format_for(template)
|
143
|
+
template = strip_extension(template)
|
144
|
+
@template.finder.class.reload!
|
145
|
+
@template.finder.file_exists?(full_template_path(template))
|
146
|
+
end
|
147
|
+
|
148
|
+
# Adds 'index' to a given template path if the path is a directory
|
149
|
+
# Will render as path/index.html
|
150
|
+
#
|
151
|
+
def add_index_if_needed(template)
|
152
|
+
File.directory?(File.join(File.expand_path(@src_dir), template)) ?
|
153
|
+
File.join(template, "index") :
|
154
|
+
template
|
155
|
+
end
|
156
|
+
|
157
|
+
# Full path to a template, relative to src/
|
158
|
+
def full_template_path(template)
|
159
|
+
add_index_if_needed(File.join(template_directory_for(template), template))
|
160
|
+
end
|
161
|
+
|
162
|
+
def calculate_relative_path_to_root(template)
|
163
|
+
if template.match(/^((\.\.?)?\/|\#|.+?\:)/) == nil
|
164
|
+
current_page_depth = template.split('/').length - 2;
|
165
|
+
(current_page_depth > 0) ? ([ '..' ] * current_page_depth).join('/') + '/' : ''
|
166
|
+
else
|
167
|
+
''
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
class Builder
|
3
|
+
attr_accessor :staticmatic
|
4
|
+
|
5
|
+
def initialize(staticmatic)
|
6
|
+
@staticmatic = staticmatic
|
7
|
+
determine_last_build
|
8
|
+
build_pages
|
9
|
+
log_version
|
10
|
+
end
|
11
|
+
|
12
|
+
def determine_last_build
|
13
|
+
versions_file = @staticmatic.root_dir + "/builds"
|
14
|
+
@last_build = File.read(versions_file).split(/\n/)[0] if File.exists?(versions_file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def log_version
|
18
|
+
return unless StaticMatic::Config[:use_build_tracking]
|
19
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
20
|
+
versions_file = @staticmatic.root_dir + "/builds"
|
21
|
+
|
22
|
+
if File.exists?(versions_file)
|
23
|
+
current_versions = File.read(versions_file)
|
24
|
+
|
25
|
+
File.open(versions_file, "w") do |file|
|
26
|
+
file.puts timestamp
|
27
|
+
file.puts current_versions
|
28
|
+
end
|
29
|
+
else
|
30
|
+
File.open(versions_file, "w") do |file|
|
31
|
+
file.puts timestamp
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_pages
|
37
|
+
%w(pages stylesheets).each do |template_path|
|
38
|
+
Dir["#{@staticmatic.src_dir}/#{template_path}/**/*"].each do |path|
|
39
|
+
if File.directory? path
|
40
|
+
unless File.exists? build_path_for(path)
|
41
|
+
@staticmatic.logger.info("Creating: #{build_path_for(path)}")
|
42
|
+
FileUtils.mkdir(build_path_for(path))
|
43
|
+
end
|
44
|
+
else
|
45
|
+
format = @staticmatic.determine_format_for(path).to_s
|
46
|
+
base_template_name = base_template_name_for(path)
|
47
|
+
|
48
|
+
@staticmatic.template.template_format = format
|
49
|
+
build_file_path = "#{build_path_for(path)}"
|
50
|
+
|
51
|
+
if !StaticMatic::Config[:use_build_tracking] || should_overwrite?(path, build_file_path)
|
52
|
+
output = (format == "html") ?
|
53
|
+
@staticmatic.render_with_layout(base_template_name) :
|
54
|
+
@staticmatic.render(base_template_name)
|
55
|
+
|
56
|
+
output_prefix = "#{template_path}/" if template_path != "pages"
|
57
|
+
save_built_file(build_file_path, output)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def should_overwrite?(template_file, build_file)
|
65
|
+
return true unless File.exists?(build_file)
|
66
|
+
file_changed?(template_file)
|
67
|
+
end
|
68
|
+
|
69
|
+
def file_changed?(src_file)
|
70
|
+
template_modification_time = File.stat(src_file).mtime.strftime("%Y%m%d%H%M%S")
|
71
|
+
template_modification_time.to_i > @last_build.to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
# Strip off src file path and extension
|
75
|
+
def base_template_name_for(path)
|
76
|
+
path.gsub("#{@staticmatic.root_dir}/", "").
|
77
|
+
gsub(/^src\//, '').
|
78
|
+
gsub(/^pages\//, '').
|
79
|
+
gsub(/\.[a-z]+$/, '')
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return an output filename
|
83
|
+
def build_path_for(path)
|
84
|
+
File.join(@staticmatic.build_dir, base_template_name_for(path))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Save contents to the specified file with the given extension to the build directory
|
88
|
+
def save_built_file(path, contents)
|
89
|
+
@staticmatic.logger.info("Generating #{path}")
|
90
|
+
File.open(path, 'w+') do |f|
|
91
|
+
f << contents
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def build(staticmatic)
|
97
|
+
staticmatic = StaticMatic::Base.new(staticmatic) if staticmatic.is_a? String
|
98
|
+
new(staticmatic)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
class Config
|
3
|
+
class << self
|
4
|
+
def defaults
|
5
|
+
@defaults ||= {
|
6
|
+
:host => "0.0.0.0",
|
7
|
+
:port => "3000",
|
8
|
+
:sass_options => {},
|
9
|
+
:haml_options => {},
|
10
|
+
:use_build_tracking => true
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup(settings = {})
|
15
|
+
@configuration = defaults.merge(settings)
|
16
|
+
end
|
17
|
+
|
18
|
+
def use
|
19
|
+
yield @configuration
|
20
|
+
end
|
21
|
+
|
22
|
+
def key?(key)
|
23
|
+
@configuration.key?(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
(@configuration||={})[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def []=(key,val)
|
31
|
+
@configuration[key] = val
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(key)
|
35
|
+
@configuration.delete(key)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fetch(key, default)
|
39
|
+
@configuration.fetch(key, default)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_hash
|
43
|
+
@configuration
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
class Creator
|
3
|
+
class << self
|
4
|
+
def setup(directory)
|
5
|
+
FileUtils.mkdir(directory) unless File.exists?(directory)
|
6
|
+
|
7
|
+
template_directory = Dir.glob(File.dirname(__FILE__) + "/templates/default/**")
|
8
|
+
|
9
|
+
FileUtils.cp_r(template_directory, directory)
|
10
|
+
|
11
|
+
unless File.exists?(directory + "/build")
|
12
|
+
FileUtils.mkdir(directory + "/build")
|
13
|
+
FileUtils.mkdir(directory + "/build/stylesheets")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
module Deprecation
|
3
|
+
def deprecate(options = {})
|
4
|
+
message = "#{caller_method_name} has been deprecated and will be removed."
|
5
|
+
message << %Q{ Please use "#{options[:alt]}" instead } if options[:alt]
|
6
|
+
|
7
|
+
logger.warn(message)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Thanks to http://snippets.dzone.com/posts/show/2787 for this nugget
|
13
|
+
def caller_method_name
|
14
|
+
parse_caller(caller(2).first).last
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse_caller(at)
|
18
|
+
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
|
19
|
+
file = Regexp.last_match[1]
|
20
|
+
line = Regexp.last_match[2].to_i
|
21
|
+
method = Regexp.last_match[3]
|
22
|
+
[file, line, method]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
module Helpers
|
3
|
+
module AssetTagHelper
|
4
|
+
def stylesheet_link_tag(*sources)
|
5
|
+
options = sources.extract_options!.stringify_keys
|
6
|
+
expand_stylesheet_sources(sources).collect do |source|
|
7
|
+
stylesheet_tag(source, options)
|
8
|
+
end.join("\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
def javascript_include_tag(*sources)
|
12
|
+
options = sources.extract_options!.stringify_keys
|
13
|
+
expand_javascript_sources(sources).collect do |source|
|
14
|
+
javascript_src_tag(source, options)
|
15
|
+
end.join("\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
def javascript_src_tag(source, options)
|
19
|
+
content_tag("script", "", { "type" => Mime::JS, "src" => compute_public_path(source, "javascripts", "js") }.merge(options))
|
20
|
+
end
|
21
|
+
|
22
|
+
def stylesheet_tag(source, options)
|
23
|
+
tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => compute_public_path(source, "stylesheets", "css") }.merge(options), false, false)
|
24
|
+
end
|
25
|
+
|
26
|
+
def compute_public_path(source, dir, ext = nil, include_host = true)
|
27
|
+
path = "#{relative_path_to_root}#{dir}/#{source}"
|
28
|
+
path << ".#{ext}" if ext
|
29
|
+
path
|
30
|
+
end
|
31
|
+
|
32
|
+
def relative_path_to_root
|
33
|
+
@relative_path_to_root
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
module Helpers
|
3
|
+
module DeprecatedHelpers
|
4
|
+
def stylesheets(*params)
|
5
|
+
deprecate :alt => "stylesheet_link_tag"
|
6
|
+
|
7
|
+
if params.blank?
|
8
|
+
glob = File.join(@staticmatic.src_dir, 'stylesheets', '*.sass')
|
9
|
+
stylesheets = Dir[glob].inject([]) do |sum, stylesheet|
|
10
|
+
sum << File.basename(stylesheet).chomp(File.extname(stylesheet))
|
11
|
+
end
|
12
|
+
|
13
|
+
stylesheets.concat assets_from_build_directory("stylesheets", "css", stylesheets)
|
14
|
+
|
15
|
+
params = stylesheets
|
16
|
+
end
|
17
|
+
|
18
|
+
stylesheet_link_tag(params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def link(title, href = "", options = {})
|
22
|
+
deprecate :alt => "link_to"
|
23
|
+
link_to(title, href, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def img(name, options = {})
|
27
|
+
deprecate :alt => "image_tag"
|
28
|
+
image_tag(name, options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def javascripts(*files)
|
32
|
+
javascript_include_tag(files)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
# Return an array of asset files from a given build directory
|
37
|
+
#
|
38
|
+
# Optionally pass in an array to exclude files served dynamically
|
39
|
+
def assets_from_build_directory(dir, ext, exclude = [])
|
40
|
+
glob = File.join(@staticmatic.build_dir, dir, "*.#{ext}")
|
41
|
+
Dir[glob].inject([]) do |sum, file|
|
42
|
+
file = File.basename(file).chomp(File.extname(file))
|
43
|
+
sum << file unless exclude && exclude.include?(file)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
module Helpers
|
3
|
+
module UrlHelper
|
4
|
+
def link_to(name, options = {}, html_options = nil)
|
5
|
+
options = urlify(name) if options == {}
|
6
|
+
super(name, options, html_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def urlify(string)
|
10
|
+
string.tr(" ", "_").
|
11
|
+
sub("&", "and").
|
12
|
+
sub("@", "at").
|
13
|
+
tr("^A-Za-z0-9_", "").
|
14
|
+
sub(/_{2,}/, "_").
|
15
|
+
downcase
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'mongrel'
|
2
|
+
|
3
|
+
module StaticMatic
|
4
|
+
class Previewer < Mongrel::HttpHandler
|
5
|
+
@@file_only_methods = %w(GET HEAD)
|
6
|
+
|
7
|
+
def initialize(staticmatic)
|
8
|
+
@files = Mongrel::DirHandler.new(staticmatic.build_dir, false)
|
9
|
+
@staticmatic = staticmatic
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(request, response)
|
13
|
+
@staticmatic.load_helpers
|
14
|
+
path_info = request.params[Mongrel::Const::PATH_INFO]
|
15
|
+
get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD]
|
16
|
+
|
17
|
+
file_ext = File.extname(path_info).gsub(/^\./, '')
|
18
|
+
file_ext = "html" if file_ext.blank?
|
19
|
+
|
20
|
+
file_name = path_info.chomp(".#{file_ext}")
|
21
|
+
file_name = CGI::unescape(file_name)
|
22
|
+
file_name.gsub!(/^\//, '')
|
23
|
+
|
24
|
+
if file_ext && file_ext.match(/html|css/)
|
25
|
+
response.start(200) do |head, out|
|
26
|
+
head["Content-Type"] = "text/#{file_ext}"
|
27
|
+
output = ""
|
28
|
+
|
29
|
+
if @staticmatic.can_render? path_info
|
30
|
+
output = (file_ext == "css") ?
|
31
|
+
@staticmatic.render(path_info) :
|
32
|
+
@staticmatic.render_with_layout(file_name)
|
33
|
+
else
|
34
|
+
if @files.can_serve(path_info)
|
35
|
+
@files.process(request,response)
|
36
|
+
else
|
37
|
+
output = "File not Found"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
out.write output
|
41
|
+
end
|
42
|
+
else
|
43
|
+
# try to serve static file from site dir
|
44
|
+
@files.process(request,response) if @files.can_serve(path_info)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class << self
|
49
|
+
# Starts the StaticMatic preview server
|
50
|
+
def start(staticmatic)
|
51
|
+
staticmatic = StaticMatic::Base.new(staticmatic) if staticmatic.is_a? String
|
52
|
+
|
53
|
+
config = Mongrel::Configurator.new :host => StaticMatic::Config[:host] do
|
54
|
+
puts "Running Preview of #{staticmatic.root_dir} on port #{StaticMatic::Config[:post]}"
|
55
|
+
listener :port => StaticMatic::Config[:port] do
|
56
|
+
uri "/", :handler => Previewer.new(staticmatic)
|
57
|
+
end
|
58
|
+
trap("INT") { stop }
|
59
|
+
run
|
60
|
+
end
|
61
|
+
config.join
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module StaticMatic
|
2
|
+
module Rescue
|
3
|
+
# Render an error template for the given exception
|
4
|
+
def rescue_from_error(exception)
|
5
|
+
rescue_template = (exception == ActionView::TemplateError) ?
|
6
|
+
"template_error" :
|
7
|
+
"default_error"
|
8
|
+
|
9
|
+
error_template_path = File.expand_path(File.dirname(__FILE__) + "/templates/rescues/#{rescue_template}.html.erb")
|
10
|
+
@template.instance_variable_set("@exception", exception)
|
11
|
+
@template.render_file(error_template_path, false)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'haml/engine'
|
3
|
+
|
4
|
+
module StaticMatic
|
5
|
+
module TemplateHandlers
|
6
|
+
class Haml < ActionView::TemplateHandler
|
7
|
+
include ActionView::TemplateHandlers::Compilable
|
8
|
+
|
9
|
+
def compile(template, local_assigns = {})
|
10
|
+
options = StaticMatic::Config[:haml_options].dup
|
11
|
+
options[:filename] = template.filename
|
12
|
+
|
13
|
+
::Haml::Engine.new(template.source, options).send(:precompiled_with_ambles, [])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActionView::Template.register_template_handler(:haml, StaticMatic::TemplateHandlers::Haml)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'liquid'
|
2
|
+
|
3
|
+
module StaticMatic
|
4
|
+
module TemplateHandlers
|
5
|
+
class Liquid < ActionView::TemplateHandler
|
6
|
+
def render(template, local_assigns = {})
|
7
|
+
::Liquid::Template.parse(template.source).render(local_assigns)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
ActionView::Template.register_template_handler(:liquid, StaticMatic::TemplateHandlers::Liquid)
|