brite 0.5 → 0.6.0
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/HISTORY.rdoc +30 -0
- data/LICENSE +199 -17
- data/README.rdoc +61 -0
- data/Syckfile +76 -0
- data/bin/brite +3 -3
- data/bin/brite-server +4 -0
- data/lib/brite.rb +11 -0
- data/lib/brite/command.rb +53 -56
- data/lib/brite/config.rb +94 -18
- data/lib/brite/controller.rb +181 -0
- data/lib/brite/layout.rb +24 -19
- data/lib/brite/meta/data.rb +26 -0
- data/lib/brite/meta/package +8 -0
- data/lib/brite/meta/profile +19 -0
- data/lib/brite/models/model.rb +97 -0
- data/lib/brite/models/page.rb +142 -0
- data/lib/brite/models/post.rb +9 -0
- data/lib/brite/models/site.rb +46 -0
- data/lib/brite/rackup.rb +6 -0
- data/lib/brite/server.rb +144 -0
- data/lib/plugins/sow/brite/awesome/Sowfile +11 -0
- data/lib/plugins/sow/brite/awesome/about.page +28 -0
- data/lib/plugins/sow/brite/awesome/assets/custom.less +96 -0
- data/lib/plugins/sow/brite/awesome/assets/fade.png +0 -0
- data/lib/plugins/sow/brite/awesome/assets/highlight.css +96 -0
- data/lib/plugins/sow/brite/awesome/assets/highlight.js +1 -0
- data/lib/plugins/sow/brite/awesome/assets/jquery.js +19 -0
- data/lib/plugins/sow/brite/awesome/assets/jquery.tabs.js +1 -0
- data/lib/plugins/sow/brite/awesome/assets/reset.css +57 -0
- data/lib/plugins/sow/brite/awesome/assets/ruby.png +0 -0
- data/lib/plugins/sow/brite/awesome/brite.yaml +3 -0
- data/lib/plugins/sow/brite/awesome/history.page +15 -0
- data/lib/plugins/sow/brite/awesome/index.page +18 -0
- data/lib/plugins/sow/brite/awesome/legal.page +28 -0
- data/lib/plugins/sow/brite/awesome/logs.page +14 -0
- data/lib/plugins/sow/brite/awesome/page.layout +75 -0
- data/lib/plugins/sow/brite/blog1/.rsync-filter +12 -0
- data/lib/plugins/sow/brite/blog1/2011/01/sample.html +293 -0
- data/lib/plugins/sow/brite/blog1/2011/01/sample.post +44 -0
- data/lib/plugins/sow/brite/blog1/Sowfile +10 -0
- 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 +15 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/id.css +85 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/misc.css +0 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/print.css +76 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/reset.css +77 -0
- data/lib/plugins/sow/brite/blog1/assets/styles/tag.css +68 -0
- data/lib/plugins/sow/brite/blog1/brite.yml +3 -0
- data/lib/plugins/sow/brite/blog1/index.page +23 -0
- data/lib/plugins/sow/brite/blog1/page.layout +88 -0
- data/lib/plugins/sow/brite/blog1/post.layout +25 -0
- data/meta/data.rb +26 -0
- data/meta/package +8 -0
- data/meta/profile +19 -0
- metadata +86 -47
- data/HISTORY +0 -16
- data/MANIFEST +0 -28
- data/README +0 -42
- data/lib/brite/page.rb +0 -235
- data/lib/brite/part.rb +0 -31
- data/lib/brite/post.rb +0 -37
- data/lib/brite/site.rb +0 -137
- data/lib/brite/template.rb +0 -215
- data/meta/authors +0 -1
- data/meta/contact +0 -1
- data/meta/copyright +0 -1
- data/meta/description +0 -4
- data/meta/homepage +0 -1
- data/meta/license +0 -1
- data/meta/name +0 -1
- data/meta/repository +0 -1
- data/meta/requires +0 -1
- data/meta/ruby +0 -2
- data/meta/subtitle +0 -1
- data/meta/suite +0 -1
- data/meta/summary +0 -1
- data/meta/title +0 -1
- data/meta/version +0 -1
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'brite/models/model'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
#
|
6
|
+
class Page < Model
|
7
|
+
|
8
|
+
# New Page.
|
9
|
+
def initialize(settings={}, &rendering)
|
10
|
+
settings.each do |k,v|
|
11
|
+
if respond_to?("#{k}=")
|
12
|
+
__send__("#{k}=",v)
|
13
|
+
else
|
14
|
+
self[k] = v
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@rendering = rendering
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
attr_accessor :file
|
23
|
+
|
24
|
+
# Instance of Site class to which this page belongs.
|
25
|
+
attr_accessor :site
|
26
|
+
|
27
|
+
# Author
|
28
|
+
attr_accessor :author do
|
29
|
+
'Anonymous'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Title of page/post
|
33
|
+
attr_accessor :title
|
34
|
+
|
35
|
+
# Publish date
|
36
|
+
attr_accessor :date do
|
37
|
+
date_from_filename(file) || Time.now
|
38
|
+
end
|
39
|
+
|
40
|
+
# Category ("a glorified tag")
|
41
|
+
attr_accessor :category
|
42
|
+
|
43
|
+
# Tags (labels)
|
44
|
+
attr_accessor :tags
|
45
|
+
|
46
|
+
#
|
47
|
+
def tags=(entry)
|
48
|
+
case entry
|
49
|
+
when String, Symbol
|
50
|
+
entry = entry.to_s.strip
|
51
|
+
if entry.index(/[,;]/)
|
52
|
+
entry = entry.split(/[,;]/)
|
53
|
+
else
|
54
|
+
entry = entry.split(/\s+/)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
entry = entry.to_a.flatten
|
58
|
+
end
|
59
|
+
@tags = entry.map{ |e| e.strip }
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
attr_accessor :url do
|
64
|
+
File.join(site.url, name + extension)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
attr_accessor :layout
|
69
|
+
|
70
|
+
#
|
71
|
+
def output
|
72
|
+
@output ||= file.chomp(File.extname(file)) + extension
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
def output=(fname)
|
77
|
+
@output = File.join(File.dirname(file), fname) if fname
|
78
|
+
@output
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
def name
|
83
|
+
@name ||= file.chomp(File.extname(file))
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
#attr_accessor :relative_url do
|
88
|
+
# output #File.join(root, output)
|
89
|
+
#end
|
90
|
+
|
91
|
+
#
|
92
|
+
attr_accessor :path do
|
93
|
+
'/' + name + extension
|
94
|
+
end
|
95
|
+
|
96
|
+
# DEPRECATE: Get rid of this and use rack to test page instead of files.
|
97
|
+
# OTOH, that may not alwasy be possible we may need to keep this.
|
98
|
+
attr_accessor :root do
|
99
|
+
'../' * file.count('/')
|
100
|
+
end
|
101
|
+
|
102
|
+
# Working directory of file being rendering. (Why a field?)
|
103
|
+
attr_accessor :work do
|
104
|
+
'/' + File.dirname(file)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Summary is the rendering of the first part.
|
108
|
+
attr_accessor :summary
|
109
|
+
|
110
|
+
# Output extension (defualt is 'html')
|
111
|
+
def extension
|
112
|
+
@extension ||= '.html'
|
113
|
+
end
|
114
|
+
|
115
|
+
# Set output extension.
|
116
|
+
def extension=(extname)
|
117
|
+
@extension = (
|
118
|
+
e = (extname || 'html').to_s
|
119
|
+
e = '.' + e unless e.start_with?('.')
|
120
|
+
e
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Renders page template.
|
125
|
+
def to_s
|
126
|
+
@rendering.call(self)
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
#
|
132
|
+
def date_from_filename(file)
|
133
|
+
if md = (/^\d\d\d\d-\d\d-\d\d/.match(file))
|
134
|
+
md[1]
|
135
|
+
else
|
136
|
+
File.mtime(file)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'brite/models/model'
|
2
|
+
|
3
|
+
module Brite
|
4
|
+
|
5
|
+
#
|
6
|
+
class Site < Model
|
7
|
+
|
8
|
+
# New Site model.
|
9
|
+
def initialize(settings={})
|
10
|
+
settings.each do |k,v|
|
11
|
+
__send__("#{k}=", v)
|
12
|
+
end
|
13
|
+
@pages = []
|
14
|
+
@posts = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a String of the site's URL.
|
18
|
+
attr_accessor :url
|
19
|
+
|
20
|
+
# Returns and Array of Page instances.
|
21
|
+
attr :pages
|
22
|
+
|
23
|
+
# Returns and Array of Post instances.
|
24
|
+
attr :posts
|
25
|
+
|
26
|
+
# Returns an Array of all tags used in all posts.
|
27
|
+
def tags
|
28
|
+
@tags ||= posts.map{ |post| post.tags }.flatten.uniq.sort
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a Hash posts indexed by tag.
|
32
|
+
def posts_by_tag
|
33
|
+
@posts_by_tag ||= (
|
34
|
+
chart ||= Hash.new{|h,k|h[k]=[]}
|
35
|
+
posts.each do |post|
|
36
|
+
post.tags.each do |tag|
|
37
|
+
chart[tag] << post
|
38
|
+
end
|
39
|
+
end
|
40
|
+
chart
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/brite/rackup.rb
ADDED
data/lib/brite/server.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'optparse'
|
3
|
+
require 'rack/server'
|
4
|
+
require 'rack/handler'
|
5
|
+
require 'rack/builder'
|
6
|
+
require 'rack/directory'
|
7
|
+
require 'rack/file'
|
8
|
+
|
9
|
+
module Brite
|
10
|
+
|
11
|
+
# Brite::Server is a Rack-based server useful for testing sites locally.
|
12
|
+
# not all sites --in fact, most sites, can not be fully previewed via
|
13
|
+
# static files. A webserver is required to render and navigate a site
|
14
|
+
# completely. So this light server is provided to facilitate this.
|
15
|
+
class Server < ::Rack::Server
|
16
|
+
|
17
|
+
class Options
|
18
|
+
def parse!(args)
|
19
|
+
args, options = args.dup, {}
|
20
|
+
|
21
|
+
opt_parser = OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: brite-server [options]"
|
23
|
+
|
24
|
+
opts.on("-p", "--port=port", Integer,
|
25
|
+
"Runs server on the specified port.", "Default: 3000") { |v| options[:Port] = v }
|
26
|
+
|
27
|
+
opts.on("-b", "--binding=ip", String,
|
28
|
+
"Binds server to the specified ip.", "Default: 0.0.0.0") { |v| options[:Host] = v }
|
29
|
+
|
30
|
+
opts.on("-c", "--config=file", String,
|
31
|
+
"Use custom rackup configuration file.") { |v| options[:config] = v }
|
32
|
+
|
33
|
+
opts.on("-d", "--daemon", "Make server run as a Daemon.") { options[:daemonize] = true }
|
34
|
+
|
35
|
+
opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { options[:debugger] = true }
|
36
|
+
|
37
|
+
opts.on("-e", "--environment=name", String,
|
38
|
+
"Specifies the environment to run this server under (test/development/production).",
|
39
|
+
"Default: development") { |v| options[:environment] = v }
|
40
|
+
|
41
|
+
opts.separator ""
|
42
|
+
|
43
|
+
opts.on_tail("-h", "--help", "Show this help message.") { puts opts; exit }
|
44
|
+
end
|
45
|
+
|
46
|
+
opt_parser.parse!(args)
|
47
|
+
|
48
|
+
options[:server] = args.shift
|
49
|
+
|
50
|
+
return options
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
def initialize(*)
|
56
|
+
super
|
57
|
+
set_environment
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
def opt_parser
|
62
|
+
Options.new
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
def set_environment
|
67
|
+
ENV["BRITE_ENV"] ||= options[:environment]
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
def start
|
72
|
+
puts "=> Booting #{server}"
|
73
|
+
puts "=> On http://#{options[:Host]}:#{options[:Port]}"
|
74
|
+
puts "=> Call with -d to detach" unless options[:daemonize]
|
75
|
+
trap(:INT) { exit }
|
76
|
+
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
|
77
|
+
|
78
|
+
#Create required tmp directories if not found
|
79
|
+
%w(cache pids sessions sockets).each do |dir_to_make|
|
80
|
+
FileUtils.mkdir_p(File.join('.cache', dir_to_make))
|
81
|
+
end
|
82
|
+
|
83
|
+
super
|
84
|
+
ensure
|
85
|
+
# The '-h' option calls exit before @options is set.
|
86
|
+
# If we call 'options' with it unset, we get double help banners.
|
87
|
+
puts 'Exiting' unless @options && options[:daemonize]
|
88
|
+
end
|
89
|
+
|
90
|
+
def middleware
|
91
|
+
middlewares = []
|
92
|
+
#middlewares << [Rails::Rack::LogTailer, log_path] unless options[:daemonize]
|
93
|
+
#middlewares << [Rails::Rack::Debugger] if options[:debugger]
|
94
|
+
Hash.new(middlewares)
|
95
|
+
end
|
96
|
+
|
97
|
+
def log_path
|
98
|
+
".cache/brite.log"
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_options
|
102
|
+
super.merge({
|
103
|
+
:Port => 3000,
|
104
|
+
:environment => (ENV['BRITE_ENV'] || "development").dup,
|
105
|
+
:daemonize => false,
|
106
|
+
:debugger => false,
|
107
|
+
:pid => ".cache/pids/server.pid",
|
108
|
+
:config => nil
|
109
|
+
})
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
def root
|
114
|
+
Dir.pwd
|
115
|
+
end
|
116
|
+
|
117
|
+
def app
|
118
|
+
@app ||= begin
|
119
|
+
config_file = options[:config]
|
120
|
+
if config_file && ::File.exist?(config_file)
|
121
|
+
app, options = Rack::Builder.parse_file(config_file, opt_parser)
|
122
|
+
self.options.merge!(options)
|
123
|
+
app
|
124
|
+
else
|
125
|
+
root = self.root
|
126
|
+
app, options = Rack::Builder.new do
|
127
|
+
run Rack::Directory.new("#{root}")
|
128
|
+
end
|
129
|
+
#self.options.merge!(options)
|
130
|
+
app
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
## The static content rooted in the current working directory
|
140
|
+
## Eg. Dir.pwd => http://0.0.0.0:3000/
|
141
|
+
#root = Dir.pwd
|
142
|
+
#puts ">>> Serving: #{root}"
|
143
|
+
#run Rack::Directory.new("#{root}")
|
144
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
title : About
|
3
|
+
layout : page
|
4
|
+
stencil : erb
|
5
|
+
|
6
|
+
--- html
|
7
|
+
|
8
|
+
<%= if file = project.exist?('{,meta}{PACKAGE,VERSION}*') %>
|
9
|
+
<h1>VERSION</h1>
|
10
|
+
<pre>
|
11
|
+
<%= File.read(file) %>
|
12
|
+
<% end %>
|
13
|
+
</pre>
|
14
|
+
|
15
|
+
<%= if file = project.exist?('{,meta}{PROFILE}*') %>
|
16
|
+
<h1>PROFILE</h1>
|
17
|
+
<pre>
|
18
|
+
<%= File.read(file) %>
|
19
|
+
</pre>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<%= if file = project.exist?('{MANIFEST}*') %>
|
23
|
+
<h1>MANIFEST</h1>
|
24
|
+
<pre>
|
25
|
+
<%= read('MANIFEST*') %>
|
26
|
+
<%= File.read(file) %>
|
27
|
+
</pre>
|
28
|
+
<% end %>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
@color_background: #ffffff;
|
2
|
+
@color_foreground: #222222;
|
3
|
+
@color_hyperlink: #220022;
|
4
|
+
@colot_highlight: #111111;
|
5
|
+
|
6
|
+
/* ------------ TAG STYLES -------------- */
|
7
|
+
|
8
|
+
html { font-family: sans-setif; font-size: 100%; }
|
9
|
+
body { position: relative; color: #222233; background: #ffffff; }
|
10
|
+
|
11
|
+
p { text-align: justify; font-size: 100%; line-height: 150%; margin: 0 0 1.2em 0; }
|
12
|
+
a { text-decoration: none; color: @color_hyperlink; }
|
13
|
+
a:hover { text-decoration: underline; }
|
14
|
+
|
15
|
+
td { vertical-align: top; text-align: left; }
|
16
|
+
ul { padding: 0 0 10px 0; }
|
17
|
+
li { padding: 0 0 3px 0; font-size: 0.9em; line-height: 130%; }
|
18
|
+
|
19
|
+
img { border: none; }
|
20
|
+
pre { margin: 10px 0; font-family: monospace; color: white; }
|
21
|
+
pre code { padding: 10px 10px; }
|
22
|
+
|
23
|
+
h1, h2, h3, h4, h5, h6 { margin: 1.75em 0 0.7em 0; }
|
24
|
+
h1 { font-size: 200%; }
|
25
|
+
h2 { font-size: 150%; }
|
26
|
+
h3 { font-size: 120%; }
|
27
|
+
h4 { font-size: 100%; }
|
28
|
+
|
29
|
+
|
30
|
+
/* ------------ CLASS STYLES ------------ */
|
31
|
+
|
32
|
+
.centered {
|
33
|
+
width: 760px;
|
34
|
+
margin: 0 auto;
|
35
|
+
}
|
36
|
+
|
37
|
+
.colorized {
|
38
|
+
background: @color_backgound;
|
39
|
+
color: @color_foreground;
|
40
|
+
}
|
41
|
+
|
42
|
+
.highlighted {
|
43
|
+
background: @color_backgound;
|
44
|
+
color: @color_highlight;
|
45
|
+
}
|
46
|
+
|
47
|
+
/* ------------ ID STYLES ------------ */
|
48
|
+
|
49
|
+
/* #header */
|
50
|
+
|
51
|
+
#header { border-bottom: 1px solid #ccc; padding: 0; }
|
52
|
+
#header .title { padding: 10px 0; font-size: 20px; height: 120px; vertical-align: absmiddle; text-align: center; }
|
53
|
+
#header .title h1 { font-size: 81px; font-weight: bold; margin-top: 30px; }
|
54
|
+
#header .title h1 { color: @color_highlight; }
|
55
|
+
#header .title pre { background: transparent; }
|
56
|
+
#header .menu { text-align: center; padding: 5px 0 15px 0; }
|
57
|
+
|
58
|
+
/* #nav */
|
59
|
+
|
60
|
+
#nav { padding: 0 10px 0 50px; text-align: left; }
|
61
|
+
#nav ul { list-style-type: none; margin: 0px; padding: 0px; width: 100%; position: relative; }
|
62
|
+
#nav ul li { margin: 0 1px 10px 0; line-height: 20px; white-space:nowrap; }
|
63
|
+
#nav ul li a { border-top: 0 solid; }
|
64
|
+
#nav { text-align: right; }
|
65
|
+
#nav ul li a { font-weight: bold; text-decoration: none; font-size: 1.5em; line-height: 1.4em; }
|
66
|
+
#nav ul li a:hover { text-decoration: underline; }
|
67
|
+
#nav ul li a:active { text-decoration: underline; }
|
68
|
+
#nav ul { background: transparent; }
|
69
|
+
|
70
|
+
/* #main */
|
71
|
+
|
72
|
+
.main { padding: 20px 0 30px 0; }
|
73
|
+
.main { }
|
74
|
+
.main a { font-size: 100%; }
|
75
|
+
.main a:hover { text-decoration: underline; }
|
76
|
+
.main h1:first-child { margin-top: 20px; }
|
77
|
+
.main h2 { font-size: 2em; font-weight: bold; }
|
78
|
+
.main h3 { font-style: italic; }
|
79
|
+
|
80
|
+
/* #doc */
|
81
|
+
|
82
|
+
#doc { font-weight: bold; line-height: 150%; padding-right: 20px; }
|
83
|
+
#doc a:hover { }
|
84
|
+
#doc p { font-weight: bold; font-size: 150%; }
|
85
|
+
#doc h2 { color: @color_highlight; border-color: @color_highlight; }
|
86
|
+
#doc h3 { border-color: @color_highlight; }
|
87
|
+
|
88
|
+
#readme { margin-top: 10px; margin-bottom: 20px; padding-top: 20px; }
|
89
|
+
#readme ol, ul { list-style: square; margin-left: 24px; }
|
90
|
+
|
91
|
+
/* #footer */
|
92
|
+
|
93
|
+
#footer { margin-top: 0; padding-top: 30px; border-top: 1px solid #ccc; }
|
94
|
+
#footer .advert { border: 1px solid :eee; }
|
95
|
+
#footer .copyright { margin-top: 20px; padding: 20px 0px 35px 0px; font-size: 0.8em; color: #aaa; }
|
96
|
+
|