gumdrop 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/ChangeLog.md +13 -0
- data/Gemfile +6 -2
- data/Gemfile.lock +43 -3
- data/Rakefile +37 -21
- data/Readme.md +60 -158
- data/bin/gumdrop +2 -1
- data/gumdrop.gemspec +11 -4
- data/lib/gumdrop/builder.rb +164 -0
- data/lib/gumdrop/cli/external.rb +14 -9
- data/lib/gumdrop/cli/internal.rb +54 -22
- data/lib/gumdrop/cli.rb +21 -0
- data/lib/gumdrop/content.rb +195 -132
- data/lib/gumdrop/data.rb +185 -0
- data/lib/gumdrop/data_providers/csv.rb +18 -0
- data/lib/gumdrop/data_providers/pstore.rb +25 -0
- data/lib/gumdrop/data_providers/sqlite.rb +43 -0
- data/lib/gumdrop/data_providers/xml.rb +15 -0
- data/lib/gumdrop/data_providers/yaml_and_json.rb +18 -0
- data/lib/gumdrop/data_providers/yamldb.rb +18 -0
- data/lib/gumdrop/data_providers/yamldoc.rb +12 -0
- data/lib/gumdrop/generator.rb +118 -94
- data/lib/gumdrop/renderer.rb +272 -0
- data/lib/gumdrop/server.rb +36 -27
- data/lib/gumdrop/site.rb +283 -338
- data/lib/gumdrop/support/compressor.rb +52 -0
- data/lib/gumdrop/support/sprockets.rb +14 -23
- data/lib/gumdrop/support/stitch.rb +25 -14
- data/lib/gumdrop/support/yaml_doc_template.rb +29 -0
- data/lib/gumdrop/util/configurable.rb +44 -0
- data/lib/gumdrop/util/core_ex.rb +84 -0
- data/lib/gumdrop/util/eventable.rb +35 -0
- data/lib/gumdrop/util/hash_object.rb +70 -0
- data/lib/gumdrop/util/loggable.rb +44 -0
- data/lib/gumdrop/util/pager.rb +51 -0
- data/lib/gumdrop/{support → util}/proxy_handler.rb +7 -6
- data/lib/gumdrop/util/scanner.rb +47 -0
- data/lib/gumdrop/util/site_access.rb +16 -0
- data/lib/gumdrop/util/view_helpers.rb +50 -0
- data/lib/gumdrop/util/yaml_doc.rb +51 -0
- data/lib/gumdrop/version.rb +2 -2
- data/lib/gumdrop.rb +40 -77
- data/specs/content_spec.rb +83 -73
- data/specs/fixtures/expected/data-access/from-csv.html +4 -0
- data/specs/fixtures/expected/data-access/from-json.html +6 -0
- data/specs/fixtures/expected/data-access/from-sqlite.html +5 -0
- data/specs/fixtures/expected/data-access/from-xml.html +4 -0
- data/specs/fixtures/expected/data-access/from-yaml.html +5 -0
- data/specs/fixtures/expected/data-access/from-yamldb.html +5 -0
- data/specs/fixtures/expected/data-access/from-yamldoc.html +2 -0
- data/specs/fixtures/expected/gen-with-block/as-file.html +1 -0
- data/specs/fixtures/expected/gen-with-block/as-plain.html +1 -0
- data/specs/fixtures/expected/gen-with-block/layout-nested.html +1 -0
- data/specs/fixtures/expected/gen-with-block/layout-nil.html +1 -0
- data/specs/fixtures/expected/gen-with-block/layout-wrap.html +1 -0
- data/specs/fixtures/expected/gen-with-inline-render/0-as-file.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/0-as-plain.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/0-layout-nil.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/0-layout-sub.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/0-layout-wrap.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/1-as-file.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/1-as-plain.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/1-layout-nil.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/1-layout-sub.html +4 -0
- data/specs/fixtures/expected/gen-with-inline-render/1-layout-wrap.html +4 -0
- data/specs/fixtures/expected/goodbye.html +1 -0
- data/specs/fixtures/expected/hello.html +1 -0
- data/specs/fixtures/expected/image.png +0 -0
- data/specs/fixtures/expected/index.html +47 -0
- data/specs/fixtures/expected/js/sprockets-app.js +7 -0
- data/specs/fixtures/expected/js/stitch-app.js +65 -0
- data/specs/fixtures/expected/js/stitch-app.min.js +5 -0
- data/specs/fixtures/expected/js/stitch-app.min.src.js +65 -0
- data/specs/fixtures/expected/js/straight.js +8 -0
- data/specs/fixtures/expected/js/test-coffee.js +5 -0
- data/specs/fixtures/expected/pages/docs/force-abs.html +2 -0
- data/specs/fixtures/expected/pages/docs/index.html +2 -0
- data/specs/fixtures/expected/partials/hoisted-data.html +3 -0
- data/specs/fixtures/expected/partials/nested.html +7 -0
- data/specs/fixtures/expected/partials/params.html +1 -0
- data/specs/fixtures/expected/partials/with-layouts.html +1 -0
- data/specs/fixtures/expected/robots.txt +1 -0
- data/specs/fixtures/expected/test-multi-procs.html +4 -0
- data/specs/fixtures/expected/test-nested-layout.html +1 -0
- data/specs/fixtures/expected/test-no-layout.html +2 -0
- data/specs/fixtures/expected/test-yamldoc.html +1 -0
- data/specs/fixtures/expected/test.html +2 -0
- data/{templates/backbone → specs/fixtures/source}/Gemfile +8 -4
- data/specs/fixtures/source/Gemfile.lock +84 -0
- data/specs/fixtures/source/Gumdrop +60 -9
- data/specs/fixtures/source/data/csv_data.csv +2 -0
- data/specs/fixtures/source/data/json_data.json +13 -0
- data/specs/fixtures/source/data/sql_data.sqlite +0 -0
- data/specs/fixtures/source/data/xml_data.xml +4 -0
- data/specs/fixtures/source/data/yaml_db.yamldb +9 -0
- data/specs/fixtures/source/data/yaml_items.yaml +2 -0
- data/specs/fixtures/source/data/yamldoc.yamldoc +4 -0
- data/specs/fixtures/source/data-access/from-csv.html.erb +4 -0
- data/specs/fixtures/source/data-access/from-json.html.erb +6 -0
- data/specs/fixtures/source/data-access/from-sqlite.html.erb +5 -0
- data/specs/fixtures/source/data-access/from-xml.html.erb +5 -0
- data/specs/fixtures/source/data-access/from-yaml.html.erb +5 -0
- data/specs/fixtures/source/data-access/from-yamldb.html.erb +5 -0
- data/specs/fixtures/source/data-access/from-yamldoc.html.erb +2 -0
- data/specs/fixtures/source/gen-with-inline-render.generator +7 -0
- data/specs/fixtures/source/goodbye.html.erb +1 -0
- data/specs/fixtures/source/hello.html +1 -0
- data/specs/fixtures/source/image.png +0 -0
- data/specs/fixtures/source/index.html.erb +6 -0
- data/specs/fixtures/source/js/sprockets/app.js +2 -0
- data/specs/fixtures/source/js/sprockets/view.js.coffee +1 -0
- data/specs/fixtures/source/js/stitch/app.js +1 -0
- data/specs/fixtures/source/js/stitch/view.js.coffee +1 -0
- data/specs/fixtures/source/js/straight.js +8 -0
- data/specs/fixtures/source/js/test-coffee.js.coffee +1 -0
- data/specs/fixtures/source/layouts/site.layout.erb +1 -0
- data/specs/fixtures/source/layouts/sub.layout.erb +1 -0
- data/specs/fixtures/source/layouts/wrap.layout.erb +1 -0
- data/specs/fixtures/source/pages/_users-nested.html.erb +7 -0
- data/specs/fixtures/source/pages/docs/force-abs.html.erb +2 -0
- data/specs/fixtures/source/pages/docs/index.html.erb +2 -0
- data/specs/fixtures/source/partials/_post_entry.html.erb +4 -0
- data/specs/fixtures/source/partials/_provides_name.html.erb +1 -0
- data/specs/fixtures/source/partials/_user-params.html.erb +1 -0
- data/specs/fixtures/source/partials/_user.html.erb +1 -0
- data/specs/fixtures/source/partials/_user_sets_layout.html.erb +1 -0
- data/specs/fixtures/source/partials/hoisted-data.html.erb +6 -0
- data/specs/fixtures/source/partials/nested.html.erb +1 -0
- data/specs/fixtures/source/partials/params.html.erb +1 -0
- data/specs/fixtures/source/partials/with-layouts.html.erb +1 -0
- data/specs/fixtures/source/test-multi-procs.html.markdown.erb +3 -0
- data/specs/fixtures/source/test-nested-layout.html.erb +1 -0
- data/specs/fixtures/source/test-no-layout.html.erb +2 -0
- data/specs/fixtures/source/test-yamldoc.html.erb.yamldoc +4 -0
- data/specs/fixtures/source/test.html.erb +2 -0
- data/specs/hash_object_spec.rb +53 -8
- data/specs/render_spec.rb +10 -0
- data/specs/site_spec.rb +79 -0
- data/specs/spec_helper.rb +59 -0
- data/templates/blank/Gemfile +0 -4
- data/templates/blank/Gumdrop +180 -113
- data/templates/default/Gemfile +3 -8
- data/templates/default/Gumdrop +166 -95
- data/templates/default/ReadMe.md +14 -0
- data/templates/default/config.ru +1 -0
- data/templates/default/data/news/20120703.yamldoc +14 -0
- data/templates/default/data/news/20120704.yamldoc +8 -0
- data/templates/{backbone/source/feed.xml.builder.txt → default/source/feed.xml.builder} +4 -4
- data/templates/default/source/index.html.erb +10 -1
- data/templates/default/source/theme/layout/_sidebar.html +1 -0
- data/templates/{backbone/source/theme/templates/site.template.slim → default/source/theme/layout/site.layout.slim} +3 -3
- metadata +212 -63
- data/lib/gumdrop/context.rb +0 -135
- data/lib/gumdrop/data_manager.rb +0 -214
- data/lib/gumdrop/support/base_packager.rb +0 -60
- data/lib/gumdrop/support/callbacks.rb +0 -30
- data/lib/gumdrop/support/hash_object.rb +0 -22
- data/lib/gumdrop/view_helpers.rb +0 -25
- data/notes.md +0 -347
- data/specs/deferred_loader_spec.rb +0 -31
- data/specs/fixtures/expected/posts/post1.html +0 -1
- data/specs/fixtures/expected/posts/post1.js +0 -14
- data/specs/fixtures/expected/posts/post2.html +0 -5
- data/specs/fixtures/expected/sub/sub/sub/test.html +0 -5
- data/specs/fixtures/expected/sub/sub/sub/test2.html +0 -5
- data/specs/fixtures/expected/test.js +0 -14
- data/specs/fixtures/source/posts/post1.html.slim +0 -6
- data/specs/fixtures/source/posts/post1.js.coffee +0 -3
- data/specs/fixtures/source/posts/post2.html.erb +0 -5
- data/specs/fixtures/source/sub/sub/sub/test.html +0 -5
- data/specs/fixtures/source/sub/sub/sub/test2.html.erb +0 -5
- data/specs/fixtures/source/test.js.coffee +0 -4
- data/specs/fixtures/source/test.js.erb.coffee +0 -3
- data/templates/backbone/Gumdrop +0 -123
- data/templates/backbone/Rakefile +0 -38
- data/templates/backbone/app/app.js.coffee +0 -49
- data/templates/backbone/app/init.js.coffee +0 -10
- data/templates/backbone/app/models/.gitkeep +0 -0
- data/templates/backbone/app/utils/index.js.coffee +0 -27
- data/templates/backbone/app/views/home.js.coffee +0 -17
- data/templates/backbone/app/views/styles/home.scss +0 -8
- data/templates/backbone/app/views/templates/home.mustache +0 -2
- data/templates/backbone/config.ru +0 -20
- data/templates/backbone/lib/all.js.coffee +0 -18
- data/templates/backbone/lib/backbone.js +0 -1158
- data/templates/backbone/lib/hogan.js +0 -509
- data/templates/backbone/lib/jquery.js +0 -9266
- data/templates/backbone/lib/underscore.js +0 -981
- data/templates/backbone/powrc +0 -2
- data/templates/backbone/source/default.htaccess.erb +0 -27
- data/templates/backbone/source/favicon.ico +0 -0
- data/templates/backbone/source/index.html.erb +0 -2
- data/templates/backbone/source/theme/screen.css.sass +0 -9
- data/templates/backbone/source/theme/scripts/app.js.coffee +0 -4
- data/templates/backbone/source/theme/styles/_tools.scss +0 -434
- data/templates/backbone/source/theme/templates/app.template.slim +0 -14
- data/templates/default/Rakefile +0 -38
- data/templates/default/powrc +0 -2
- data/templates/default/source/default.htaccess.erb +0 -27
- data/templates/default/source/feed.xml.builder.txt +0 -23
- data/templates/default/source/theme/templates/site.template.slim +0 -33
data/lib/gumdrop/cli/internal.rb
CHANGED
@@ -14,29 +14,33 @@ module Gumdrop::CLI
|
|
14
14
|
method_option :env, default:'production', aliases:'-e'
|
15
15
|
method_option :assets, aliases:'-a', type: :array, desc:"List of assets to render."
|
16
16
|
method_option :quiet, default:false, aliases:'-q', type: :boolean
|
17
|
-
method_option :subdued, default:false, aliases:'-s', type: :boolean, desc:"Subdued output (....)"
|
18
17
|
method_option :resume, default:false, aliases:'-r', type: :boolean, desc:"Auto resume rendering after any errors"
|
19
|
-
|
20
|
-
|
18
|
+
method_option :force, default:false, aliases:'-f', type: :boolean, desc:"Ignore file checksums and create all files"
|
19
|
+
def build
|
20
|
+
if options[:quiet]
|
21
|
+
Gumdrop.configure do |c|
|
22
|
+
c.log_level= :warn
|
23
|
+
end
|
24
|
+
end
|
25
|
+
Gumdrop.run options.merge(mode:'build')
|
21
26
|
end
|
22
27
|
|
23
28
|
desc 'server', 'Run development server'
|
24
|
-
method_option :env, default:'production', aliases:'-e'
|
25
29
|
def server
|
30
|
+
Gumdrop.site.options = options.merge(mode:'build')
|
26
31
|
Gumdrop::Server
|
27
32
|
end
|
28
33
|
|
29
34
|
desc 'watch', "Watch filesystem for changes and recompile"
|
30
|
-
method_option :env, default:'production', aliases:'-e'
|
31
35
|
method_option :quiet, default:false, aliases:'-q', type: :boolean
|
32
36
|
method_option :subdued, default:false, aliases:'-s', type: :boolean, desc:"Subdued output (....)"
|
33
37
|
method_option :resume, default:false, aliases:'-r', type: :boolean, desc:"Auto resume rendering after any errors"
|
34
38
|
def watch
|
35
|
-
Gumdrop.run options
|
36
|
-
paths= [
|
37
|
-
paths <<
|
39
|
+
Gumdrop.run options.merge(mode:'merge')
|
40
|
+
paths= [Gumdrop.site.source_dir, Gumdrop.site.sitefile] #? Sitefile too?
|
41
|
+
paths << Gumdrop.site.data_dir if File.directory? Gumdrop.site.data_dir
|
38
42
|
Listen.to(*paths, :latency => 0.5) do |m, a, r|
|
39
|
-
|
43
|
+
Gumdrop.rebuild options.merge(mode:'merge')
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
@@ -50,26 +54,54 @@ module Gumdrop::CLI
|
|
50
54
|
else
|
51
55
|
say "Creating template: #{name}"
|
52
56
|
say " ~/.gumdrop/templates/#{name}"
|
53
|
-
site_root= Gumdrop.
|
57
|
+
site_root= Gumdrop.site.root
|
54
58
|
FileUtils.mkdir_p File.dirname(template_path)
|
55
|
-
FileUtils.cp_r
|
59
|
+
FileUtils.cp_r (site_root / "."), template_path
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
|
-
private
|
60
|
-
|
61
|
-
def home_path(name="")
|
62
|
-
File.expand_path File.join("~", ".gumdrop", name)
|
63
|
-
end
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
desc 'uris', "Print list of the uri that will be generated."
|
65
|
+
def uris
|
66
|
+
Gumdrop.configure do |c|
|
67
|
+
c.log_level= :error
|
67
68
|
end
|
69
|
+
Gumdrop.site.scan
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
+
say "Gumdrop found:"
|
72
|
+
say ""
|
73
|
+
Gumdrop.site.contents.keys.sort.each do |uri|
|
74
|
+
content= Gumdrop.site.contents[uri]
|
75
|
+
blackout= Gumdrop.site.in_blacklist?(uri) ? 'X' : ' '
|
76
|
+
generated= content.generated? ? '*' : ' '
|
77
|
+
binary= content.binary? ? '!' : ' '
|
78
|
+
say " #{blackout + generated + binary} #{content.uri}"
|
71
79
|
end
|
80
|
+
say ""
|
81
|
+
say "Legend:"
|
82
|
+
say " X = On on the blacklist"
|
83
|
+
say " * = Generated (not on fs)"
|
84
|
+
say " ! = Binary file"
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "version", "Displays Gumdrop version"
|
88
|
+
def version
|
89
|
+
say "Gumdrop v#{ Gumdrop::VERSION }"
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def home_path(name="")
|
96
|
+
File.expand_path "~" /".gumdrop" / name
|
97
|
+
end
|
98
|
+
|
99
|
+
def home_template_path(template)
|
100
|
+
home_path 'templates' / template
|
101
|
+
end
|
102
|
+
|
103
|
+
def local_path(name="")
|
104
|
+
"." / name
|
105
|
+
end
|
72
106
|
end
|
73
107
|
end
|
74
|
-
|
75
|
-
SITE= Gumdrop::Site.new Gumdrop.fetch_site_file unless defined?( SITE )
|
data/lib/gumdrop/cli.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gumdrop
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Allows addition of CLI commands from Gumdrop file:
|
6
|
+
#
|
7
|
+
# Gumdrop.cli do
|
8
|
+
# desc 'ping'
|
9
|
+
# method_option :loud, default:false
|
10
|
+
# def ping
|
11
|
+
# say options[:loud] ? 'PONG!' : 'pong'
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
def cli(&block)
|
16
|
+
CLI::Internal.class_eval &block
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/gumdrop/content.rb
CHANGED
@@ -1,36 +1,34 @@
|
|
1
|
-
|
2
1
|
module Gumdrop
|
3
|
-
|
2
|
+
|
3
|
+
# All content (layouts, partials, images, html, js css, etc) found in
|
4
|
+
# the source directory are represented as a Content object in memory
|
4
5
|
class Content
|
6
|
+
include Util::SiteAccess
|
5
7
|
|
6
|
-
|
7
|
-
LAYOUTLESS_EXTS= %w(.css .js .xml)
|
8
|
-
|
9
|
-
attr_reader :full_path, :path, :params, :site
|
8
|
+
attr_reader :source_path, :params
|
10
9
|
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
10
|
+
def initialize(source_path, generator=nil, &block)
|
11
|
+
@source_path= source_path
|
12
|
+
@generator= generator
|
13
|
+
@ignore= false
|
14
|
+
@block= block
|
15
|
+
@params= Util::HashObject.new
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
# TODO: Use a Pathname for all path operations instead of File.*
|
19
|
+
# Add support for relative_to and relative_from to
|
20
|
+
# ContentList (find?)
|
20
21
|
|
21
|
-
def
|
22
|
-
@
|
23
|
-
end
|
24
|
-
def ignore(state=true)
|
25
|
-
@ignored= state
|
22
|
+
def params=(value={})
|
23
|
+
@params.merge! value
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
29
|
-
@
|
26
|
+
def slug
|
27
|
+
@slug ||= uri.gsub('/', '-').gsub(ext, '')
|
30
28
|
end
|
31
29
|
|
32
30
|
def path
|
33
|
-
@path ||=
|
31
|
+
@path ||= _source_path
|
34
32
|
end
|
35
33
|
|
36
34
|
def level
|
@@ -38,11 +36,11 @@ module Gumdrop
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def source_filename
|
41
|
-
@source_filename ||= File.basename
|
39
|
+
@source_filename ||= File.basename source_path
|
42
40
|
end
|
43
41
|
|
44
42
|
def filename
|
45
|
-
@filename ||=
|
43
|
+
@filename ||= _target_filename
|
46
44
|
end
|
47
45
|
|
48
46
|
def type
|
@@ -54,92 +52,98 @@ module Gumdrop
|
|
54
52
|
end
|
55
53
|
|
56
54
|
def uri
|
57
|
-
@uri ||=
|
55
|
+
@uri ||= _uri
|
58
56
|
end
|
59
57
|
|
60
|
-
def
|
61
|
-
@
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
def binary?
|
59
|
+
@is_binary ||= begin
|
60
|
+
if generated? or has_block? or missing?
|
61
|
+
false
|
62
|
+
else
|
63
|
+
# from ptools
|
64
|
+
s = (File.read(source_path, File.stat(source_path).blksize) || "").split(//)
|
65
|
+
((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30
|
66
|
+
end
|
65
67
|
end
|
66
68
|
end
|
67
|
-
|
68
|
-
|
69
|
+
|
70
|
+
# Can I call #body() ?
|
71
|
+
def exists?
|
72
|
+
has_block? or File.exists? @source_path
|
69
73
|
end
|
70
|
-
|
71
|
-
def
|
72
|
-
|
73
|
-
if reset_context
|
74
|
-
default_layout= LAYOUTLESS_EXTS.include?(ext) ? nil : 'site'
|
75
|
-
context.reset_data 'current_depth'=>level, 'current_slug'=>slug, 'page'=>self, 'layout'=>default_layout, 'params'=>params
|
76
|
-
end
|
77
|
-
context.set_content self, locals
|
78
|
-
content= render_all(context)
|
79
|
-
return relativize content, context if ignore_layout
|
80
|
-
begin
|
81
|
-
layout= context.get_template()
|
82
|
-
while !layout.nil? and !layout.template.nil?
|
83
|
-
content = layout.template.render(context, content:content) { content }
|
84
|
-
layout= context.get_template()
|
85
|
-
end
|
86
|
-
rescue => ex
|
87
|
-
raise StandardError, "Layout: #{ex.to_s}", ex.backtrace
|
88
|
-
end
|
89
|
-
relativize content, context
|
90
|
-
rescue => ex
|
91
|
-
raise StandardError, "Rendering exception: #{ex.to_s}", ex.backtrace
|
74
|
+
|
75
|
+
def missing?
|
76
|
+
!exists?
|
92
77
|
end
|
93
|
-
|
94
|
-
def
|
95
|
-
|
96
|
-
site.report " rendering: #{uri}"
|
97
|
-
output= render(context)
|
98
|
-
filters.each {|f| output= f.call(output, self) }
|
99
|
-
File.open output_path, 'w' do |f|
|
100
|
-
f.write output
|
101
|
-
end
|
78
|
+
|
79
|
+
def generated?
|
80
|
+
!@generator.nil?
|
102
81
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
do_copy= if File.exists? output
|
107
|
-
!FileUtils.identical? @full_path, output
|
108
|
-
else
|
109
|
-
true
|
110
|
-
end
|
111
|
-
if do_copy
|
112
|
-
site.report " copying: #{uri}"
|
113
|
-
FileUtils.cp_r @full_path, output, opts
|
114
|
-
else
|
115
|
-
site.report " (same): #{uri}"
|
116
|
-
end
|
82
|
+
|
83
|
+
def has_block?
|
84
|
+
!@block.nil?
|
117
85
|
end
|
118
|
-
|
119
|
-
def
|
120
|
-
|
121
|
-
File.new(@full_path).mtime
|
122
|
-
else
|
123
|
-
Time.now
|
124
|
-
end
|
86
|
+
|
87
|
+
def partial?
|
88
|
+
source_filename[0] == "_"
|
125
89
|
end
|
126
|
-
|
127
|
-
def
|
128
|
-
|
90
|
+
|
91
|
+
def layout?
|
92
|
+
ext == '.layout'
|
129
93
|
end
|
130
94
|
|
131
|
-
def
|
132
|
-
|
95
|
+
def generator?
|
96
|
+
ext == '.generator'
|
133
97
|
end
|
134
|
-
|
98
|
+
|
99
|
+
def body # Memoize this?
|
100
|
+
@body ||= case
|
101
|
+
when has_block?
|
102
|
+
@block.call
|
103
|
+
when missing?, binary?
|
104
|
+
nil
|
105
|
+
else
|
106
|
+
File.read @source_path
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def mtime
|
111
|
+
@mtime ||= if exists? and !generated?
|
112
|
+
File.new(@source_path).mtime
|
113
|
+
else
|
114
|
+
Time.now
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
135
118
|
def to_s
|
136
119
|
uri
|
137
120
|
end
|
138
|
-
|
121
|
+
|
122
|
+
def method_missing(sym, *args, &block)
|
123
|
+
if params.has_key? sym
|
124
|
+
params[sym]
|
125
|
+
else
|
126
|
+
super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
139
130
|
private
|
140
131
|
|
141
|
-
def
|
142
|
-
|
132
|
+
def _uri
|
133
|
+
# Do I need to do anything for windoze here to make sure
|
134
|
+
# the slashes are / and not \ ?
|
135
|
+
uri= File.dirname(path) / filename
|
136
|
+
if uri.starts_with? './'
|
137
|
+
uri[2..-1]
|
138
|
+
elsif uri.starts_with? '/'
|
139
|
+
uri[1..-1]
|
140
|
+
else
|
141
|
+
uri
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def _source_path
|
146
|
+
path= @source_path.gsub site.source_path, ''
|
143
147
|
if path[0] == '/'
|
144
148
|
path[1..-1]
|
145
149
|
else
|
@@ -147,61 +151,120 @@ module Gumdrop
|
|
147
151
|
end
|
148
152
|
end
|
149
153
|
|
150
|
-
def
|
154
|
+
def _target_filename
|
151
155
|
filename_parts= source_filename.split('.')
|
152
156
|
ext= filename_parts.pop
|
153
|
-
while !
|
157
|
+
while !Renderer.for(ext).nil?
|
154
158
|
ext= filename_parts.pop
|
155
159
|
end
|
156
160
|
filename_parts << ext # push the last file ext back on there!
|
157
|
-
filename_parts.join('.')
|
158
|
-
|
159
|
-
|
160
|
-
def render_all(ctx)
|
161
|
-
if generated or !File.exists?(@full_path)
|
162
|
-
content= template.render(ctx)
|
161
|
+
fname= filename_parts.join('.')
|
162
|
+
if partial?
|
163
|
+
fname[1..-1]
|
163
164
|
else
|
164
|
-
|
165
|
-
exts= source_filename.gsub filename, ''
|
166
|
-
exts.split('.').reverse.each do |ext|
|
167
|
-
unless ext.blank?
|
168
|
-
templateClass= Tilt[".#{ext}"]
|
169
|
-
template= templateClass.new(@full_path) do
|
170
|
-
content
|
171
|
-
end
|
172
|
-
content= template.render(ctx)
|
173
|
-
end
|
174
|
-
end
|
165
|
+
fname
|
175
166
|
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.path_match?(path, pattern)
|
170
|
+
File.fnmatch pattern, path, File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class ContentList < Hash
|
175
|
+
|
176
|
+
def create(path, generator=nil, &block)
|
177
|
+
content= Content.new path, generator, &block
|
178
|
+
add content #, path
|
179
|
+
end
|
180
|
+
|
181
|
+
def add(content, uri=nil)
|
182
|
+
uri= content.uri if uri.nil?
|
183
|
+
self[uri]= content
|
176
184
|
content
|
177
185
|
end
|
178
186
|
|
179
|
-
def
|
180
|
-
uri=
|
181
|
-
|
182
|
-
uri[2..-1]
|
183
|
-
else
|
184
|
-
uri
|
185
|
-
end
|
187
|
+
def remove(content)
|
188
|
+
uri = content.is_a? String ? content : content.uri
|
189
|
+
self.delete uri
|
186
190
|
end
|
187
191
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
192
|
+
# Returns Array of content objects
|
193
|
+
def all(pattern=nil)
|
194
|
+
pattern.nil? ? values : find(pattern)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Scans the filenames (keys) and uses fnmatch to find maches
|
198
|
+
def find(pattern)
|
199
|
+
patterns= [pattern].flatten
|
200
|
+
contents=[]
|
201
|
+
self.each_pair do |path, content|
|
202
|
+
patterns.each do |pattern|
|
203
|
+
contents << content if Content.path_match? path, pattern
|
200
204
|
end
|
201
205
|
end
|
202
|
-
|
206
|
+
contents
|
207
|
+
end
|
208
|
+
|
209
|
+
def get(key)
|
210
|
+
self[key]
|
211
|
+
end
|
212
|
+
|
213
|
+
def first(pattern)
|
214
|
+
find(pattern).first
|
203
215
|
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
# Keeps a ref to content at full path and just the basename
|
220
|
+
class SpecialContentList < ContentList
|
204
221
|
|
222
|
+
def initialize(default_ext=false)#, *args)
|
223
|
+
@ext= default_ext || ".html" # ???
|
224
|
+
super()
|
225
|
+
end
|
226
|
+
|
227
|
+
def add(content, uri=nil)
|
228
|
+
uri= content.uri if uri.nil?
|
229
|
+
buri = File.basename uri
|
230
|
+
self[uri]= content
|
231
|
+
self[buri]= content
|
232
|
+
content
|
233
|
+
end
|
234
|
+
|
235
|
+
def remove(content)
|
236
|
+
uri = content.is_a? String ? content : content.uri
|
237
|
+
self.delete uri
|
238
|
+
self.delete File.basename uri
|
239
|
+
end
|
240
|
+
|
241
|
+
# Find isn't fuzzy for Special Content. It looks for full
|
242
|
+
# uri or the uri's basename, optionally tacking on @ext
|
243
|
+
def find(uri)
|
244
|
+
_try_variations_of(uri) do |path|
|
245
|
+
content= get path
|
246
|
+
return [content] unless content.nil?
|
247
|
+
end unless uri.nil?
|
248
|
+
[]
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
def _try_variations_of(uri)
|
254
|
+
# try the uri
|
255
|
+
yield uri
|
256
|
+
# plus default ext
|
257
|
+
yield uri + @ext
|
258
|
+
urip= Pathname.new uri
|
259
|
+
# just the filename
|
260
|
+
yield urip.basename
|
261
|
+
# filename plus default extension
|
262
|
+
yield urip.basename + @ext
|
263
|
+
# filename minus the ext
|
264
|
+
yield urip.basename.to_s.gsub urip.extname, ''
|
265
|
+
# uri minus ext
|
266
|
+
yield uri.gsub urip.extname, ''
|
267
|
+
end
|
268
|
+
|
205
269
|
end
|
206
|
-
|
207
270
|
end
|