brite 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +56 -0
- data/COPYING.rdoc +30 -0
- data/HISTORY.rdoc +16 -2
- data/README.rdoc +35 -27
- data/bin/brite-server +1 -1
- data/lib/brite.rb +2 -1
- data/lib/brite.yml +56 -0
- data/lib/brite/command.rb +100 -55
- data/lib/brite/config.rb +122 -40
- data/lib/brite/controller.rb +46 -104
- data/lib/brite/layout.rb +27 -13
- data/lib/brite/model.rb +107 -0
- data/lib/brite/page.rb +229 -0
- data/lib/brite/part.rb +88 -0
- data/lib/brite/post.rb +41 -0
- data/lib/brite/server.rb +88 -93
- data/lib/brite/site.rb +150 -0
- data/lib/brite/version.rb +21 -0
- data/test/fixture/brite.yml +3 -0
- data/test/fixture/example-page.page +8 -0
- data/test/fixture/example-post.post +9 -0
- data/test/helper.rb +5 -0
- data/test/test_config.rb +23 -0
- data/test/test_page.rb +28 -0
- data/test/test_site.rb +37 -0
- metadata +104 -109
- data/LICENSE +0 -205
- data/Syckfile +0 -76
- data/lib/brite/meta/data.rb +0 -26
- data/lib/brite/meta/package +0 -8
- data/lib/brite/meta/profile +0 -19
- data/lib/brite/models/model.rb +0 -97
- data/lib/brite/models/page.rb +0 -142
- data/lib/brite/models/post.rb +0 -9
- data/lib/brite/models/site.rb +0 -46
- data/lib/brite/rackup.rb +0 -6
- data/lib/plugins/sow/brite/awesome/Sowfile +0 -11
- data/lib/plugins/sow/brite/awesome/about.page +0 -28
- data/lib/plugins/sow/brite/awesome/assets/custom.less +0 -96
- data/lib/plugins/sow/brite/awesome/assets/fade.png +0 -0
- data/lib/plugins/sow/brite/awesome/assets/highlight.css +0 -96
- data/lib/plugins/sow/brite/awesome/assets/highlight.js +0 -1
- data/lib/plugins/sow/brite/awesome/assets/jquery.js +0 -19
- data/lib/plugins/sow/brite/awesome/assets/jquery.tabs.js +0 -1
- data/lib/plugins/sow/brite/awesome/assets/reset.css +0 -57
- data/lib/plugins/sow/brite/awesome/assets/ruby.png +0 -0
- data/lib/plugins/sow/brite/awesome/brite.yaml +0 -3
- data/lib/plugins/sow/brite/awesome/history.page +0 -15
- data/lib/plugins/sow/brite/awesome/index.page +0 -18
- data/lib/plugins/sow/brite/awesome/legal.page +0 -28
- data/lib/plugins/sow/brite/awesome/logs.page +0 -14
- data/lib/plugins/sow/brite/awesome/page.layout +0 -75
- data/lib/plugins/sow/brite/blog1/.rsync-filter +0 -12
- data/lib/plugins/sow/brite/blog1/2011/01/sample.html +0 -293
- data/lib/plugins/sow/brite/blog1/2011/01/sample.post +0 -44
- data/lib/plugins/sow/brite/blog1/Sowfile +0 -10
- data/lib/plugins/sow/brite/blog1/assets/images/bg.jpg +0 -0
- data/lib/plugins/sow/brite/blog1/assets/images/icon.jpg +0 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/class.css +0 -15
- data/lib/plugins/sow/brite/blog1/assets/styles/id.css +0 -85
- data/lib/plugins/sow/brite/blog1/assets/styles/misc.css +0 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/print.css +0 -76
- data/lib/plugins/sow/brite/blog1/assets/styles/reset.css +0 -77
- data/lib/plugins/sow/brite/blog1/assets/styles/tag.css +0 -68
- data/lib/plugins/sow/brite/blog1/brite.yml +0 -3
- data/lib/plugins/sow/brite/blog1/index.page +0 -23
- data/lib/plugins/sow/brite/blog1/page.layout +0 -88
- data/lib/plugins/sow/brite/blog1/post.layout +0 -25
- data/meta/data.rb +0 -26
- data/meta/package +0 -8
- data/meta/profile +0 -19
data/lib/brite/model.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
module Brite
|
2
|
+
|
3
|
+
# Base class for all site classes.
|
4
|
+
#
|
5
|
+
class Model
|
6
|
+
|
7
|
+
#
|
8
|
+
def initialize(site, file, data={})
|
9
|
+
@site = site
|
10
|
+
@files = file
|
11
|
+
|
12
|
+
update(date)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :site
|
16
|
+
|
17
|
+
attr_reader :file
|
18
|
+
|
19
|
+
#
|
20
|
+
def config
|
21
|
+
site.config
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Render partial template.
|
26
|
+
#
|
27
|
+
def part(path)
|
28
|
+
@part ||= (
|
29
|
+
partial = site.lookup_partial(path.to_s)
|
30
|
+
#if path
|
31
|
+
# partial = site.parts.find{ |part|
|
32
|
+
# part.name == path
|
33
|
+
# }
|
34
|
+
raise "no such part -- #{path} from #{file}" unless partial
|
35
|
+
partial.render
|
36
|
+
#else
|
37
|
+
# Part::Manager.new(self)
|
38
|
+
#end
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def update(data)
|
44
|
+
data.each do |k,v|
|
45
|
+
self[k] = v
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Add entry to settings data.
|
50
|
+
def [](k)
|
51
|
+
instance_variable_get("@#{k}")
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add entry to settings data.
|
55
|
+
def []=(k,v)
|
56
|
+
if respond_to?("#{k}=")
|
57
|
+
__send__("#{k}=", v)
|
58
|
+
else
|
59
|
+
instance_variable_set("@#{k}", v)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#def to_ary
|
64
|
+
# p caller
|
65
|
+
# raise
|
66
|
+
#end
|
67
|
+
|
68
|
+
#
|
69
|
+
def method_missing(name, *a, &b)
|
70
|
+
instance_variable_get("@#{name}")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns a Binding for this instance.
|
74
|
+
def to_binding(&block)
|
75
|
+
binding
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns a Hash of rendering fields.
|
79
|
+
def to_h
|
80
|
+
hash = {}
|
81
|
+
fields = rendering_fields
|
82
|
+
fields.each do |field|
|
83
|
+
hash[field.to_s] = __send__(field)
|
84
|
+
end
|
85
|
+
hash
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns an Array of attribute/method names to be visible to the page
|
89
|
+
# rendering.
|
90
|
+
def rendering_fields
|
91
|
+
list = []
|
92
|
+
instance_variables.each do |iv|
|
93
|
+
name = iv.to_s.sub('@','')
|
94
|
+
next if name.start_with?('_')
|
95
|
+
list << name
|
96
|
+
end
|
97
|
+
list
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
#def singleton_class
|
102
|
+
# (class << self; self; end)
|
103
|
+
#end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/lib/brite/page.rb
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'brite/model'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Models a site page.
|
6
|
+
class Page < Model
|
7
|
+
|
8
|
+
# New Page.
|
9
|
+
def initialize(site, file, copy={})
|
10
|
+
@site = site
|
11
|
+
@file = file
|
12
|
+
|
13
|
+
initialize_defaults
|
14
|
+
|
15
|
+
update(copy)
|
16
|
+
|
17
|
+
@_template = Neapolitan.file(file, :stencil=>site.config.stencil) #site.page_defaults)
|
18
|
+
|
19
|
+
update(@_template.metadata)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
def initialize_defaults
|
24
|
+
@tags = []
|
25
|
+
@author = site.config.author
|
26
|
+
@route = site.config.page_route
|
27
|
+
@layout = site.config.page_layout
|
28
|
+
|
29
|
+
@extension = '.html'
|
30
|
+
|
31
|
+
# these are filled-out as needed, but the instance variable
|
32
|
+
# must define up front to ensure #to_h will pick them up.
|
33
|
+
# Probably this should be done in a different way in the future.
|
34
|
+
@output = nil
|
35
|
+
@path = nil
|
36
|
+
@name = nil
|
37
|
+
@url = nil
|
38
|
+
@root = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Instance of Site class to which this page belongs.
|
42
|
+
attr_reader :site
|
43
|
+
|
44
|
+
# The `.page` file.
|
45
|
+
attr_reader :file
|
46
|
+
|
47
|
+
# Author of page.
|
48
|
+
attr_accessor :author
|
49
|
+
|
50
|
+
# Title of page/post.
|
51
|
+
attr_accessor :title
|
52
|
+
|
53
|
+
# Publish date.
|
54
|
+
attr_accessor :date
|
55
|
+
|
56
|
+
def date
|
57
|
+
@date ||= date_from_filename(file) || Time.now
|
58
|
+
end
|
59
|
+
|
60
|
+
# Category ("a glorified tag")
|
61
|
+
attr_accessor :category
|
62
|
+
|
63
|
+
# Is this page a draft? If so it will not be rendered.
|
64
|
+
attr_accessor :draft
|
65
|
+
|
66
|
+
# Query alias for #draft.
|
67
|
+
alias_method :draft?, :draft
|
68
|
+
|
69
|
+
# Output route.
|
70
|
+
attr_accessor :route
|
71
|
+
|
72
|
+
# Layout to use for page.
|
73
|
+
attr_accessor :layout
|
74
|
+
|
75
|
+
# Tags (labels)
|
76
|
+
attr_accessor :tags
|
77
|
+
|
78
|
+
#
|
79
|
+
def tags=(entry)
|
80
|
+
case entry
|
81
|
+
when String, Symbol
|
82
|
+
entry = entry.to_s.strip
|
83
|
+
if entry.index(/[,;]/)
|
84
|
+
entry = entry.split(/[,;]/)
|
85
|
+
else
|
86
|
+
entry = entry.split(/\s+/)
|
87
|
+
end
|
88
|
+
else
|
89
|
+
entry = entry.to_a.flatten
|
90
|
+
end
|
91
|
+
@tags = entry.map{ |e| e.strip }
|
92
|
+
end
|
93
|
+
|
94
|
+
# The page's route, which is effectively the "Save As" output file.
|
95
|
+
def output
|
96
|
+
@output ||= calculate_output
|
97
|
+
end
|
98
|
+
|
99
|
+
# Set route directly, relative to file, overriding any slug.
|
100
|
+
def output=(path)
|
101
|
+
@output = path.sub(/^\//,'')
|
102
|
+
end
|
103
|
+
|
104
|
+
# Setting the peramlink is the same as setting output.
|
105
|
+
alias_method :permalink=, :output=
|
106
|
+
|
107
|
+
# Same as output but prefixed with `/`.
|
108
|
+
def permalink
|
109
|
+
'/' + output
|
110
|
+
end
|
111
|
+
|
112
|
+
alias_method :url, :permalink
|
113
|
+
|
114
|
+
#
|
115
|
+
#def url
|
116
|
+
# @url ||= config.url ? File.join(config.url, output) : permalink
|
117
|
+
#end
|
118
|
+
|
119
|
+
# The `name` is same as `output` but without any file extension.
|
120
|
+
def name
|
121
|
+
@name ||= output.chomp(extension)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
#attr_accessor :relative_url do
|
126
|
+
# output #File.join(root, output)
|
127
|
+
#end
|
128
|
+
|
129
|
+
# THINK: Is there any reason to have #work ?
|
130
|
+
# Working directory of file being rendering.
|
131
|
+
#def work
|
132
|
+
# @work ||= '/' + File.dirname(file)
|
133
|
+
#end
|
134
|
+
|
135
|
+
# Relative path difference between the route and the site's root.
|
136
|
+
# The return value is a string of `..` paths, e.g. `"../../"`.
|
137
|
+
#
|
138
|
+
# @return [String] multiples of `../`.
|
139
|
+
def root
|
140
|
+
#@root ||= '../' * file.count('/')
|
141
|
+
@root ||= '../' * (output.count('/') - (output.scan('../').length*2))
|
142
|
+
end
|
143
|
+
|
144
|
+
# Output extension (defualts to 'html').
|
145
|
+
def extension
|
146
|
+
@extension #||= '.html'
|
147
|
+
end
|
148
|
+
|
149
|
+
# Set output extension.
|
150
|
+
#
|
151
|
+
# @param [String] extname
|
152
|
+
# The file extension.
|
153
|
+
#
|
154
|
+
def extension=(extname)
|
155
|
+
@extension = (
|
156
|
+
e = (extname || 'html').to_s
|
157
|
+
e = '.' + e unless e.start_with?('.')
|
158
|
+
e
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
# TODO: Summary is being set externally, is there a way to fix ?
|
163
|
+
|
164
|
+
# Summary is the rendering of the first part.
|
165
|
+
attr_accessor :summary
|
166
|
+
|
167
|
+
# Renders page template.
|
168
|
+
def to_s
|
169
|
+
render
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
def inspect
|
174
|
+
"#<#{self.class} #{@file}>"
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
#
|
180
|
+
def date_from_filename(file)
|
181
|
+
if md = (/^\d\d\d\d-\d\d-\d\d/.match(file))
|
182
|
+
md[1]
|
183
|
+
else
|
184
|
+
File.mtime(file)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
def calculate_output
|
190
|
+
path = file.chomp(File.extname(file))
|
191
|
+
name = File.basename(path)
|
192
|
+
|
193
|
+
out = route.dup
|
194
|
+
out = date.strftime(out) if out.index('%')
|
195
|
+
out = out.sub(':path', path)
|
196
|
+
out = out.sub(':name', name)
|
197
|
+
out = out + extension
|
198
|
+
out
|
199
|
+
end
|
200
|
+
|
201
|
+
# Render page or post.
|
202
|
+
#
|
203
|
+
# @param [Neapolitan::Template] template
|
204
|
+
# Template to be rendered.
|
205
|
+
#
|
206
|
+
# @param [Model] model
|
207
|
+
# Page or Post model to use for rendering.
|
208
|
+
#
|
209
|
+
def render
|
210
|
+
render = @_template.render(self) #, &body)
|
211
|
+
|
212
|
+
self.summary = render.summary # TODO: make part of neapolitan?
|
213
|
+
|
214
|
+
result = render.to_s
|
215
|
+
|
216
|
+
if layout
|
217
|
+
if layout_object = site.lookup_layout(layout)
|
218
|
+
result = layout_object.render(self){ result }
|
219
|
+
#else
|
220
|
+
# raise "No such layout -- #{layout}" unless layout
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
result.to_s.strip
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
data/lib/brite/part.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Brite
|
2
|
+
|
3
|
+
# In you templates:
|
4
|
+
#
|
5
|
+
# <%= part.some_part_name %>
|
6
|
+
#
|
7
|
+
class Part < Model
|
8
|
+
|
9
|
+
# New Page.
|
10
|
+
def initialize(site, file, copy={})
|
11
|
+
@site = site
|
12
|
+
@file = file
|
13
|
+
|
14
|
+
initialize_defaults
|
15
|
+
|
16
|
+
update(copy)
|
17
|
+
|
18
|
+
@_template = Neapolitan.file(file, :stencil=>site.config.stencil) #site.page_defaults)
|
19
|
+
|
20
|
+
update(@_template.metadata)
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
def initialize_defaults
|
25
|
+
@layout = nil
|
26
|
+
|
27
|
+
@part = nil
|
28
|
+
@name = nil
|
29
|
+
@basename = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
def name
|
34
|
+
@name ||= file.chomp('.part')
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
def basename
|
39
|
+
@basename ||= File.basename(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Render page or post template.
|
43
|
+
#
|
44
|
+
def render
|
45
|
+
render = @_template.render(self) #, &body)
|
46
|
+
|
47
|
+
result = render.to_s
|
48
|
+
|
49
|
+
if layout
|
50
|
+
if layout_object = site.lookup_layout(layout)
|
51
|
+
result = layout_object.render(self){ result }
|
52
|
+
#else
|
53
|
+
# raise "No such layout -- #{layout}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
result.to_s.strip
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
class Manager
|
62
|
+
|
63
|
+
def initialize(model)
|
64
|
+
@model = model
|
65
|
+
@site = model.site
|
66
|
+
|
67
|
+
@parts = {}
|
68
|
+
model.site.parts.each do |part|
|
69
|
+
@parts[part.basename] = part
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
def to_h
|
75
|
+
@parts
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
def method_missing(name, *args, &block)
|
80
|
+
@parts[name.to_s].render
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
data/lib/brite/post.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'brite/page'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
# Models a blog post. A post is essentially the same as a page,
|
6
|
+
# but carries a relatition with other posts that a page does not.
|
7
|
+
#
|
8
|
+
class Post < Page
|
9
|
+
|
10
|
+
#
|
11
|
+
def initialize_defaults
|
12
|
+
super
|
13
|
+
|
14
|
+
@route = site.config.post_route
|
15
|
+
@layout = site.config.post_layout #@site.config.find_layout(@site.config.post_layout)
|
16
|
+
|
17
|
+
@previous_post = nil
|
18
|
+
@next_post = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# This assumes `site.posts` is sorted by date.
|
22
|
+
#
|
23
|
+
# @todo Rename to back_post.
|
24
|
+
def previous_post
|
25
|
+
@previous_post ||= (
|
26
|
+
index = site.posts.index(self)
|
27
|
+
index == 0 ? nil : site.posts[index - 1]
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# This assumes `site.posts` is sorted by date.
|
32
|
+
def next_post
|
33
|
+
@next_post ||= (
|
34
|
+
index = site.posts.index(self)
|
35
|
+
site.posts[index + 1]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|