blogical 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/app/blogical/atom.rb +31 -0
- data/app/blogical/blog.rb +29 -0
- data/app/blogical/content.rb +146 -0
- data/app/blogical/extensions.rb +30 -0
- data/app/blogical/helpers.rb +38 -0
- data/content/01 Welcome/content.markdown +3 -0
- data/content/01 Welcome/meta.rb +5 -0
- data/public/css/screen.css +330 -0
- data/public/css/twilight.css +137 -0
- data/public/scripts/iepngfix.htc +187 -0
- data/public/scripts/iepngfix.tilebg.js +173 -0
- data/views/blogical/article.erb +9 -0
- data/views/blogical/blog.erb +17 -0
- data/views/blogical/layout.erb +42 -0
- metadata +17 -3
@@ -0,0 +1,31 @@
|
|
1
|
+
module Blogical
|
2
|
+
module Atom
|
3
|
+
def self.included(app)
|
4
|
+
|
5
|
+
app.get '/blog/atom.xml' do
|
6
|
+
|
7
|
+
feed = ::Atom::Feed.new do |f|
|
8
|
+
f.title = self.class.feed_title
|
9
|
+
f.links << ::Atom::Link.new(:href => self.class.url)
|
10
|
+
f.updated = options.repository.latest.posted.to_s(:iso8601)
|
11
|
+
f.authors << ::Atom::Person.new(:name => self.class.full_name)
|
12
|
+
f.id = 'tag:'+self.class.domain+',2010:blogical/blog'
|
13
|
+
|
14
|
+
options.repository.recent(15).each do |post|
|
15
|
+
entry = ::Atom::Entry.new do |e|
|
16
|
+
e.title = post.title
|
17
|
+
e.links << ::Atom::Link.new(:href => post.url)
|
18
|
+
e.id = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, post.url).to_uri.to_s
|
19
|
+
e.updated = post.posted.to_s(:iso8601)
|
20
|
+
e.content = ::Atom::Content::Html.new(markup(File.read(post.content)))
|
21
|
+
end
|
22
|
+
|
23
|
+
f.entries << entry
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
feed.to_xml
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Blogical
|
2
|
+
module Blog
|
3
|
+
def self.included(app)
|
4
|
+
|
5
|
+
# GET /blog
|
6
|
+
app.get %r{^/blog/?(\?.*)?$} do
|
7
|
+
@posts = options.repository.paginated(Integer(params['page']))
|
8
|
+
@pages = options.repository.total_pages
|
9
|
+
erb :blog
|
10
|
+
end
|
11
|
+
|
12
|
+
# GET /blog/2009/05/12/comma-intro
|
13
|
+
app.get '/blog/:year/:month/:day/:title' do |year, month, day, title|
|
14
|
+
@post = options.repository.find_by_permalink(title)
|
15
|
+
raise Sinatra::NotFound, 'No such post' unless @post
|
16
|
+
@title = @post.title
|
17
|
+
erb :article
|
18
|
+
end
|
19
|
+
|
20
|
+
# GET /assets/2009/05/12/1-filename.pdf
|
21
|
+
app.get '/assets/:year/:month/:day/:attachment' do |year, month, day, attachment|
|
22
|
+
@attachment = options.repository.find_by_attachment(attachment)
|
23
|
+
raise Sinatra::NotFound, 'No such attachment' unless @attachment
|
24
|
+
send_file @attachment.content, :disposition => 'attachment'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module Blogical
|
4
|
+
module Content
|
5
|
+
|
6
|
+
def self.included(app)
|
7
|
+
app.configure do |app|
|
8
|
+
app.set :repository, Repository.new(app.content)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Repository
|
13
|
+
attr_accessor :articles, :path
|
14
|
+
|
15
|
+
def initialize(path)
|
16
|
+
@path, @index, @articles, @attachments = path, [], {}, {}
|
17
|
+
scan
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_permalink(link)
|
21
|
+
@articles[link]
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_attachment(attachment)
|
25
|
+
@attachments[attachment]
|
26
|
+
end
|
27
|
+
|
28
|
+
def recent(count = 3)
|
29
|
+
count = @index.size if count > @index.size
|
30
|
+
@index[0..(count - 1)]
|
31
|
+
end
|
32
|
+
|
33
|
+
def latest
|
34
|
+
@index[0]
|
35
|
+
end
|
36
|
+
|
37
|
+
def total_pages
|
38
|
+
@index.total_pages
|
39
|
+
end
|
40
|
+
|
41
|
+
def paginated(page_number = 1)
|
42
|
+
@index.page(page_number)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def page_size
|
48
|
+
@index.page_size
|
49
|
+
end
|
50
|
+
|
51
|
+
def article(meta)
|
52
|
+
article = Article.new(meta)
|
53
|
+
@index << article
|
54
|
+
@articles[article.permalink] = article
|
55
|
+
article.attachments.each { |a| @attachments[a.name] = a } if article.attachments
|
56
|
+
puts "Registered article #{article.permalink} (posted #{article.posted})"
|
57
|
+
end
|
58
|
+
|
59
|
+
def scan
|
60
|
+
metafiles = []
|
61
|
+
Find.find(@path) do |path|
|
62
|
+
next unless FileTest.directory?(path)
|
63
|
+
meta = "#{path}/meta.rb"
|
64
|
+
next unless File.exists?(meta)
|
65
|
+
metafiles << meta
|
66
|
+
Find.prune
|
67
|
+
end
|
68
|
+
metafiles.sort.reverse.each do |meta|
|
69
|
+
article(meta)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
class Article
|
76
|
+
attr_accessor :permalink, :posted, :attachments, :tags, :content, :title
|
77
|
+
|
78
|
+
def initialize(meta)
|
79
|
+
@path, @content = meta, File.join(File.expand_path(File.dirname(meta)), 'content.markdown')
|
80
|
+
instance_eval File.read(meta)
|
81
|
+
end
|
82
|
+
|
83
|
+
def article(title, &block)
|
84
|
+
@title = title
|
85
|
+
instance_eval &block
|
86
|
+
end
|
87
|
+
|
88
|
+
def permalink(link = nil)
|
89
|
+
return @permalink unless link
|
90
|
+
@permalink = link
|
91
|
+
end
|
92
|
+
|
93
|
+
def posted(date = nil)
|
94
|
+
if date
|
95
|
+
@posted = date
|
96
|
+
else
|
97
|
+
return Chronic.parse(@posted)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# REVISIT: most recent content file git commit author
|
102
|
+
def nickname
|
103
|
+
Blogical::Application.nickname
|
104
|
+
end
|
105
|
+
|
106
|
+
def email
|
107
|
+
Blogical::Application.email
|
108
|
+
end
|
109
|
+
|
110
|
+
def url
|
111
|
+
"/blog/#{@posted}/#{@permalink}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def attachments(*attachments)
|
115
|
+
return @attachments if attachments.empty?
|
116
|
+
@attachments = attachments.collect { |attachment| Attachment.new(self, attachment) }
|
117
|
+
end
|
118
|
+
|
119
|
+
def tags(*tags)
|
120
|
+
return @tags if tags.empty?
|
121
|
+
@tags = tags.collect { |tag| Tag.new(self, tag) }
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
class Attachment
|
127
|
+
attr_accessor :article, :name, :content
|
128
|
+
|
129
|
+
def initialize(article, name)
|
130
|
+
@article, @name = article, name
|
131
|
+
@content = File.join(File.expand_path(File.dirname(article.content)), name)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
class Tag
|
137
|
+
attr_accessor :article, :name
|
138
|
+
|
139
|
+
def initialize(article, name)
|
140
|
+
@article, @name = article, name
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Time
|
2
|
+
|
3
|
+
FORMATS = {
|
4
|
+
:iso8601 => '%Y-%m-%dT%H:%MZ',
|
5
|
+
:posted => '%d %B %Y'
|
6
|
+
}
|
7
|
+
|
8
|
+
def to_s(requested = :iso8601)
|
9
|
+
self.strftime(FORMATS[requested])
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
class Array
|
15
|
+
|
16
|
+
def total_pages
|
17
|
+
(self.size.to_f / page_size.to_f).ceil
|
18
|
+
end
|
19
|
+
|
20
|
+
def page(page_number = 0)
|
21
|
+
page_number = 1 if page_number < 1
|
22
|
+
base = (page_number - 1) * page_size
|
23
|
+
self[base..(base + page_size - 1)]
|
24
|
+
end
|
25
|
+
|
26
|
+
def page_size
|
27
|
+
3
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rdiscount'
|
2
|
+
|
3
|
+
module Blogical
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
def self.included(app)
|
7
|
+
app.helpers do
|
8
|
+
include Rack::Utils
|
9
|
+
alias_method :h, :escape_html
|
10
|
+
|
11
|
+
def markup(string)
|
12
|
+
RDiscount::new(string, :smart).to_html
|
13
|
+
end
|
14
|
+
|
15
|
+
def tags(post)
|
16
|
+
return '' unless post
|
17
|
+
tag_names = post.tags.collect { |tag| tag.name }
|
18
|
+
", #{tag_names.join(', ')}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def url(path)
|
22
|
+
request.script_name + path
|
23
|
+
end
|
24
|
+
|
25
|
+
def body_id
|
26
|
+
b_id = request.path_info.split('/')[1] || 'home'
|
27
|
+
b_id.to_i == 0 ? b_id : 'blog' # numerical paths are considered blog posts
|
28
|
+
end
|
29
|
+
|
30
|
+
def current_page?(page_number)
|
31
|
+
Integer(params['page']) == page_number
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
@charset "utf-8";
|
2
|
+
/* CSS Document */
|
3
|
+
|
4
|
+
body, html {
|
5
|
+
margin: 0;
|
6
|
+
padding: 0;
|
7
|
+
}
|
8
|
+
body {
|
9
|
+
font: 81% "Trebuchet MS", Helvetica, Arial, sans-serif;
|
10
|
+
color: #bcbcbc;
|
11
|
+
background: #090e11;
|
12
|
+
text-align: center;
|
13
|
+
}
|
14
|
+
a:link {
|
15
|
+
color: #CCF;
|
16
|
+
text-decoration: none;
|
17
|
+
}
|
18
|
+
a:visited {
|
19
|
+
color: #af2d33;
|
20
|
+
text-decoration: none;
|
21
|
+
}
|
22
|
+
a:active {
|
23
|
+
color: #ffb43d;
|
24
|
+
}
|
25
|
+
a:hover {
|
26
|
+
color: #FFFFFF;
|
27
|
+
text-decoration: underline;
|
28
|
+
}
|
29
|
+
#header {
|
30
|
+
height: 144px;
|
31
|
+
background: #bbbbbb url(/images/ui/banner.jpg) center top repeat-x;
|
32
|
+
border-bottom: 1px solid #9fadb3;
|
33
|
+
}
|
34
|
+
body#home #header {
|
35
|
+
height: 289px;
|
36
|
+
}
|
37
|
+
span#dotmesh {
|
38
|
+
display: block;
|
39
|
+
position: absolute;
|
40
|
+
top: 0;
|
41
|
+
left: 0;
|
42
|
+
width: 100%;
|
43
|
+
height: 144px;
|
44
|
+
margin: 0;
|
45
|
+
background: url(/images/ui/dot-mesh.png);
|
46
|
+
}
|
47
|
+
body#home span#dotmesh {
|
48
|
+
height: 289px;
|
49
|
+
}
|
50
|
+
h1, h2, h3, h4 {
|
51
|
+
font-family: Arial, Helvetica, sans-serif;
|
52
|
+
color: #fff;
|
53
|
+
font-weight: normal;
|
54
|
+
margin-top: 0;
|
55
|
+
padding-top: 1em;
|
56
|
+
}
|
57
|
+
h2 {
|
58
|
+
font-size: 2.0em;
|
59
|
+
background: url(/images/ui/content-divider.png) center top no-repeat;
|
60
|
+
margin: 1em 0 1em;
|
61
|
+
padding: 1em 0 0;
|
62
|
+
color: #FFF;
|
63
|
+
}
|
64
|
+
h3 {
|
65
|
+
font-size: 1.6em;
|
66
|
+
}
|
67
|
+
h1#logo {
|
68
|
+
position: absolute;
|
69
|
+
margin: 0;
|
70
|
+
padding: 0;
|
71
|
+
top: 22px;
|
72
|
+
left: 15px;
|
73
|
+
}
|
74
|
+
body#home h1#logo {
|
75
|
+
top: 45px;
|
76
|
+
left: 15px;
|
77
|
+
}
|
78
|
+
h1#logo a {
|
79
|
+
display: block;
|
80
|
+
width: 237px;
|
81
|
+
height: 0;
|
82
|
+
padding: 102px 0 0;
|
83
|
+
overflow: hidden;
|
84
|
+
background: url(/images/ui/ra-logo-mid.png) no-repeat;
|
85
|
+
}
|
86
|
+
body#home h1#logo a {
|
87
|
+
width: 473px;
|
88
|
+
padding: 201px 0 0;
|
89
|
+
background: url(/images/ui/ra-logo-large.png) no-repeat;
|
90
|
+
}
|
91
|
+
h1#logo img {
|
92
|
+
display: none;
|
93
|
+
}
|
94
|
+
p#tagline {
|
95
|
+
position: absolute;
|
96
|
+
top: 109px;
|
97
|
+
left: 159px;
|
98
|
+
width: 339px;
|
99
|
+
height: 0;
|
100
|
+
margin: 0;
|
101
|
+
padding: 19px 0 0;
|
102
|
+
overflow: hidden;
|
103
|
+
background: url(/images/ui/ra-tagline-mid.png) no-repeat;
|
104
|
+
}
|
105
|
+
body#home p#tagline {
|
106
|
+
top: 226px;
|
107
|
+
left: auto;
|
108
|
+
right: 15px;
|
109
|
+
width: 448px;
|
110
|
+
padding: 25px 0 0;
|
111
|
+
background: url(/images/ui/ra-tagline.png) no-repeat;
|
112
|
+
}
|
113
|
+
#main-content p {
|
114
|
+
line-height: 1.5em;
|
115
|
+
}
|
116
|
+
ul#navbar {
|
117
|
+
position: absolute;
|
118
|
+
top: 0;
|
119
|
+
right: 0;
|
120
|
+
margin: 0;
|
121
|
+
padding: 0;
|
122
|
+
list-style: none;
|
123
|
+
}
|
124
|
+
ul#navbar li {
|
125
|
+
float: left;
|
126
|
+
}
|
127
|
+
ul#navbar li a {
|
128
|
+
display: block;
|
129
|
+
height: 0;
|
130
|
+
padding: 45px 0 0;
|
131
|
+
overflow: hidden;
|
132
|
+
background: url(/images/ui/navbar.png) no-repeat;
|
133
|
+
}
|
134
|
+
ul#navbar li#nav-home a:link, ul#navbar li#nav-home a:visited {
|
135
|
+
width: 88px;
|
136
|
+
background-position: 0 0;
|
137
|
+
}
|
138
|
+
ul#navbar li#nav-home a.selected:link, ul#navbar li#nav-home a.selected:visited, ul#navbar li#nav-home a:hover {
|
139
|
+
background-position: 0 -45px;
|
140
|
+
}
|
141
|
+
ul#navbar li#nav-ruby a:link, ul#navbar li#nav-ruby a:visited {
|
142
|
+
width: 81px;
|
143
|
+
background-position: -88px 0;
|
144
|
+
}
|
145
|
+
ul#navbar li#nav-ruby a.selected:link, ul#navbar li#nav-ruby a.selected:visited, ul#navbar li#nav-ruby a:hover {
|
146
|
+
background-position: -88px -45px;
|
147
|
+
}
|
148
|
+
ul#navbar li#nav-iphone a:link, ul#navbar li#nav-iphone a:visited {
|
149
|
+
width: 95px;
|
150
|
+
background-position: -169px 0;
|
151
|
+
}
|
152
|
+
ul#navbar li#nav-iphone a.selected:link, ul#navbar li#nav-iphone a.selected:visited, ul#navbar li#nav-iphone a:hover {
|
153
|
+
background-position: -169px -45px;
|
154
|
+
}
|
155
|
+
ul#navbar li#nav-blog a:link, ul#navbar li#nav-blog a:visited {
|
156
|
+
width: 76px;
|
157
|
+
background-position: -264px 0;
|
158
|
+
}
|
159
|
+
ul#navbar li#nav-blog a.selected:link, ul#navbar li#nav-blog a.selected:visited, ul#navbar li#nav-blog a:hover {
|
160
|
+
background-position: -264px -45px;
|
161
|
+
}
|
162
|
+
ul#navbar li#nav-about a:link, ul#navbar li#nav-about a:visited {
|
163
|
+
width: 89px;
|
164
|
+
background-position: -340px 0;
|
165
|
+
}
|
166
|
+
ul#navbar li#nav-about a.selected:link, ul#navbar li#nav-about a.selected:visited, ul#navbar li#nav-about a:hover {
|
167
|
+
background-position: -340px -45px;
|
168
|
+
}
|
169
|
+
ul#navbar li#nav-contact a:link, ul#navbar li#nav-contact a:visited {
|
170
|
+
width: 105px;
|
171
|
+
background-position: -429px 0;
|
172
|
+
}
|
173
|
+
ul#navbar li#nav-contact a.selected:link, ul#navbar li#nav-contact a.selected:visited, ul#navbar li#nav-contact a:hover {
|
174
|
+
background-position: -429px -45px;
|
175
|
+
}
|
176
|
+
div.main-container {
|
177
|
+
position: relative;
|
178
|
+
width: 960px;
|
179
|
+
text-align: left;
|
180
|
+
margin: 0 auto;
|
181
|
+
overflow: auto;
|
182
|
+
}
|
183
|
+
div#header div.main-container {
|
184
|
+
overflow: visible;
|
185
|
+
}
|
186
|
+
div#main-content {
|
187
|
+
background: url(/images/ui/content-glow-large.jpg) center top no-repeat;
|
188
|
+
clear: both;
|
189
|
+
}
|
190
|
+
body#home div#main-content {
|
191
|
+
background: url(/images/ui/content-glow-w-header.jpg) center top no-repeat;
|
192
|
+
}
|
193
|
+
.inset {
|
194
|
+
padding: 15px;
|
195
|
+
}
|
196
|
+
.col-1-2 {
|
197
|
+
float: left;
|
198
|
+
width: 450px;
|
199
|
+
padding: 15px;
|
200
|
+
}
|
201
|
+
.col-1-3 {
|
202
|
+
float: left;
|
203
|
+
width: 290px;
|
204
|
+
padding: 15px;
|
205
|
+
}
|
206
|
+
.col-1-5 {
|
207
|
+
float: left;
|
208
|
+
width: 162px;
|
209
|
+
padding: 15px;
|
210
|
+
}
|
211
|
+
.first-row {
|
212
|
+
padding-top: 0;
|
213
|
+
}
|
214
|
+
div#footer {
|
215
|
+
background: url(/images/ui/content-glow-small.jpg) center top no-repeat;
|
216
|
+
clear: both;
|
217
|
+
padding: 0 0 30px;
|
218
|
+
font-family: Arial, Helvetica, sans-serif;
|
219
|
+
font-size: .85em;
|
220
|
+
}
|
221
|
+
#footer dl {
|
222
|
+
margin: 15px 0 2em;
|
223
|
+
}
|
224
|
+
#footer dt {
|
225
|
+
font-weight: bold;
|
226
|
+
color: #3c484c;
|
227
|
+
margin: 0 0 1em;
|
228
|
+
}
|
229
|
+
#footer dd {
|
230
|
+
margin: 1em 0 1em 15px;
|
231
|
+
padding: 0;
|
232
|
+
color: #778f99;
|
233
|
+
}
|
234
|
+
#footer dd a {
|
235
|
+
color: #778f99;
|
236
|
+
}
|
237
|
+
div#footer p {
|
238
|
+
margin: 0;
|
239
|
+
}
|
240
|
+
div#footer p#mini-logo {
|
241
|
+
margin: 5px 0 .5em;
|
242
|
+
}
|
243
|
+
div#footer p#copyright {
|
244
|
+
margin: .5em 0;
|
245
|
+
color: #3c484c;
|
246
|
+
text-align: center;
|
247
|
+
}
|
248
|
+
div#footer p#mini-tagline {
|
249
|
+
margin: .5em 0;
|
250
|
+
font-weight: bold;
|
251
|
+
color: #3c484c;
|
252
|
+
text-align: center;
|
253
|
+
}
|
254
|
+
|
255
|
+
h2.title {
|
256
|
+
margin-top: 0;
|
257
|
+
margin-left: -15px;
|
258
|
+
margin-bottom: .5em;
|
259
|
+
padding: 25px 0 0;
|
260
|
+
background: none;
|
261
|
+
}
|
262
|
+
h2.title a {
|
263
|
+
display: block;
|
264
|
+
height: 0;
|
265
|
+
padding: 85px 0 0;
|
266
|
+
background-repeat: no-repeat;
|
267
|
+
overflow: hidden;
|
268
|
+
}
|
269
|
+
|
270
|
+
h3.title {
|
271
|
+
background: none;
|
272
|
+
padding: 0;
|
273
|
+
}
|
274
|
+
h3.title a {
|
275
|
+
display: block;
|
276
|
+
height: 0;
|
277
|
+
padding: 27px 0 0;
|
278
|
+
background-repeat: no-repeat;
|
279
|
+
overflow: hidden;
|
280
|
+
}
|
281
|
+
|
282
|
+
div.divider {
|
283
|
+
position: relative;
|
284
|
+
clear: both;
|
285
|
+
height: 0;
|
286
|
+
margin: 0;
|
287
|
+
padding: 3px 0 0;
|
288
|
+
overflow: hidden;
|
289
|
+
background: url(/images/ui/content-divider.png) center top no-repeat;
|
290
|
+
}
|
291
|
+
div.divider hr {
|
292
|
+
margin: 0;
|
293
|
+
display: none;
|
294
|
+
}
|
295
|
+
#blog pre {
|
296
|
+
position: relative;
|
297
|
+
width: 920px;
|
298
|
+
padding: 8px;
|
299
|
+
white-space: pre;
|
300
|
+
overflow: auto;
|
301
|
+
background: #223;
|
302
|
+
border: 1px solid #778;
|
303
|
+
color: #eec;
|
304
|
+
line-height: 1.5em;
|
305
|
+
}
|
306
|
+
#blog .vcard {
|
307
|
+
font-style: italic;
|
308
|
+
float: right;
|
309
|
+
position: relative;
|
310
|
+
top: -2em;
|
311
|
+
margin: -2em 0 0;
|
312
|
+
color: #fff;
|
313
|
+
}
|
314
|
+
#blog .pagination {
|
315
|
+
margin: 1em 0;
|
316
|
+
padding: 1em 0 .5em;
|
317
|
+
text-align: center;
|
318
|
+
background: url(/images/ui/content-divider.png) center top no-repeat;
|
319
|
+
}
|
320
|
+
#blog .pagination a {
|
321
|
+
display: inline-block;
|
322
|
+
padding: 5px 9px;
|
323
|
+
margin: 0 3px;
|
324
|
+
font-size: 1.2em;
|
325
|
+
font-weight: bold;
|
326
|
+
}
|
327
|
+
|
328
|
+
.stand-out {
|
329
|
+
font-size: 1.3em;
|
330
|
+
}
|
@@ -0,0 +1,137 @@
|
|
1
|
+
pre.twilight .DiffInserted {
|
2
|
+
background-color: #253B22;
|
3
|
+
color: #F8F8F8;
|
4
|
+
}
|
5
|
+
pre.twilight .DiffHeader {
|
6
|
+
background-color: #0E2231;
|
7
|
+
color: #F8F8F8;
|
8
|
+
font-style: italic;
|
9
|
+
}
|
10
|
+
pre.twilight .CssPropertyValue {
|
11
|
+
color: #F9EE98;
|
12
|
+
}
|
13
|
+
pre.twilight .CCCPreprocessorDirective {
|
14
|
+
color: #AFC4DB;
|
15
|
+
}
|
16
|
+
pre.twilight .Constant {
|
17
|
+
color: #CF6A4C;
|
18
|
+
}
|
19
|
+
pre.twilight .DiffChanged {
|
20
|
+
background-color: #4A410D;
|
21
|
+
color: #F8F8F8;
|
22
|
+
}
|
23
|
+
pre.twilight .EmbeddedSource {
|
24
|
+
background-color: #A3A6AD;
|
25
|
+
}
|
26
|
+
pre.twilight .Support {
|
27
|
+
color: #9B859D;
|
28
|
+
}
|
29
|
+
pre.twilight .MarkupList {
|
30
|
+
color: #F9EE98;
|
31
|
+
}
|
32
|
+
pre.twilight .CssConstructorArgument {
|
33
|
+
color: #8F9D6A;
|
34
|
+
}
|
35
|
+
pre.twilight .Storage {
|
36
|
+
color: #F9EE98;
|
37
|
+
}
|
38
|
+
pre.twilight .line-numbers {
|
39
|
+
background-color: #DDF0FF;
|
40
|
+
color: #000000;
|
41
|
+
}
|
42
|
+
pre.twilight .CssClass {
|
43
|
+
color: #9B703F;
|
44
|
+
}
|
45
|
+
pre.twilight .StringConstant {
|
46
|
+
color: #DDF2A4;
|
47
|
+
}
|
48
|
+
pre.twilight .CssAtRule {
|
49
|
+
color: #8693A5;
|
50
|
+
}
|
51
|
+
pre.twilight .MetaTagInline {
|
52
|
+
color: #E0C589;
|
53
|
+
}
|
54
|
+
pre.twilight .MarkupHeading {
|
55
|
+
color: #CF6A4C;
|
56
|
+
}
|
57
|
+
pre.twilight .CssTagName {
|
58
|
+
color: #CDA869;
|
59
|
+
}
|
60
|
+
pre.twilight .SupportConstant {
|
61
|
+
color: #CF6A4C;
|
62
|
+
}
|
63
|
+
pre.twilight .DiffDeleted {
|
64
|
+
background-color: #420E09;
|
65
|
+
color: #F8F8F8;
|
66
|
+
}
|
67
|
+
pre.twilight .CCCPreprocessorLine {
|
68
|
+
color: #8996A8;
|
69
|
+
}
|
70
|
+
pre.twilight .StringRegexpSpecial {
|
71
|
+
color: #CF7D34;
|
72
|
+
}
|
73
|
+
pre.twilight .EmbeddedSourceBright {
|
74
|
+
background-color: #9C9EA4;
|
75
|
+
}
|
76
|
+
pre.twilight .InvalidIllegal {
|
77
|
+
background-color: #241A24;
|
78
|
+
color: #F8F8F8;
|
79
|
+
}
|
80
|
+
pre.twilight .SupportFunction {
|
81
|
+
color: #DAD085;
|
82
|
+
}
|
83
|
+
pre.twilight .CssAdditionalConstants {
|
84
|
+
color: #CA7840;
|
85
|
+
}
|
86
|
+
pre.twilight .MetaTagAll {
|
87
|
+
color: #AC885B;
|
88
|
+
}
|
89
|
+
pre.twilight .StringRegexp {
|
90
|
+
color: #E9C062;
|
91
|
+
}
|
92
|
+
pre.twilight .StringEmbeddedSource {
|
93
|
+
color: #DAEFA3;
|
94
|
+
}
|
95
|
+
pre.twilight .EntityInheritedClass {
|
96
|
+
color: #9B5C2E;
|
97
|
+
font-style: italic;
|
98
|
+
}
|
99
|
+
pre.twilight .CssId {
|
100
|
+
color: #8B98AB;
|
101
|
+
}
|
102
|
+
pre.twilight .CssPseudoClass {
|
103
|
+
color: #8F9D6A;
|
104
|
+
}
|
105
|
+
pre.twilight .StringVariable {
|
106
|
+
color: #8A9A95;
|
107
|
+
}
|
108
|
+
pre.twilight .String {
|
109
|
+
color: #8F9D6A;
|
110
|
+
}
|
111
|
+
pre.twilight .Keyword {
|
112
|
+
color: #CDA869;
|
113
|
+
}
|
114
|
+
pre.twilight {
|
115
|
+
background-color: #141414;
|
116
|
+
color: #F8F8F8;
|
117
|
+
}
|
118
|
+
pre.twilight .CssPropertyName {
|
119
|
+
color: #C5AF75;
|
120
|
+
}
|
121
|
+
pre.twilight .DoctypeXmlProcessing {
|
122
|
+
color: #494949;
|
123
|
+
}
|
124
|
+
pre.twilight .InvalidDeprecated {
|
125
|
+
color: #D2A8A1;
|
126
|
+
font-style: italic;
|
127
|
+
}
|
128
|
+
pre.twilight .Variable {
|
129
|
+
color: #7587A6;
|
130
|
+
}
|
131
|
+
pre.twilight .Entity {
|
132
|
+
color: #9B703F;
|
133
|
+
}
|
134
|
+
pre.twilight .Comment {
|
135
|
+
color: #5F5A60;
|
136
|
+
font-style: italic;
|
137
|
+
}
|
@@ -0,0 +1,187 @@
|
|
1
|
+
<public:component>
|
2
|
+
<script type="text/javascript">
|
3
|
+
|
4
|
+
// IE5.5+ PNG Alpha Fix v2.0 Alpha
|
5
|
+
// (c) 2004-2008 Angus Turnbull http://www.twinhelix.com
|
6
|
+
|
7
|
+
// This is licensed under the GNU LGPL, version 2.1 or later.
|
8
|
+
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
|
9
|
+
|
10
|
+
var IEPNGFix = window.IEPNGFix || {};
|
11
|
+
IEPNGFix.data = IEPNGFix.data || {};
|
12
|
+
|
13
|
+
|
14
|
+
// This must be a path to a blank image, relative to the HTML document(s).
|
15
|
+
// In production use I suggest '/images/blank.gif' or similar. That's all!
|
16
|
+
IEPNGFix.blankImg = '/scripts/blank.gif';
|
17
|
+
|
18
|
+
|
19
|
+
IEPNGFix.fix = function(elm, src, t) {
|
20
|
+
// Applies an image 'src' to an element 'elm' using the DirectX filter.
|
21
|
+
// If 'src' is null, filter is disabled.
|
22
|
+
// Disables the 'hook' to prevent infinite recursion on setting BG/src.
|
23
|
+
// 't' = type, where background tile = 0, background = 1, IMG SRC = 2.
|
24
|
+
|
25
|
+
var h = this.hook.enabled;
|
26
|
+
this.hook.enabled = 0;
|
27
|
+
|
28
|
+
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
|
29
|
+
src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');
|
30
|
+
|
31
|
+
if (
|
32
|
+
src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&
|
33
|
+
elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'
|
34
|
+
) {
|
35
|
+
elm.style.width = elm.offsetWidth + 'px';
|
36
|
+
elm.style.height = elm.clientHeight + 'px';
|
37
|
+
if (elm.currentStyle.display == 'inline') {
|
38
|
+
elm.style.display = 'inline-block';
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if (t == 1) {
|
43
|
+
elm.style.backgroundImage = 'url("' + this.blankImg + '")';
|
44
|
+
}
|
45
|
+
if (t == 2) {
|
46
|
+
elm.src = this.blankImg;
|
47
|
+
}
|
48
|
+
|
49
|
+
if (elm.filters[f]) {
|
50
|
+
elm.filters[f].enabled = src ? true : false;
|
51
|
+
if (src) {
|
52
|
+
elm.filters[f].src = src;
|
53
|
+
}
|
54
|
+
} else if (src) {
|
55
|
+
elm.style.filter = 'progid:' + f + '(src="' + src +
|
56
|
+
'",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';
|
57
|
+
}
|
58
|
+
|
59
|
+
this.hook.enabled = h;
|
60
|
+
};
|
61
|
+
|
62
|
+
|
63
|
+
IEPNGFix.process = function(elm, init) {
|
64
|
+
// Checks the onpropertychange event (on first 'init' run, a fake event)
|
65
|
+
// and calls the filter-applying-functions.
|
66
|
+
|
67
|
+
if (
|
68
|
+
!/MSIE (5\.5|6)/.test(navigator.userAgent) ||
|
69
|
+
typeof elm.filters == 'unknown'
|
70
|
+
) {
|
71
|
+
return;
|
72
|
+
}
|
73
|
+
if (!this.data[elm.uniqueID]) {
|
74
|
+
this.data[elm.uniqueID] = {
|
75
|
+
className: ''
|
76
|
+
};
|
77
|
+
}
|
78
|
+
var data = this.data[elm.uniqueID],
|
79
|
+
evt = init ? { propertyName: 'src,backgroundImage' } : event,
|
80
|
+
isSrc = /src/.test(evt.propertyName),
|
81
|
+
isBg = /backgroundImage/.test(evt.propertyName),
|
82
|
+
isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),
|
83
|
+
isClass = !init && ((elm.className != data.className) &&
|
84
|
+
(elm.className || data.className));
|
85
|
+
if (!(isSrc || isBg || isPos || isClass)) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
data.className = elm.className;
|
89
|
+
var blank = this.blankImg.match(/([^\/]+)$/)[1],
|
90
|
+
eS = elm.style,
|
91
|
+
eCS = elm.currentStyle;
|
92
|
+
|
93
|
+
// Required for Whatever:hover - erase set BG if className changes.
|
94
|
+
if (
|
95
|
+
isClass && (eS.backgroundImage.indexOf('url(') == -1 ||
|
96
|
+
eS.backgroundImage.indexOf(blank) > -1)
|
97
|
+
) {
|
98
|
+
return setTimeout(function() {
|
99
|
+
eS.backgroundImage = '';
|
100
|
+
}, 0);
|
101
|
+
}
|
102
|
+
|
103
|
+
// Foregrounds.
|
104
|
+
if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {
|
105
|
+
if ((/\.png/i).test(elm.src)) {
|
106
|
+
this.fix(elm, elm.src, 2);
|
107
|
+
} else if (elm.src.indexOf(blank) == -1) {
|
108
|
+
this.fix(elm, '');
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
// Backgrounds.
|
113
|
+
var bgSrc = eCS.backgroundImage || eS.backgroundImage;
|
114
|
+
if ((bgSrc + elm.src).indexOf(blank) == -1) {
|
115
|
+
var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
|
116
|
+
if (bgPNG) {
|
117
|
+
if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {
|
118
|
+
this.tileBG(elm, bgPNG[1]);
|
119
|
+
this.fix(elm, '', 1);
|
120
|
+
} else {
|
121
|
+
if (data.tiles && data.tiles.src) {
|
122
|
+
this.tileBG(elm, '');
|
123
|
+
}
|
124
|
+
this.fix(elm, bgPNG[1], 1);
|
125
|
+
this.childFix(elm);
|
126
|
+
}
|
127
|
+
} else {
|
128
|
+
if (data.tiles && data.tiles.src) {
|
129
|
+
this.tileBG(elm, '');
|
130
|
+
}
|
131
|
+
this.fix(elm, '');
|
132
|
+
}
|
133
|
+
} else if ((isPos || isClass) && data.tiles && data.tiles.src) {
|
134
|
+
this.tileBG(elm, data.tiles.src);
|
135
|
+
}
|
136
|
+
|
137
|
+
if (init) {
|
138
|
+
this.hook.enabled = 1;
|
139
|
+
elm.attachEvent('onpropertychange', this.hook);
|
140
|
+
}
|
141
|
+
};
|
142
|
+
|
143
|
+
|
144
|
+
IEPNGFix.childFix = function(elm) {
|
145
|
+
// "hasLayout" fix for unclickable children inside PNG backgrounds.
|
146
|
+
var tags = [
|
147
|
+
'a',
|
148
|
+
'input',
|
149
|
+
'select',
|
150
|
+
'textarea',
|
151
|
+
'button',
|
152
|
+
'iframe',
|
153
|
+
'object'
|
154
|
+
],
|
155
|
+
t = tags.length,
|
156
|
+
tFix = [];
|
157
|
+
while (t--) {
|
158
|
+
var pFix = elm.all.tags(tags[t]),
|
159
|
+
e = pFix.length;
|
160
|
+
while (e--) {
|
161
|
+
tFix.push(pFix[e]);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
t = tFix.length;
|
165
|
+
if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {
|
166
|
+
alert('IEPNGFix: Unclickable children of element:' +
|
167
|
+
'\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');
|
168
|
+
}
|
169
|
+
while (t--) {
|
170
|
+
if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {
|
171
|
+
tFix[t].style.position = 'relative';
|
172
|
+
}
|
173
|
+
}
|
174
|
+
};
|
175
|
+
|
176
|
+
|
177
|
+
IEPNGFix.hook = function() {
|
178
|
+
if (IEPNGFix.hook.enabled) {
|
179
|
+
IEPNGFix.process(element, 0);
|
180
|
+
}
|
181
|
+
};
|
182
|
+
|
183
|
+
|
184
|
+
IEPNGFix.process(element, 1);
|
185
|
+
|
186
|
+
</script>
|
187
|
+
</public:component>
|
@@ -0,0 +1,173 @@
|
|
1
|
+
// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support
|
2
|
+
// (c) 2008 Angus Turnbull http://www.twinhelix.com
|
3
|
+
|
4
|
+
// This is licensed under the GNU LGPL, version 2.1 or later.
|
5
|
+
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
|
6
|
+
|
7
|
+
var IEPNGFix = window.IEPNGFix || {};
|
8
|
+
|
9
|
+
IEPNGFix.tileBG = function(elm, pngSrc, ready) {
|
10
|
+
// Params: A reference to a DOM element, the PNG src file pathname, and a
|
11
|
+
// hidden "ready-to-run" passed when called back after image preloading.
|
12
|
+
|
13
|
+
var data = this.data[elm.uniqueID],
|
14
|
+
elmW = Math.max(elm.clientWidth, elm.scrollWidth),
|
15
|
+
elmH = Math.max(elm.clientHeight, elm.scrollHeight),
|
16
|
+
bgX = elm.currentStyle.backgroundPositionX,
|
17
|
+
bgY = elm.currentStyle.backgroundPositionY,
|
18
|
+
bgR = elm.currentStyle.backgroundRepeat;
|
19
|
+
|
20
|
+
// Cache of DIVs created per element, and image preloader/data.
|
21
|
+
if (!data.tiles) {
|
22
|
+
data.tiles = {
|
23
|
+
elm: elm,
|
24
|
+
src: '',
|
25
|
+
cache: [],
|
26
|
+
img: new Image(),
|
27
|
+
old: {}
|
28
|
+
};
|
29
|
+
}
|
30
|
+
var tiles = data.tiles,
|
31
|
+
pngW = tiles.img.width,
|
32
|
+
pngH = tiles.img.height;
|
33
|
+
|
34
|
+
if (pngSrc) {
|
35
|
+
if (!ready && pngSrc != tiles.src) {
|
36
|
+
// New image? Preload it with a callback to detect dimensions.
|
37
|
+
tiles.img.onload = function() {
|
38
|
+
this.onload = null;
|
39
|
+
IEPNGFix.tileBG(elm, pngSrc, 1);
|
40
|
+
};
|
41
|
+
return tiles.img.src = pngSrc;
|
42
|
+
}
|
43
|
+
} else {
|
44
|
+
// No image?
|
45
|
+
if (tiles.src) ready = 1;
|
46
|
+
pngW = pngH = 0;
|
47
|
+
}
|
48
|
+
tiles.src = pngSrc;
|
49
|
+
|
50
|
+
if (!ready && elmW == tiles.old.w && elmH == tiles.old.h &&
|
51
|
+
bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
|
55
|
+
// Convert English and percentage positions to pixels.
|
56
|
+
var pos = {
|
57
|
+
top: '0%',
|
58
|
+
left: '0%',
|
59
|
+
center: '50%',
|
60
|
+
bottom: '100%',
|
61
|
+
right: '100%'
|
62
|
+
},
|
63
|
+
x,
|
64
|
+
y,
|
65
|
+
pc;
|
66
|
+
x = pos[bgX] || bgX;
|
67
|
+
y = pos[bgY] || bgY;
|
68
|
+
if (pc = x.match(/(\d+)%/)) {
|
69
|
+
x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100));
|
70
|
+
}
|
71
|
+
if (pc = y.match(/(\d+)%/)) {
|
72
|
+
y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100));
|
73
|
+
}
|
74
|
+
x = parseInt(x);
|
75
|
+
y = parseInt(y);
|
76
|
+
|
77
|
+
// Handle backgroundRepeat.
|
78
|
+
var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR],
|
79
|
+
repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];
|
80
|
+
if (repeatX) {
|
81
|
+
x %= pngW;
|
82
|
+
if (x > 0) x -= pngW;
|
83
|
+
}
|
84
|
+
if (repeatY) {
|
85
|
+
y %= pngH;
|
86
|
+
if (y > 0) y -= pngH;
|
87
|
+
}
|
88
|
+
|
89
|
+
// Go!
|
90
|
+
this.hook.enabled = 0;
|
91
|
+
if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) {
|
92
|
+
elm.style.position = 'relative';
|
93
|
+
}
|
94
|
+
var count = 0,
|
95
|
+
xPos,
|
96
|
+
maxX = repeatX ? elmW : x + 0.1,
|
97
|
+
yPos,
|
98
|
+
maxY = repeatY ? elmH : y + 0.1,
|
99
|
+
d,
|
100
|
+
s,
|
101
|
+
isNew;
|
102
|
+
if (pngW && pngH) {
|
103
|
+
for (xPos = x; xPos < maxX; xPos += pngW) {
|
104
|
+
for (yPos = y; yPos < maxY; yPos += pngH) {
|
105
|
+
isNew = 0;
|
106
|
+
if (!tiles.cache[count]) {
|
107
|
+
tiles.cache[count] = document.createElement('div');
|
108
|
+
isNew = 1;
|
109
|
+
}
|
110
|
+
var clipR = (xPos + pngW > elmW ? elmW - xPos : pngW),
|
111
|
+
clipB = (yPos + pngH > elmH ? elmH - yPos : pngH);
|
112
|
+
d = tiles.cache[count];
|
113
|
+
s = d.style;
|
114
|
+
s.behavior = 'none';
|
115
|
+
s.left = xPos + 'px';
|
116
|
+
s.top = yPos + 'px';
|
117
|
+
s.width = clipR + 'px';
|
118
|
+
s.height = clipB + 'px';
|
119
|
+
s.clip = 'rect(' +
|
120
|
+
(yPos < 0 ? 0 - yPos : 0) + 'px,' +
|
121
|
+
clipR + 'px,' +
|
122
|
+
clipB + 'px,' +
|
123
|
+
(xPos < 0 ? 0 - xPos : 0) + 'px)';
|
124
|
+
s.display = 'block';
|
125
|
+
if (isNew) {
|
126
|
+
s.position = 'absolute';
|
127
|
+
s.zIndex = -999;
|
128
|
+
if (elm.firstChild) {
|
129
|
+
elm.insertBefore(d, elm.firstChild);
|
130
|
+
} else {
|
131
|
+
elm.appendChild(d);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
this.fix(d, pngSrc, 0);
|
135
|
+
count++;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
while (count < tiles.cache.length) {
|
140
|
+
this.fix(tiles.cache[count], '', 0);
|
141
|
+
tiles.cache[count++].style.display = 'none';
|
142
|
+
}
|
143
|
+
|
144
|
+
this.hook.enabled = 1;
|
145
|
+
|
146
|
+
// Cache so updates are infrequent.
|
147
|
+
tiles.old = {
|
148
|
+
w: elmW,
|
149
|
+
h: elmH,
|
150
|
+
x: bgX,
|
151
|
+
y: bgY,
|
152
|
+
r: bgR
|
153
|
+
};
|
154
|
+
};
|
155
|
+
|
156
|
+
|
157
|
+
IEPNGFix.update = function() {
|
158
|
+
// Update all PNG backgrounds.
|
159
|
+
for (var i in IEPNGFix.data) {
|
160
|
+
var t = IEPNGFix.data[i].tiles;
|
161
|
+
if (t && t.elm && t.src) {
|
162
|
+
IEPNGFix.tileBG(t.elm, t.src);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
};
|
166
|
+
IEPNGFix.update.timer = 0;
|
167
|
+
|
168
|
+
if (window.attachEvent && !window.opera) {
|
169
|
+
window.attachEvent('onresize', function() {
|
170
|
+
clearTimeout(IEPNGFix.update.timer);
|
171
|
+
IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100);
|
172
|
+
});
|
173
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<div class="content">
|
2
|
+
<div class="hentry">
|
3
|
+
<h2><%=h @post.title %></h2>
|
4
|
+
<div class="vcard">
|
5
|
+
posted by <a href="mailto:<%= @post.email %>"><%= @post.nickname %></a>, <span class="published"><%=h @post.posted.to_s(:posted) %></span>
|
6
|
+
</div>
|
7
|
+
<%= markup(File.read(@post.content)) %>
|
8
|
+
</div>
|
9
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="content">
|
2
|
+
<% @posts.each do |post| %>
|
3
|
+
<div class="hentry">
|
4
|
+
<h2><a href="<%= post.url %>"><%=h post.title %></a></h2>
|
5
|
+
<div class="vcard">
|
6
|
+
posted by <a href="mailto:<%= post.email %>"><%= post.nickname %></a>, <span class="published"><%= h post.posted.to_s(:posted) %></span>
|
7
|
+
</div>
|
8
|
+
<%= markup File.read(post.content) %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<div class="pagination">
|
13
|
+
<% @pages.times do |i| %>
|
14
|
+
<a <%= 'id="selected"' if current_page?(i + 1) %> href="/blog?page=<%= i + 1 %>"><%= i + 1 %></a>
|
15
|
+
<% end %>
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<meta name="description" content="<%= Array(blog.description_tags)*', '%>" />
|
6
|
+
<meta name="keywords" content="<%= (Array(blog.keyword_tags) + Array(@post_tags))*', '%>" />
|
7
|
+
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
8
|
+
<style> article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } </style>
|
9
|
+
|
10
|
+
<% blog = Blogical::Application %>
|
11
|
+
<title><%= blog.title %></title>
|
12
|
+
|
13
|
+
<!-- Need HTML5 links here -->
|
14
|
+
<link type="text/css" rel="stylesheet" href="/css/screen.css" />
|
15
|
+
<link type="text/css" rel="stylesheet" href="/css/twilight.css" />
|
16
|
+
<link rel="icon" type="image/vnd.microsoft.icon" href="/favicon.ico" />
|
17
|
+
<link rel="icon" type="image/png" href="/favicon.png" />
|
18
|
+
<link href="/blog/atom.xml" rel="alternate" type="application/atom+xml" />
|
19
|
+
<!--[if lt IE 7]><script type="text/javascript" src="/scripts/iepngfix.tilebg.js"></script>
|
20
|
+
<style type="text/css">
|
21
|
+
img, div, a, p, h1, h2, li, span { behavior: url(/scripts/iepngfix.htc); }
|
22
|
+
</style><![endif]-->
|
23
|
+
</head>
|
24
|
+
|
25
|
+
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"/>
|
26
|
+
<script type="text/javascript">
|
27
|
+
_uacct = <%= blog.urchin_account_id %>;
|
28
|
+
urchinTracker();
|
29
|
+
</script>
|
30
|
+
|
31
|
+
<body id="<%= body_id %>">
|
32
|
+
<div id="header">
|
33
|
+
<!-- Put your header code here -->
|
34
|
+
</div>
|
35
|
+
<div class="main-container">
|
36
|
+
<%= yield %>
|
37
|
+
</div>
|
38
|
+
<div id="footer">
|
39
|
+
<!-- Put your footer code here -->
|
40
|
+
</div>
|
41
|
+
</body>
|
42
|
+
</html>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blogical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Clifford Heath
|
@@ -33,10 +33,24 @@ files:
|
|
33
33
|
- Gemfile
|
34
34
|
- README.markdown
|
35
35
|
- config.ru
|
36
|
+
- app/blogical/atom.rb
|
37
|
+
- app/blogical/blog.rb
|
38
|
+
- app/blogical/content.rb
|
39
|
+
- app/blogical/extensions.rb
|
40
|
+
- app/blogical/helpers.rb
|
36
41
|
- app/blogical.rb
|
42
|
+
- content/01 Welcome/content.markdown
|
43
|
+
- content/01 Welcome/meta.rb
|
37
44
|
- logs/access.log
|
38
45
|
- logs/error.log
|
46
|
+
- public/css/screen.css
|
47
|
+
- public/css/twilight.css
|
48
|
+
- public/scripts/iepngfix.htc
|
49
|
+
- public/scripts/iepngfix.tilebg.js
|
39
50
|
- tmp/restart.txt
|
51
|
+
- views/blogical/article.erb
|
52
|
+
- views/blogical/blog.erb
|
53
|
+
- views/blogical/layout.erb
|
40
54
|
has_rdoc: true
|
41
55
|
homepage: http://github.com/cjheath/blogical
|
42
56
|
licenses: []
|