brite 0.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|