sitefs 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +101 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/TODO.md +8 -0
- data/bin/sitefs +96 -0
- data/inline-site/_layout.html.erb +30 -0
- data/inline-site/_layout.md.html.erb +3 -0
- data/inline-site/advanced-md.page.md +18 -0
- data/inline-site/dir/_layout.md.html.erb +3 -0
- data/inline-site/dir/sub1/_layout.html.erb +7 -0
- data/inline-site/dir/sub1/sub2/deep-page.page.md +8 -0
- data/inline-site/ears.png +0 -0
- data/inline-site/gallery/IMG_4371.jpg +0 -0
- data/inline-site/gallery/Screen Shot 2016-04-21 at 5.57.53 PM.png +0 -0
- data/inline-site/gallery/Screen Shot 2016-04-25 at 2.06.46 PM.png +0 -0
- data/inline-site/gallery/Screen Shot 2016-04-27 at 9.31.28 PM.png +0 -0
- data/inline-site/gallery/_gallery.html.erb +1 -0
- data/inline-site/gallery/_permalink.html.erb +1 -0
- data/inline-site/gallery/photos.page.rb +23 -0
- data/inline-site/index.html +41 -0
- data/inline-site/index.page.html.erb +1 -0
- data/inline-site/single-markdown.page.md +12 -0
- data/inline-site/styles/_helper.scss +1 -0
- data/inline-site/styles/app.css +1 -0
- data/inline-site/styles/app.scss +5 -0
- data/inline-site/tagged/_tag_layout.html.erb +7 -0
- data/inline-site/tagged/public.tag-page.rb +8 -0
- data/lib/sitefs/attribute_set.rb +93 -0
- data/lib/sitefs/command_config.rb +79 -0
- data/lib/sitefs/dsl_context.rb +49 -0
- data/lib/sitefs/file_action.rb +155 -0
- data/lib/sitefs/file_action_set.rb +51 -0
- data/lib/sitefs/file_registry.rb +61 -0
- data/lib/sitefs/handler.rb +46 -0
- data/lib/sitefs/handlers/markdown.rb +102 -0
- data/lib/sitefs/handlers/noop.rb +15 -0
- data/lib/sitefs/handlers/ruby_gen.rb +33 -0
- data/lib/sitefs/handlers/scss.rb +63 -0
- data/lib/sitefs/handlers/single_erb.rb +49 -0
- data/lib/sitefs/handlers/tag_page.rb +11 -0
- data/lib/sitefs/handlers.rb +6 -0
- data/lib/sitefs/html_pipelines.rb +95 -0
- data/lib/sitefs/layout_type.rb +16 -0
- data/lib/sitefs/manifest.rb +98 -0
- data/lib/sitefs/manifest_file.rb +64 -0
- data/lib/sitefs/page.rb +44 -0
- data/lib/sitefs/page_render.rb +6 -0
- data/lib/sitefs/path_helper.rb +31 -0
- data/lib/sitefs/render_context.rb +31 -0
- data/lib/sitefs/render_result.rb +16 -0
- data/lib/sitefs/renderer.rb +65 -0
- data/lib/sitefs/renderer_pipeline.rb +94 -0
- data/lib/sitefs/servlet.rb +31 -0
- data/lib/sitefs/tag_page_dsl_context.rb +13 -0
- data/lib/sitefs/version.rb +3 -0
- data/lib/sitefs/walker.rb +94 -0
- data/lib/sitefs/watcher.rb +85 -0
- data/lib/sitefs.rb +19 -0
- data/sitefs.gemspec +47 -0
- data/test-walker.rb +20 -0
- metadata +335 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
require 'html/pipeline'
|
4
|
+
require 'html/pipeline/rouge_filter'
|
5
|
+
|
6
|
+
module Sitefs
|
7
|
+
class TitleDeterminer < HTML::Pipeline::Filter
|
8
|
+
def call
|
9
|
+
if node = doc.css('h1:first-child').first
|
10
|
+
text = node.text.strip
|
11
|
+
|
12
|
+
result[:title] = node.text unless text.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
if node = doc.css('h1:first-child + h2').first
|
16
|
+
text = node.text.strip
|
17
|
+
|
18
|
+
result[:subtitle] = node.text unless text.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
if node = doc.css('h2 + p:nth-of-type(1)').first
|
22
|
+
text = node.text.strip
|
23
|
+
|
24
|
+
result[:description] = node.text[0..199] unless text.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
doc
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class RelativePathFilter < HTML::Pipeline::Filter
|
32
|
+
def call
|
33
|
+
base_path = context[:image_base_path] || context[:base_path]
|
34
|
+
context_path = context[:context_path]
|
35
|
+
|
36
|
+
unless base_path || context_path
|
37
|
+
return doc
|
38
|
+
end
|
39
|
+
|
40
|
+
doc.search('img').each do |img|
|
41
|
+
next if img['src'].nil?
|
42
|
+
|
43
|
+
src = img['src'].strip
|
44
|
+
|
45
|
+
if src.start_with?('/') || src.start_with?('http')
|
46
|
+
elsif context_path
|
47
|
+
src = File.join(context_path, src)
|
48
|
+
end
|
49
|
+
|
50
|
+
if base_path && src.start_with?('/')
|
51
|
+
src = URI.join(base_path, src).to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
img['src'] = src
|
55
|
+
end
|
56
|
+
doc
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
module HtmlPipelines
|
63
|
+
extend self
|
64
|
+
|
65
|
+
def content
|
66
|
+
HTML::Pipeline.new([
|
67
|
+
TitleDeterminer,
|
68
|
+
HTML::Pipeline::RougeFilter,
|
69
|
+
])
|
70
|
+
end
|
71
|
+
|
72
|
+
def markdown
|
73
|
+
HTML::Pipeline.new(
|
74
|
+
[
|
75
|
+
HTML::Pipeline::MarkdownFilter,
|
76
|
+
TitleDeterminer,
|
77
|
+
HTML::Pipeline::AutolinkFilter,
|
78
|
+
HTML::Pipeline::RougeFilter,
|
79
|
+
], {
|
80
|
+
gfm: true,
|
81
|
+
})
|
82
|
+
end
|
83
|
+
|
84
|
+
def finishing str, **opts
|
85
|
+
|
86
|
+
filters = [
|
87
|
+
RelativePathFilter,
|
88
|
+
HTML::Pipeline::AutolinkFilter,
|
89
|
+
HTML::Pipeline::RougeFilter,
|
90
|
+
]
|
91
|
+
|
92
|
+
HTML::Pipeline.new(filters, **opts).call(str)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Sitefs
|
4
|
+
MANIFEST_FILENAME = '.sitefs-manifest.json'
|
5
|
+
|
6
|
+
class Manifest
|
7
|
+
def initialize root_path
|
8
|
+
@root_path = root_path
|
9
|
+
|
10
|
+
if File.exist? manifest_path
|
11
|
+
@manifest = ManifestFile.from_file manifest_path
|
12
|
+
else
|
13
|
+
@manifest = {}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def clean!
|
18
|
+
@manifest = {}
|
19
|
+
save!
|
20
|
+
end
|
21
|
+
|
22
|
+
def manifest_path
|
23
|
+
File.join @root_path, MANIFEST_FILENAME
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve_path path
|
27
|
+
path.sub(@root_path, '').sub(/^\//, '').to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def [] path
|
31
|
+
@manifest[resolve_path(path)]
|
32
|
+
end
|
33
|
+
|
34
|
+
def []= path, value
|
35
|
+
@manifest[resolve_path(path)] = ManifestFile.ensure(value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
@manifest
|
40
|
+
end
|
41
|
+
|
42
|
+
def as_json *opts
|
43
|
+
to_h.inject({}) do |h, (k,v)|
|
44
|
+
h[k] = v unless v.nil?
|
45
|
+
h
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_json *opts
|
50
|
+
as_json(*opts).to_json(*opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
def save!
|
54
|
+
File.open(manifest_path, 'w') { |f| f.puts JSON.pretty_generate(as_json) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def delete_generated
|
58
|
+
@manifest.each do |path, file|
|
59
|
+
if file[:'generated_at']
|
60
|
+
full_path = File.join(@root_path, path.to_s)
|
61
|
+
if File.exist? full_path
|
62
|
+
File.delete full_path
|
63
|
+
end
|
64
|
+
file[:'generated_at'] = nil
|
65
|
+
puts "Deleting: #{path}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
save!
|
70
|
+
end
|
71
|
+
|
72
|
+
ManifestFile::ALLOWED_KEYS.each do |key|
|
73
|
+
if key[-3..-1] == '_at'
|
74
|
+
verb = key[0...-3]
|
75
|
+
define_method "#{verb}_path" do |path|
|
76
|
+
now = Time.now
|
77
|
+
send "set_path_#{key}", path, now
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method "#{verb}?" do |path|
|
81
|
+
!!send("path_#{key}", path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
define_method "path_#{key}" do |path|
|
86
|
+
@manifest[resolve_path(path)] && @manifest[resolve_path(path)][key]
|
87
|
+
end
|
88
|
+
|
89
|
+
define_method "set_path_#{key}" do |path, value|
|
90
|
+
@manifest[resolve_path(path)] ||= ManifestFile.new
|
91
|
+
@manifest[resolve_path(path)][key] = value
|
92
|
+
save!
|
93
|
+
@manifest[resolve_path(path)]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class Sitefs::ManifestFile
|
2
|
+
ALLOWED_KEYS = %i{generated_at uploaded_at uploaded_hash content_type}
|
3
|
+
|
4
|
+
def initialize **attrs
|
5
|
+
@attributes = attrs
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_h
|
9
|
+
ALLOWED_KEYS.inject({}) do |h, key|
|
10
|
+
h[key] = @attributes[key] if @attributes[key]
|
11
|
+
h
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json *opts
|
16
|
+
hsh = to_h
|
17
|
+
if hsh.keys == [:content_type]
|
18
|
+
nil
|
19
|
+
else
|
20
|
+
hsh
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json *opts
|
25
|
+
as_json(*opts).to_json(*opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
def [] key
|
29
|
+
raise ArgumentError.new('invalid key') unless ALLOWED_KEYS.include?(key)
|
30
|
+
@attributes[key]
|
31
|
+
end
|
32
|
+
|
33
|
+
def []= key, value
|
34
|
+
raise ArgumentError.new('invalid key') unless ALLOWED_KEYS.include?(key)
|
35
|
+
|
36
|
+
if value.nil?
|
37
|
+
@attributes.delete key
|
38
|
+
else
|
39
|
+
@attributes[key] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
def ensure val
|
45
|
+
if val.is_a?(self)
|
46
|
+
return val
|
47
|
+
elsif val.respond_to? :to_h
|
48
|
+
return new(**val.to_h)
|
49
|
+
else
|
50
|
+
raise ArgumentError.new('can only convert hashes to ' + self.to_s)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def from_file file
|
55
|
+
content = File.read file
|
56
|
+
raw = JSON.parse content, symbolize_names: true
|
57
|
+
|
58
|
+
raw.inject({}) do |h, (k,v)|
|
59
|
+
h[k] = new **v if k && v
|
60
|
+
h
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/sitefs/page.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
class Sitefs::Page
|
2
|
+
class << self
|
3
|
+
def attribute_key *keys
|
4
|
+
keys.each do |key|
|
5
|
+
define_method(key) { attributes[key.to_s] }
|
6
|
+
define_method("#{key}=") { |v| attributes[key.to_s] = v }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :path, :attributes
|
12
|
+
attribute_key :title, :subtitle, :description, :tags, :published_at
|
13
|
+
attr_accessor :_rendering_template
|
14
|
+
|
15
|
+
def initialize path_helper, attributes = nil
|
16
|
+
@attributes = attributes
|
17
|
+
@path_helper = path_helper
|
18
|
+
@tags = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def public_tags
|
22
|
+
tags.select {|tag| !tag.start_with?('_')}
|
23
|
+
end
|
24
|
+
|
25
|
+
def href
|
26
|
+
@path_helper.min_href_for @path
|
27
|
+
end
|
28
|
+
|
29
|
+
def href= href
|
30
|
+
@path = @path_helper.pathname_for href
|
31
|
+
end
|
32
|
+
|
33
|
+
def expanded_path
|
34
|
+
File.join(@path_helper.root_path, path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def attributes
|
38
|
+
@attributes ||= AttributeSet.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def [] key
|
42
|
+
attributes[key]
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Sitefs::PathHelper
|
2
|
+
attr_reader :root_path, :source_file
|
3
|
+
|
4
|
+
def initialize root_path, source_file
|
5
|
+
@root_path = File.expand_path root_path
|
6
|
+
@source_file = File.expand_path source_file, @root_path
|
7
|
+
end
|
8
|
+
|
9
|
+
def pathname
|
10
|
+
source_file.sub(File.join(root_path, ''), '')
|
11
|
+
end
|
12
|
+
|
13
|
+
def pathname_for href
|
14
|
+
return nil unless href
|
15
|
+
|
16
|
+
dir = File.dirname source_file
|
17
|
+
|
18
|
+
File.expand_path(href, dir).sub(root_path, '')
|
19
|
+
end
|
20
|
+
|
21
|
+
def min_href_for path
|
22
|
+
return nil unless path
|
23
|
+
|
24
|
+
dir = File.join(File.dirname(source_file), '')
|
25
|
+
File.join(root_path, path, ).sub(dir, '').sub(root_path, '')
|
26
|
+
end
|
27
|
+
|
28
|
+
def full_path_for href
|
29
|
+
File.join(root_path, pathname_for(href))
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Sitefs::RenderContext
|
2
|
+
attr_reader :current_page
|
3
|
+
|
4
|
+
def initialize(registry, current_page: nil)
|
5
|
+
@registry, @current_page = registry, current_page
|
6
|
+
|
7
|
+
@content_for = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def _set_content_for key, val
|
11
|
+
@content_for[key] = val
|
12
|
+
end
|
13
|
+
|
14
|
+
def _get_content_for key
|
15
|
+
@content_for[key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def public_tags
|
19
|
+
@registry ? @registry.public_tags : []
|
20
|
+
end
|
21
|
+
|
22
|
+
def pages_tagged tag_str, all: false
|
23
|
+
@registry ? @registry.pages_tagged(tag_str, all: all) : []
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def nil
|
28
|
+
@nil ||= new(nil)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sitefs
|
2
|
+
class RenderResult
|
3
|
+
attr_reader :text
|
4
|
+
def initialize text:, layout_type: LayoutType.default
|
5
|
+
@text, @layout_type = text, layout_type
|
6
|
+
end
|
7
|
+
|
8
|
+
def hit_root?
|
9
|
+
@layout_type == LayoutType.root
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Sitefs
|
4
|
+
class Renderer
|
5
|
+
attr_reader :context
|
6
|
+
attr_accessor :layout_type
|
7
|
+
|
8
|
+
def initialize content
|
9
|
+
@erb = ERB.new(content, nil, nil, '@_out_buf')
|
10
|
+
@layout_type = LayoutType.default
|
11
|
+
@content_for = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_root!
|
15
|
+
@layout_type = LayoutType.root
|
16
|
+
|
17
|
+
if @context.respond_to? :hit_root!
|
18
|
+
@context.hit_root!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_root?
|
23
|
+
@layout_type == LayoutType.root
|
24
|
+
end
|
25
|
+
|
26
|
+
def render context = nil
|
27
|
+
@context = context
|
28
|
+
__result = @erb.result(binding)
|
29
|
+
@context = nil
|
30
|
+
|
31
|
+
RenderResult.new(text: __result, layout_type: @layout_type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def content_for key, txt=nil, &block
|
35
|
+
if block
|
36
|
+
@_out_buf, _buf_was = '', @_out_buf
|
37
|
+
block.call
|
38
|
+
result = eval('@_out_buf', block.binding)
|
39
|
+
@_out_buf = _buf_w
|
40
|
+
else
|
41
|
+
result = txt
|
42
|
+
end
|
43
|
+
|
44
|
+
@context._set_content_for key, (result.strip)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
render
|
49
|
+
end
|
50
|
+
|
51
|
+
def title
|
52
|
+
current_page && current_page.title
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing name, *args, &blk
|
56
|
+
if context.respond_to? name
|
57
|
+
context.send(name, *args, &blk)
|
58
|
+
elsif RenderContext.nil.respond_to? name
|
59
|
+
RenderContext.nil.send(name, *args, &blk)
|
60
|
+
else
|
61
|
+
raise "Rendering context respond to #{name}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class Sitefs::RendererPipeline
|
2
|
+
attr_reader :renderers
|
3
|
+
|
4
|
+
def initialize *args
|
5
|
+
@renderers = args
|
6
|
+
end
|
7
|
+
|
8
|
+
def << renderer
|
9
|
+
if renderer.respond_to?(:renderers)
|
10
|
+
renderer.renderers.each do |renderer|
|
11
|
+
self << renderer
|
12
|
+
end
|
13
|
+
else
|
14
|
+
@renderers << renderer
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def render context=nil
|
19
|
+
renderers.reverse.reduce('') do |prev, renderer|
|
20
|
+
renderer = ensure_renderer renderer
|
21
|
+
|
22
|
+
result = renderer.render(context) do |arg=nil|
|
23
|
+
if arg
|
24
|
+
if context.respond_to?(:_get_content_for)
|
25
|
+
value = context._get_content_for arg
|
26
|
+
else
|
27
|
+
value = "<!-- No context, so couldn't render content for #{arg} -->"
|
28
|
+
end
|
29
|
+
else
|
30
|
+
value = prev
|
31
|
+
end
|
32
|
+
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
if result.hit_root?
|
37
|
+
break result.to_s
|
38
|
+
else
|
39
|
+
next result.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def ensure_renderer renderer
|
45
|
+
if !renderer.respond_to?(:render)
|
46
|
+
if renderer.is_a?(String)
|
47
|
+
renderer = Renderer.new(renderer)
|
48
|
+
else
|
49
|
+
throw "#{renderer.inspect} is not a supported renderer"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
renderer
|
54
|
+
end
|
55
|
+
|
56
|
+
class << self
|
57
|
+
def possible_files_for root_path:, source_file:, layout_name: '_layout.html.erb'
|
58
|
+
root_path = File.join(root_path,'')
|
59
|
+
|
60
|
+
files = []
|
61
|
+
|
62
|
+
begin
|
63
|
+
dir = File.join(File.dirname(source_file), '')
|
64
|
+
|
65
|
+
look_at = File.join(dir, layout_name)
|
66
|
+
|
67
|
+
if File.exist? look_at
|
68
|
+
files << look_at
|
69
|
+
end
|
70
|
+
|
71
|
+
source_file = dir
|
72
|
+
end until dir === root_path || root_path.length >= dir.length # safety to ensure the equality doesn't miss
|
73
|
+
|
74
|
+
files
|
75
|
+
end
|
76
|
+
|
77
|
+
def for content_text: nil, **args
|
78
|
+
layouts = possible_files_for **args
|
79
|
+
|
80
|
+
layout_text = layouts.reverse.map do |layout_file|
|
81
|
+
File.read(layout_file)
|
82
|
+
end
|
83
|
+
|
84
|
+
pipeline = new *layout_text
|
85
|
+
|
86
|
+
if content_text
|
87
|
+
pipeline << content_text
|
88
|
+
end
|
89
|
+
|
90
|
+
pipeline
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "webrick"
|
2
|
+
|
3
|
+
class Sitefs::Servlet < WEBrick::HTTPServlet::FileHandler
|
4
|
+
def initialize server, root, callbacks
|
5
|
+
@sitefs_config = server.config[:SitefsConfig]
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def search_file(req, res, basename)
|
10
|
+
case @sitefs_config.index_format
|
11
|
+
when 'github', 'standard'
|
12
|
+
# /file.* > /file/index.html > /file.html
|
13
|
+
super || super(req, res, "#{basename}.html")
|
14
|
+
else
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def do_GET(req, res)
|
20
|
+
rtn = super
|
21
|
+
|
22
|
+
content_type = @sitefs_config.manifest.path_content_type res.filename
|
23
|
+
res['content-type'] = content_type if content_type
|
24
|
+
|
25
|
+
# Disable caching to make dev easier
|
26
|
+
res['Cache-Control'] = "private, max-age=0, proxy-revalidate, " \
|
27
|
+
"no-store, no-cache, must-revalidate"
|
28
|
+
|
29
|
+
rtn
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
class Sitefs::TagPageDslContext < Sitefs::DslContext
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :@registry, :pages, :public_tags, :pages_tagged
|
6
|
+
|
7
|
+
def initialize registry, path_helper
|
8
|
+
raise "registry required for #{self.class}" unless registry.is_a? FileRegistry
|
9
|
+
|
10
|
+
super path_helper
|
11
|
+
@registry = registry
|
12
|
+
end
|
13
|
+
end
|