tdreyno-staticmatic 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|