yuzu 0.2.1.pre
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/.document +5 -0
- data/.yardopts +7 -0
- data/ChangeLog.md +8 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.md +52 -0
- data/Rakefile +62 -0
- data/bin/yuzu +17 -0
- data/docs/About.md +19 -0
- data/docs/GettingStarted.md +48 -0
- data/docs/Reference.md +97 -0
- data/lib/helpers/object.rb +19 -0
- data/lib/helpers/path.rb +296 -0
- data/lib/helpers/string.rb +35 -0
- data/lib/helpers/system_checks.rb +10 -0
- data/lib/helpers/url.rb +64 -0
- data/lib/html/base.rb +187 -0
- data/lib/uploader/base.rb +59 -0
- data/lib/uploader/config.rb +19 -0
- data/lib/uploader/filesystem_service.rb +72 -0
- data/lib/uploader/ftp_service.rb +90 -0
- data/lib/uploader/s3_service.rb +135 -0
- data/lib/uploader/service.rb +57 -0
- data/lib/uploader/suppressor.rb +25 -0
- data/lib/yuzu.rb +6 -0
- data/lib/yuzu/argparse.rb +60 -0
- data/lib/yuzu/command.rb +104 -0
- data/lib/yuzu/commands/base.rb +150 -0
- data/lib/yuzu/commands/create.rb +68 -0
- data/lib/yuzu/commands/generate.rb +95 -0
- data/lib/yuzu/commands/help.rb +20 -0
- data/lib/yuzu/commands/preview.rb +58 -0
- data/lib/yuzu/commands/publish.rb +43 -0
- data/lib/yuzu/commands/stage.rb +62 -0
- data/lib/yuzu/commands/watch.rb +70 -0
- data/lib/yuzu/content/blog_post.rb +45 -0
- data/lib/yuzu/content/sample_project.rb +130 -0
- data/lib/yuzu/core/config.rb +154 -0
- data/lib/yuzu/core/layout.rb +85 -0
- data/lib/yuzu/core/paginated_file.rb +69 -0
- data/lib/yuzu/core/registrar.rb +32 -0
- data/lib/yuzu/core/siteroot.rb +57 -0
- data/lib/yuzu/core/template.rb +158 -0
- data/lib/yuzu/core/updater.rb +123 -0
- data/lib/yuzu/core/visitor.rb +44 -0
- data/lib/yuzu/core/website_base.rb +150 -0
- data/lib/yuzu/core/website_file.rb +270 -0
- data/lib/yuzu/core/website_folder.rb +176 -0
- data/lib/yuzu/filters/base.rb +86 -0
- data/lib/yuzu/filters/catalog.rb +248 -0
- data/lib/yuzu/filters/categories.rb +58 -0
- data/lib/yuzu/filters/currentpath.rb +35 -0
- data/lib/yuzu/filters/description.rb +16 -0
- data/lib/yuzu/filters/extension.rb +16 -0
- data/lib/yuzu/filters/images.rb +32 -0
- data/lib/yuzu/filters/linkroot.rb +35 -0
- data/lib/yuzu/filters/post_date.rb +45 -0
- data/lib/yuzu/filters/post_title.rb +66 -0
- data/lib/yuzu/filters/post_title_removed.rb +28 -0
- data/lib/yuzu/filters/sidebar.rb +26 -0
- data/lib/yuzu/filters/template.rb +16 -0
- data/lib/yuzu/generators/base.rb +44 -0
- data/lib/yuzu/generators/category_folders.rb +91 -0
- data/lib/yuzu/generators/index.rb +108 -0
- data/lib/yuzu/generators/paginate.rb +136 -0
- data/lib/yuzu/postprocessors/all_categories.rb +48 -0
- data/lib/yuzu/postprocessors/base.rb +34 -0
- data/lib/yuzu/postprocessors/contents_without_first_paragraph.rb +20 -0
- data/lib/yuzu/postprocessors/excerpt.rb +23 -0
- data/lib/yuzu/postprocessors/first_paragraph.rb +16 -0
- data/lib/yuzu/postprocessors/pagination.rb +35 -0
- data/lib/yuzu/postprocessors/recent_posts.rb +27 -0
- data/lib/yuzu/postprocessors/thumbnails.rb +48 -0
- data/lib/yuzu/preprocessors/base.rb +71 -0
- data/lib/yuzu/preprocessors/insert_contents.rb +57 -0
- data/lib/yuzu/renderers/base.rb +23 -0
- data/lib/yuzu/renderers/breadcrumb.rb +163 -0
- data/lib/yuzu/renderers/gallery.rb +24 -0
- data/lib/yuzu/renderers/title.rb +21 -0
- data/lib/yuzu/translators/base.rb +57 -0
- data/lib/yuzu/translators/markdown.rb +21 -0
- data/lib/yuzu/translators/plaintext.rb +17 -0
- data/lib/yuzu/version.rb +12 -0
- data/resources/config/compass.rb +6 -0
- data/resources/config/yuzu.yml +166 -0
- data/resources/git/post-commit +42 -0
- data/resources/sample_content/introduction/_snippets/about_insert_contents.md +3 -0
- data/resources/sample_content/introduction/about.md +6 -0
- data/resources/sample_content/introduction/advanced-posts.md +18 -0
- data/resources/sample_content/introduction/blog/blog-folder-is-special.md +8 -0
- data/resources/sample_content/introduction/getting-started.md +14 -0
- data/resources/sample_content/introduction/index.md +6 -0
- data/resources/sample_content/introduction/sample-post.md +13 -0
- data/resources/sample_projects.yml +7 -0
- data/resources/themes/minimal/_sass/print.sass +0 -0
- data/resources/themes/minimal/_sass/screen.sass +81 -0
- data/resources/themes/minimal/_templates/_block.haml +4 -0
- data/resources/themes/minimal/_templates/_blog.haml +3 -0
- data/resources/themes/minimal/_templates/_footer.haml +2 -0
- data/resources/themes/minimal/_templates/_gallery.haml +25 -0
- data/resources/themes/minimal/_templates/_head.haml +12 -0
- data/resources/themes/minimal/_templates/_header.haml +1 -0
- data/resources/themes/minimal/_templates/_menu.haml +6 -0
- data/resources/themes/minimal/_templates/blog.haml +21 -0
- data/resources/themes/minimal/_templates/generic.haml +26 -0
- data/resources/themes/minimal/_templates/home.haml +15 -0
- data/resources/themes/minimal/_templates/index.haml +21 -0
- data/resources/themes/minimal/css/print.css +0 -0
- data/resources/themes/minimal/css/screen.css +133 -0
- data/resources/themes/minimal/img/favicon.png +0 -0
- data/resources/yard/default/fulldoc/html/css/common.css +16 -0
- data/test/helper.rb +18 -0
- data/test/test_yuzu.rb +8 -0
- data/yuzu.gemspec +182 -0
- metadata +302 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require 'helpers/path'
|
|
2
|
+
|
|
3
|
+
module Yuzu::Core
|
|
4
|
+
class WebsiteBase
|
|
5
|
+
include Helpers
|
|
6
|
+
|
|
7
|
+
attr_reader :path, :parent, :kind
|
|
8
|
+
|
|
9
|
+
def initialize(path, parent)
|
|
10
|
+
raise "WebsiteBase not initialized with a Path object." if not path.is_a?(Path)
|
|
11
|
+
|
|
12
|
+
@path = path
|
|
13
|
+
raise "@path is nil for #{self}" if @path.nil?
|
|
14
|
+
@parent = parent
|
|
15
|
+
@kind = nil
|
|
16
|
+
@stash = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def == (other)
|
|
20
|
+
return false if not other.is_a?(WebsiteBase)
|
|
21
|
+
return @path == other.path
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def name
|
|
25
|
+
@path.basename
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def root
|
|
29
|
+
@root ||= (@parent.nil? ? self : @parent.root)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def root?
|
|
33
|
+
root == self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def blog_folder
|
|
37
|
+
@@blog ||= root.find_file_by_path(Path.new(config.blog_dir))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def in_blog?
|
|
41
|
+
blog_folder.nil? ? false : blog_folder.is_child?(self)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def is_blog?
|
|
45
|
+
self == blog_folder or (index? and self.path.dirname == blog_folder.path.dirname)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def index?
|
|
49
|
+
false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def config
|
|
53
|
+
@parent.config
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def file?
|
|
57
|
+
@kind == :file
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def folder?
|
|
61
|
+
@kind == :folder
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def children
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def processable?
|
|
69
|
+
@processable ||= is_processable?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def is_processable?
|
|
73
|
+
return false if folder?
|
|
74
|
+
config_says = config.processable?(@path)
|
|
75
|
+
translators_say = Yuzu::Translators::Translator.can_translate?(self)
|
|
76
|
+
config_says and translators_say
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def resource?
|
|
80
|
+
return false if folder?
|
|
81
|
+
config.resource?(@path)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def image?
|
|
85
|
+
return false if folder?
|
|
86
|
+
config.image?(@path)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def asset?
|
|
90
|
+
return false if folder?
|
|
91
|
+
config.asset?(@path)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def hidden?
|
|
95
|
+
return false if root?
|
|
96
|
+
@parent.hidden? or @path.rootname[0].chr == "_"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def config
|
|
100
|
+
@parent.config
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def link_to_self(attr={})
|
|
104
|
+
Html::Link.new({:href => link_url}.merge(attr)) << name
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def link_url
|
|
108
|
+
@link_url ||= get_link_url
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def get_link_url
|
|
112
|
+
folder? ? currentpath.full : (currentpath + output_filename).full
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def remote_path
|
|
116
|
+
@remote_path ||= get_remote_path
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def get_remote_path
|
|
120
|
+
if processable?
|
|
121
|
+
tr = file? ? @path.with_extension(extension) : @path
|
|
122
|
+
if tr == @path
|
|
123
|
+
raise "Remote path and source path are the same! Got #{tr} and #{@path}."
|
|
124
|
+
end
|
|
125
|
+
tr
|
|
126
|
+
else
|
|
127
|
+
@path
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def default_stash
|
|
132
|
+
{
|
|
133
|
+
:generated_siblings => [],
|
|
134
|
+
:catalog => nil
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Enables other processes to add imbue this node with information.
|
|
139
|
+
def stash(kwds={})
|
|
140
|
+
@stash = default_stash if @stash.nil?
|
|
141
|
+
kwds.empty? ? @stash : @stash.update(kwds)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def generated?
|
|
145
|
+
false
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
require 'html/base'
|
|
2
|
+
require 'core/website_base'
|
|
3
|
+
require 'core/layout'
|
|
4
|
+
|
|
5
|
+
require 'filters/base'
|
|
6
|
+
require 'renderers/base'
|
|
7
|
+
require 'preprocessors/base'
|
|
8
|
+
require 'postprocessors/base'
|
|
9
|
+
require 'translators/base'
|
|
10
|
+
|
|
11
|
+
%w(filters renderers preprocessors postprocessors translators).each do |folder|
|
|
12
|
+
Dir["#{File.dirname(__FILE__)}/../#{folder}/*"].each { |c| require c if not c.include?("base.rb")}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Yuzu::Core
|
|
16
|
+
class WebsiteFile < WebsiteBase
|
|
17
|
+
include Yuzu::Filters
|
|
18
|
+
include Yuzu::Renderers
|
|
19
|
+
include Yuzu::PreProcessors
|
|
20
|
+
include Yuzu::PostProcessors
|
|
21
|
+
include Yuzu::Translators
|
|
22
|
+
|
|
23
|
+
def self.translators
|
|
24
|
+
Translator.translators
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.processors
|
|
28
|
+
tr = Filter.filters.merge(Renderer.renderers)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Create an accessor method for each filter, renderer, postprocessor.
|
|
32
|
+
self.processors.each_pair do |name, object|
|
|
33
|
+
execution_method = object.kind_of?(Renderer) ? :render : :value
|
|
34
|
+
|
|
35
|
+
instance_variable = "@#{name}".to_sym
|
|
36
|
+
|
|
37
|
+
define_method(name) do
|
|
38
|
+
val = self.instance_variable_get(instance_variable)
|
|
39
|
+
|
|
40
|
+
if val.nil?
|
|
41
|
+
self.instance_variable_set(
|
|
42
|
+
instance_variable,
|
|
43
|
+
object.send(execution_method, self)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
self.instance_variable_get(instance_variable)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Adds all the postprocessors to this object as methods.
|
|
52
|
+
PostProcessor.postprocessors.each_pair do |name, processor|
|
|
53
|
+
|
|
54
|
+
define_method name do
|
|
55
|
+
# This routine caches the result in an instance variable.
|
|
56
|
+
instance_variable = "@postprocessor_#{name}".to_sym
|
|
57
|
+
begin
|
|
58
|
+
if instance_variable_get(instance_variable).nil?
|
|
59
|
+
result = processor.value(self)
|
|
60
|
+
instance_variable_set(instance_variable, result)
|
|
61
|
+
end
|
|
62
|
+
instance_variable_get(instance_variable)
|
|
63
|
+
rescue => e
|
|
64
|
+
puts "\033[91mEXCEPTION IN #{name}\033[0m"
|
|
65
|
+
#puts e.message
|
|
66
|
+
#puts e.backtrace
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attr_reader :page, :parent, :path
|
|
73
|
+
|
|
74
|
+
def initialize(path, parent, page=1)
|
|
75
|
+
@path = path
|
|
76
|
+
raise "@path is nil for #{self}" if @path.nil?
|
|
77
|
+
|
|
78
|
+
@parent = parent
|
|
79
|
+
@page = page
|
|
80
|
+
|
|
81
|
+
@kind = :file
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns a Hash of the properties of this file, like the name, etc.
|
|
85
|
+
def properties
|
|
86
|
+
@properties ||= FileProperties.new(self)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def to_s
|
|
90
|
+
"WebsiteFile(#{@path.relative})"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def name
|
|
94
|
+
post_title
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def author
|
|
98
|
+
config.author
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def home?
|
|
102
|
+
parent.root? and index?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def index?
|
|
106
|
+
basename == "index" or basename.include?("index_")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def filename
|
|
110
|
+
@path.filename
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def basename
|
|
114
|
+
@path.basename
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def output_filename
|
|
118
|
+
processable? ? @path.with_extension(extension).filename : filename
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def markdown?
|
|
122
|
+
@path.markdown?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def plaintext?
|
|
126
|
+
@path.plaintext?
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Alias
|
|
130
|
+
def link_root
|
|
131
|
+
linkroot
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def paginated?
|
|
135
|
+
false
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def raw_contents
|
|
139
|
+
if @raw_contents.nil?
|
|
140
|
+
@raw_contents = get_raw_contents
|
|
141
|
+
preprocess!
|
|
142
|
+
end
|
|
143
|
+
@raw_contents
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def get_raw_contents
|
|
147
|
+
f = File.open(@path.absolute, "r")
|
|
148
|
+
contents = f.read
|
|
149
|
+
f.close
|
|
150
|
+
contents
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def created_at
|
|
154
|
+
@created_at ||= @path.pathname.ctime
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def modified_at
|
|
158
|
+
@modified_at ||= @path.pathname.mtime
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def preprocess!
|
|
162
|
+
PreProcessor.preprocessors.each do |name, preprocessor|
|
|
163
|
+
preprocessor.process(self, @raw_contents)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def prefiltered_contents
|
|
168
|
+
@prefiltered_contents ||= get_prefiltered_contents
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def get_prefiltered_contents
|
|
172
|
+
tr = raw_contents
|
|
173
|
+
prefilters.each do |filter|
|
|
174
|
+
tr = filter.process(self, tr)
|
|
175
|
+
end
|
|
176
|
+
tr
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Returns the contents passed through the filters.
|
|
180
|
+
#
|
|
181
|
+
# @return [String] the processed contents
|
|
182
|
+
def processed_contents
|
|
183
|
+
@processed_contents ||= get_processed_contents
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def get_processed_contents
|
|
187
|
+
tr = prefiltered_contents
|
|
188
|
+
(mainfilters + postfilters).each do |filter|
|
|
189
|
+
tr = filter.process(self, tr)
|
|
190
|
+
end
|
|
191
|
+
tr
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Return the results of running the processed_contents through the textual processors, e.g.
|
|
195
|
+
# markdown.
|
|
196
|
+
#
|
|
197
|
+
# @return [String] the file's html-rendered contents
|
|
198
|
+
def rendered_contents
|
|
199
|
+
@rendered_contents ||= Translator.translate(processed_contents, @path.extension)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def layout
|
|
203
|
+
@layout ||= Yuzu::Core::Layout.new(template)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Presents the rendered_contents placed into its layout. The postprocessors act on this to
|
|
207
|
+
# produce the values needed for html_contents.
|
|
208
|
+
def layout_contents
|
|
209
|
+
layout.render(self)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# The user-facing entry for post.contents in the Haml templates.
|
|
214
|
+
def contents
|
|
215
|
+
rendered_contents
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Renders the full, rendered HTML to write to disk.
|
|
219
|
+
def html_contents
|
|
220
|
+
layout_contents
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def filters
|
|
224
|
+
Filter.filters
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def prefilters
|
|
228
|
+
@prefilters ||= filters.values.select {|filt| filt.filter_type.include?(:prefilter)}
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def mainfilters
|
|
232
|
+
@mainfilters ||= filters.values.select {|filt| filt.filter_type.include?(:filter)}
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def postfilters
|
|
236
|
+
@postfilters ||= filters.values.select {|filt| filt.filter_type.include?(:postfilter)}
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# FileProperties objects are passed into renderers when they need to pass information
|
|
243
|
+
# to a Haml template or other user-facing mechanism. e.g. This makes "breadcrumb" available in
|
|
244
|
+
# Haml templates and layouts by using post.breadcrumb.
|
|
245
|
+
class FileProperties
|
|
246
|
+
# instance.methods == public instance methods
|
|
247
|
+
def initialize(website_file)
|
|
248
|
+
|
|
249
|
+
@website_file = website_file
|
|
250
|
+
unique_methods = (website_file.methods - Object.instance_methods).sort
|
|
251
|
+
|
|
252
|
+
(class << self; self; end).class_eval do
|
|
253
|
+
|
|
254
|
+
unique_methods.each do |method_name|
|
|
255
|
+
|
|
256
|
+
define_method(method_name) do
|
|
257
|
+
website_file.send(method_name)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
end
|
|
261
|
+
end # class_eval
|
|
262
|
+
|
|
263
|
+
end # initialize
|
|
264
|
+
|
|
265
|
+
def to_s
|
|
266
|
+
"Properties(#{@website_file.path.relative})"
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
require 'core/website_file'
|
|
2
|
+
|
|
3
|
+
module Yuzu::Core
|
|
4
|
+
class WebsiteFolder < WebsiteBase
|
|
5
|
+
def initialize(path, parent)
|
|
6
|
+
raise "Not a Path object." if not path.is_a?(Path)
|
|
7
|
+
@path = path
|
|
8
|
+
raise "@path is nil for #{self}" if @path.nil?
|
|
9
|
+
@parent = parent
|
|
10
|
+
@kind = :folder
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s
|
|
14
|
+
"WebsiteFolder(#{@path})"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# -------------------------------------------------------------------------------------------
|
|
18
|
+
# TODO Find a way for folders to know what all the categories are, or better yet, remove this
|
|
19
|
+
# interface and have another way of files, folders, and processors to ask information about the
|
|
20
|
+
# entire site.
|
|
21
|
+
#def all_categories
|
|
22
|
+
#end
|
|
23
|
+
|
|
24
|
+
def breadcrumb
|
|
25
|
+
Yuzu::Renderers::BreadcrumbRenderer.new.render(self)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def currentpath
|
|
29
|
+
Yuzu::Filters::CurrentpathFilter.new.value(self)
|
|
30
|
+
end
|
|
31
|
+
# -------------------------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
def name
|
|
34
|
+
@path.rootname.titlecase
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def files
|
|
38
|
+
@files ||= children.select {|child| child.file?}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def folders
|
|
42
|
+
@folders ||= children.select {|child| child.folder?}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def all_files
|
|
46
|
+
@all_files ||= get_all_files
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def get_all_files
|
|
50
|
+
v = Visitor.new(proc {|c| c.file?})
|
|
51
|
+
tr = []
|
|
52
|
+
v.traverse(self) do |website_file|
|
|
53
|
+
tr.push(website_file)
|
|
54
|
+
end
|
|
55
|
+
tr
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def processable_children
|
|
59
|
+
children.select {|child| child.processable?}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns all the descendants of this folder, as deep as the tree goes, that are "processable"
|
|
63
|
+
# as specified by the config.
|
|
64
|
+
#
|
|
65
|
+
# @return [Array] Of WebsiteFiles representing content that can be translated into HTML or other
|
|
66
|
+
# publishable form.
|
|
67
|
+
def all_processable_children
|
|
68
|
+
all_files.select {|child| child.processable? and not child.hidden?}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns an array of immediate children, files and folders.
|
|
72
|
+
def children
|
|
73
|
+
@children ||= get_children
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Add a new child object to the @children. Used by generators to add new files to the existing
|
|
77
|
+
# file-system-gathered pages. This method should only be called in a generator, since their
|
|
78
|
+
# execution is managed in such a way that new children are added at the right stage of
|
|
79
|
+
# processing.
|
|
80
|
+
#
|
|
81
|
+
# @param [WebsiteFile, WebsiteFolder] new_child The new generated object to add a child.
|
|
82
|
+
# @return nothing
|
|
83
|
+
def append_child(new_child)
|
|
84
|
+
# Ensure we get the children from disk first.
|
|
85
|
+
children
|
|
86
|
+
@children.push(new_child)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def get_children
|
|
90
|
+
tr = folder_contents.collect { |child_path| get_object_for_path(child_path) }
|
|
91
|
+
tr.reject {|c| c.nil?}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Returns a WebsiteFile or WebsiteFolder for the given path.
|
|
95
|
+
#
|
|
96
|
+
# @param [Path] path The Path object representing the on-disk file or folder.
|
|
97
|
+
# @return [WebsiteFile, WebsiteFolder, nil] The child of this folder.
|
|
98
|
+
def get_object_for_path(path)
|
|
99
|
+
# TODO Add different file types: processable, resource, etc.
|
|
100
|
+
|
|
101
|
+
if path.file?
|
|
102
|
+
WebsiteFile.new(path, self)
|
|
103
|
+
|
|
104
|
+
elsif path.folder?
|
|
105
|
+
WebsiteFolder.new(path, self)
|
|
106
|
+
|
|
107
|
+
else
|
|
108
|
+
# ignore
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def folder_contents
|
|
114
|
+
@path.children
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def get_child_by_path(path)
|
|
118
|
+
children.each do |child|
|
|
119
|
+
return child if child.path == path
|
|
120
|
+
end
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def get_child_by_rootname(rootname)
|
|
125
|
+
children.each do |child|
|
|
126
|
+
return child if child.path.rootname == rootname
|
|
127
|
+
end
|
|
128
|
+
nil
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def get_child_by_basename(basename)
|
|
132
|
+
children.each do |child|
|
|
133
|
+
return child if child.path.basename == basename
|
|
134
|
+
end
|
|
135
|
+
nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def get_child_by_filename(filename)
|
|
139
|
+
children.each do |child|
|
|
140
|
+
return child if child.path.filename == filename
|
|
141
|
+
end
|
|
142
|
+
nil
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def is_immediate_child?(web_obj)
|
|
146
|
+
children.include?(web_obj)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def is_child?(web_obj)
|
|
150
|
+
folders_only = proc {|c| c.folder?}
|
|
151
|
+
tr = self.is_immediate_child?(web_obj)
|
|
152
|
+
return true if tr
|
|
153
|
+
|
|
154
|
+
v = Visitor.new(folders_only)
|
|
155
|
+
v.traverse(self) do |website_folder|
|
|
156
|
+
tr ||= website_folder.is_immediate_child?(web_obj)
|
|
157
|
+
end
|
|
158
|
+
tr
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def has_index?
|
|
162
|
+
@has_index ||= get_has_index
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def get_has_index
|
|
166
|
+
child_names = files.collect do |file|
|
|
167
|
+
filename = file.filename
|
|
168
|
+
ext = File.extname(filename)
|
|
169
|
+
filename.sub(ext, "")
|
|
170
|
+
end
|
|
171
|
+
child_names.include?("index")
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
end
|
|
176
|
+
|