broadway 0.0.3.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +155 -0
- data/lib/broadway.rb +64 -4
- data/lib/broadway/{core_ext.rb → ext.rb} +40 -6
- data/lib/broadway/filters/erb.rb +10 -0
- data/lib/broadway/filters/haml.rb +10 -0
- data/lib/broadway/filters/liquid.rb +14 -0
- data/lib/broadway/filters/markdown.rb +10 -0
- data/lib/broadway/filters/textile.rb +11 -0
- data/lib/broadway/migrators/blogger.rb +7 -0
- data/lib/broadway/migrators/wordpress.rb +7 -0
- data/lib/broadway/mixins/assetable.rb +48 -0
- data/lib/broadway/mixins/configurable.rb +32 -0
- data/lib/broadway/mixins/convertible.rb +25 -0
- data/lib/broadway/mixins/hierarchical.rb +61 -0
- data/lib/broadway/mixins/layoutable.rb +18 -0
- data/lib/broadway/mixins/pageable.rb +5 -0
- data/lib/broadway/mixins/processable.rb +44 -0
- data/lib/broadway/mixins/publishable.rb +36 -0
- data/lib/broadway/mixins/readable.rb +73 -0
- data/lib/broadway/mixins/resourceful.rb +27 -0
- data/lib/broadway/mixins/sluggable.rb +36 -0
- data/lib/broadway/mixins/sortable.rb +24 -0
- data/lib/broadway/mixins/taggable.rb +46 -0
- data/lib/broadway/mixins/themeable.rb +39 -0
- data/lib/broadway/processors/link.rb +45 -0
- data/lib/broadway/processors/post.rb +117 -0
- data/lib/broadway/processors/site.rb +77 -0
- data/lib/broadway/processors/tree.rb +121 -0
- data/lib/broadway/resources/asset.rb +28 -0
- data/lib/broadway/resources/configuration.rb +114 -0
- data/lib/broadway/resources/file.rb +88 -0
- data/lib/broadway/resources/layout.rb +28 -0
- data/lib/broadway/resources/link.rb +16 -0
- data/lib/broadway/resources/post.rb +63 -0
- data/lib/broadway/resources/site.rb +164 -0
- data/lib/broadway/resources/slug.rb +69 -0
- data/lib/broadway/sinatra/app.rb +21 -0
- data/lib/broadway/sinatra/helpers/collection_helper.rb +2 -1
- data/lib/broadway/sinatra/helpers/partial_helper.rb +5 -5
- data/lib/broadway/sinatra/helpers/text_helper.rb +5 -11
- data/lib/broadway/sinatra/processor.rb +84 -0
- data/lib/broadway/tasks.rb +1 -0
- data/lib/broadway/tasks/default.rake +85 -0
- metadata +46 -41
- data/README.textile +0 -306
- data/Rakefile +0 -85
- data/lib/broadway/api.rb +0 -51
- data/lib/broadway/asset.rb +0 -17
- data/lib/broadway/base.rb +0 -120
- data/lib/broadway/convertible.rb +0 -91
- data/lib/broadway/page.rb +0 -71
- data/lib/broadway/post.rb +0 -112
- data/lib/broadway/rails.rb +0 -3
- data/lib/broadway/resource.rb +0 -128
- data/lib/broadway/runner.rb +0 -62
- data/lib/broadway/sinatra.rb +0 -5
- data/lib/broadway/sinatra/base.rb +0 -90
- data/lib/broadway/sinatra/helpers.rb +0 -7
- data/lib/broadway/site.rb +0 -421
- data/lib/broadway/static_file.rb +0 -32
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rdiscount'
|
2
|
+
require 'redcloth'
|
3
|
+
module Broadway
|
4
|
+
|
5
|
+
class File
|
6
|
+
attr_accessor :site, :path, :directory, :extension, :categories, :name, :slug, :parent, :date
|
7
|
+
|
8
|
+
SRC_MATCHER = /^(.+\/)*(?:(\d+-\d+-\d+)-)?(.*)\.([^.]+)$/
|
9
|
+
URL_MATCHER = /^(.+\/)*(.*)$/
|
10
|
+
|
11
|
+
def initialize(site, options = {})
|
12
|
+
self.site = site
|
13
|
+
self.path = options[:file] || options[:path]
|
14
|
+
|
15
|
+
site_source = self.site.source
|
16
|
+
self.name = ::File.basename(self.path)
|
17
|
+
self.directory = ::File.dirname(self.path)
|
18
|
+
|
19
|
+
n, cats, date, slug, extension = *self.path.match(SRC_MATCHER)
|
20
|
+
|
21
|
+
self.parent = self.directory.gsub(/#{site_source}/, "").squeeze("/")
|
22
|
+
self.date = Time.parse(date) if date
|
23
|
+
|
24
|
+
base = self.parent.blank? ? "" : self.parent
|
25
|
+
|
26
|
+
self.categories = base.split('/').reject { |x| x.empty? }
|
27
|
+
self.slug = slug
|
28
|
+
self.extension = extension
|
29
|
+
end
|
30
|
+
|
31
|
+
def header
|
32
|
+
content = IO.read(self.path)
|
33
|
+
|
34
|
+
if content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
35
|
+
YAML.load($1)
|
36
|
+
else
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def read(attribute = nil)
|
42
|
+
content = IO.read(self.path)
|
43
|
+
if content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
44
|
+
if attribute
|
45
|
+
output = YAML.load($1)[attribute] || ""
|
46
|
+
return output
|
47
|
+
end
|
48
|
+
content = content[($1.size + $2.size)..-1]
|
49
|
+
end
|
50
|
+
content
|
51
|
+
end
|
52
|
+
|
53
|
+
def render(attribute = nil, extension = self.extension)
|
54
|
+
content = read(attribute)
|
55
|
+
case extension.to_s
|
56
|
+
when "markdown", "md"
|
57
|
+
content = RDiscount.new(content).to_html
|
58
|
+
when "textile"
|
59
|
+
content = RedCloth.new(content).to_html
|
60
|
+
end
|
61
|
+
content
|
62
|
+
end
|
63
|
+
|
64
|
+
def full_path
|
65
|
+
::File.expand_path(self.path)
|
66
|
+
end
|
67
|
+
|
68
|
+
def write(dest)
|
69
|
+
FileUtils.mkdir_p(File.join(dest, File.dirname(directory)))
|
70
|
+
FileUtils.cp(@path, File.join(dest, directory))
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
"#<Broadway:File @path=#{self.path.inspect}>"
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
def file_name(full_path)
|
79
|
+
::File.basename(full_path).split(".").first
|
80
|
+
end
|
81
|
+
|
82
|
+
def file_ext(full_path)
|
83
|
+
::File.extname(full_path).gsub(".", "")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Broadway
|
2
|
+
class Layout
|
3
|
+
attr_accessor :action, :file, :resource
|
4
|
+
|
5
|
+
def initialize(attributes)
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def template(theme = "")
|
10
|
+
# first check if it's in the posts directory (where textile files are)
|
11
|
+
path = File.join(file.directory, action).squeeze("/")
|
12
|
+
exists = false
|
13
|
+
extensions = %w(html haml erb html.haml html.erb)
|
14
|
+
extensions.each do |ext|
|
15
|
+
exists = true if File.exists?("#{path}.#{ext}")
|
16
|
+
end
|
17
|
+
path if exists
|
18
|
+
end
|
19
|
+
|
20
|
+
def kind
|
21
|
+
if file.extension =~ /(haml|erb)/
|
22
|
+
$1
|
23
|
+
else
|
24
|
+
"file"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Broadway
|
2
|
+
class Link
|
3
|
+
include Comparable
|
4
|
+
include Broadway::Processable
|
5
|
+
include Broadway::Convertible
|
6
|
+
include Broadway::Configurable
|
7
|
+
include Broadway::Resourceful
|
8
|
+
include Broadway::Hierarchical
|
9
|
+
include Broadway::Sortable
|
10
|
+
include Broadway::Taggable
|
11
|
+
|
12
|
+
# link category is the menu it's in, or null
|
13
|
+
attr_accessor :href, :rel, :target, :resource, :categories
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Broadway
|
2
|
+
|
3
|
+
class Post
|
4
|
+
include Comparable
|
5
|
+
include Broadway::Processable
|
6
|
+
include Broadway::Convertible
|
7
|
+
include Broadway::Resourceful
|
8
|
+
include Broadway::Readable
|
9
|
+
include Broadway::Configurable
|
10
|
+
include Broadway::Sluggable
|
11
|
+
include Broadway::Sortable
|
12
|
+
include Broadway::Taggable
|
13
|
+
include Broadway::Layoutable
|
14
|
+
include Broadway::Assetable
|
15
|
+
include Broadway::Hierarchical
|
16
|
+
include Broadway::Publishable
|
17
|
+
include Broadway::Themeable
|
18
|
+
|
19
|
+
def sluggify
|
20
|
+
{
|
21
|
+
"year" => "",# date ? date.strftime("%Y") : "",
|
22
|
+
"month" => "",# date ? date.strftime("%m") : "",
|
23
|
+
"day" => "",# date ? date.strftime("%d") : "",
|
24
|
+
"title" => kind == "page" ? "" : slug.value,
|
25
|
+
"categories" => categories.join('/') # page is "categories[0..-2].join('/')"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
{ "title" => self.title,
|
31
|
+
"url" => self.url,
|
32
|
+
"date" => self.date,
|
33
|
+
"id" => self.id,
|
34
|
+
"categories" => self.categories,
|
35
|
+
"tags" => self.tags,
|
36
|
+
"content" => self.content }.deep_merge(self.data)
|
37
|
+
end
|
38
|
+
|
39
|
+
def format
|
40
|
+
extension
|
41
|
+
end
|
42
|
+
def updated_at
|
43
|
+
date
|
44
|
+
end
|
45
|
+
alias created_at updated_at
|
46
|
+
def body
|
47
|
+
read
|
48
|
+
end
|
49
|
+
|
50
|
+
def description
|
51
|
+
unless @description
|
52
|
+
if data["description"]
|
53
|
+
@description = data["description"]
|
54
|
+
else
|
55
|
+
@description = "" # read
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@description
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module Broadway
|
2
|
+
|
3
|
+
class Site
|
4
|
+
include Broadway::Resourceful
|
5
|
+
include Broadway::Processable
|
6
|
+
include Broadway::Configurable
|
7
|
+
|
8
|
+
attr_accessor :posts, :links, :assets, :layouts, :files, :categories, :tags, :configuration, :roots
|
9
|
+
|
10
|
+
def initialize(settings)
|
11
|
+
self.processor = Broadway::Processor::Site.new(self, settings)
|
12
|
+
end
|
13
|
+
|
14
|
+
def build!
|
15
|
+
processor.build
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate!
|
19
|
+
processor.generate
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate(&block)
|
23
|
+
processor.generate(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
settings[:url] || "http://localhost"
|
28
|
+
end
|
29
|
+
|
30
|
+
def index_path
|
31
|
+
settings[:index_path]
|
32
|
+
end
|
33
|
+
|
34
|
+
def views_path
|
35
|
+
settings[:views_path]
|
36
|
+
end
|
37
|
+
|
38
|
+
def public_path
|
39
|
+
settings[:public_path]
|
40
|
+
end
|
41
|
+
|
42
|
+
def setting(path)
|
43
|
+
configuration.get(path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def settings
|
47
|
+
configuration.settings
|
48
|
+
end
|
49
|
+
|
50
|
+
def data
|
51
|
+
settings
|
52
|
+
end
|
53
|
+
|
54
|
+
def title
|
55
|
+
settings[:title]
|
56
|
+
end
|
57
|
+
|
58
|
+
def language
|
59
|
+
settings[:language]
|
60
|
+
end
|
61
|
+
|
62
|
+
def permalink_style
|
63
|
+
settings[:permalink].to_sym
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup
|
67
|
+
configuration.setup
|
68
|
+
end
|
69
|
+
|
70
|
+
def source
|
71
|
+
self.settings[:source]
|
72
|
+
end
|
73
|
+
|
74
|
+
def posts_path
|
75
|
+
self.settings[:posts]
|
76
|
+
end
|
77
|
+
|
78
|
+
# While in Jekyll this method renders the content explicitly,
|
79
|
+
# I'm using Sinatra, partly because I like having the flexibility
|
80
|
+
# of using their get/post methods, and partly because I don't have
|
81
|
+
# the time/desire to try to hack jekyll to use haml.
|
82
|
+
# I'd rather just start over
|
83
|
+
def render
|
84
|
+
server.render
|
85
|
+
end
|
86
|
+
|
87
|
+
def find(type, attributes)
|
88
|
+
result = []
|
89
|
+
self.send(type.to_s.pluralize).each do |resource|
|
90
|
+
failed_to_match = false
|
91
|
+
attributes.each do |method, value|
|
92
|
+
if resource.respond_to?(method)
|
93
|
+
failed_to_match = (resource.send(method) != value)
|
94
|
+
else
|
95
|
+
failed_to_match = !resource.send(method.to_s.pluralize).include?(value)
|
96
|
+
end
|
97
|
+
break if failed_to_match
|
98
|
+
end
|
99
|
+
result << resource unless failed_to_match
|
100
|
+
end
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
def first(type, attributes)
|
105
|
+
find(type, attributes).first
|
106
|
+
end
|
107
|
+
|
108
|
+
%w(post layout asset link file).each do |type|
|
109
|
+
define_method "#{type}_roots" do |attributes|
|
110
|
+
find(type.pluralize, attributes).select { |resource| resource.parent.nil? }
|
111
|
+
end
|
112
|
+
|
113
|
+
define_method "count_#{type}_roots" do |attributes|
|
114
|
+
send("#{type}_roots", attributes).length
|
115
|
+
end
|
116
|
+
|
117
|
+
define_method "find_#{type}" do |attributes|
|
118
|
+
first(type, attributes)
|
119
|
+
end
|
120
|
+
|
121
|
+
define_method "find_#{type.pluralize}" do |attributes|
|
122
|
+
find(type, attributes)
|
123
|
+
end
|
124
|
+
|
125
|
+
%w(category path tag title).each do |property|
|
126
|
+
define_method "find_#{type}_by_#{property}" do |value|
|
127
|
+
first(type.to_sym, property => value)
|
128
|
+
end
|
129
|
+
|
130
|
+
define_method "find_#{type.pluralize}_by_#{property}" do |value|
|
131
|
+
find(type.to_sym, property => value)
|
132
|
+
end
|
133
|
+
|
134
|
+
define_method "count_#{type.pluralize}_by_#{property}" do |value|
|
135
|
+
find(type.to_sym, property => value).length
|
136
|
+
end
|
137
|
+
|
138
|
+
define_method "#{type}_roots_by_#{property}" do |value|
|
139
|
+
send("#{type}_roots", property => value)
|
140
|
+
end
|
141
|
+
|
142
|
+
define_method "count_#{type}_roots_by_#{property}" do |value|
|
143
|
+
send("count_#{type}_roots", property => value)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def num_posts
|
149
|
+
posts.length
|
150
|
+
end
|
151
|
+
|
152
|
+
def num_pages
|
153
|
+
pages.length
|
154
|
+
end
|
155
|
+
|
156
|
+
def pages
|
157
|
+
posts.select { |post| post.kind == "page" }
|
158
|
+
end
|
159
|
+
|
160
|
+
def menu(name)
|
161
|
+
link_roots_by_category(name)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Broadway
|
2
|
+
class Slug
|
3
|
+
attr_accessor :resource, :value, :scope
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :styles
|
7
|
+
|
8
|
+
def default_styles
|
9
|
+
{
|
10
|
+
:category => "/:categories/:slug",
|
11
|
+
:date => "/:categories/:slug.:format",
|
12
|
+
:category_and_date => "/:categories/:year/:month/:day/:slug",
|
13
|
+
:page => "/:categories/:slug"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(slug, resource)
|
19
|
+
self.value = slug
|
20
|
+
self.resource = resource
|
21
|
+
end
|
22
|
+
|
23
|
+
def permalink
|
24
|
+
resource.permalink
|
25
|
+
end
|
26
|
+
|
27
|
+
def site
|
28
|
+
resource.site
|
29
|
+
end
|
30
|
+
|
31
|
+
def template
|
32
|
+
case self.site.permalink_style
|
33
|
+
when :pretty
|
34
|
+
"/:categories/:year/:month/:day/:title"
|
35
|
+
when :none
|
36
|
+
"/:categories/:title.html"
|
37
|
+
when :date
|
38
|
+
"/:categories/:year/:month/:day/:title.html"
|
39
|
+
else
|
40
|
+
self.site.permalink_style.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def path
|
45
|
+
@path ||= permalink
|
46
|
+
@path ||= resource.sluggify.inject(template) do |result, token|
|
47
|
+
result.gsub(/:#{token.first}/, token.last.nested_parameterize)
|
48
|
+
end.gsub(/#{site.posts_path}/, "").squeeze("/").gsub(/\/$/, "")
|
49
|
+
@path
|
50
|
+
end
|
51
|
+
|
52
|
+
def url
|
53
|
+
::File.join(site.url, path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def scope
|
57
|
+
path.split("/")[0..-2].join("/")
|
58
|
+
end
|
59
|
+
|
60
|
+
def titleize
|
61
|
+
self.value.split('-').select { |w| w.capitalize! || w }.join(' ')
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
path
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
Dir[File.dirname(__FILE__) + '/helpers/*'].each { |file| require file if File.extname(file) =~ /\.rb/ }
|
3
|
+
|
4
|
+
helpers do
|
5
|
+
include Broadway::Sinatra::CollectionHelper
|
6
|
+
include Broadway::Sinatra::PartialHelper
|
7
|
+
include Broadway::Sinatra::TextHelper
|
8
|
+
|
9
|
+
def site
|
10
|
+
SITE
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# must define the SITE constant
|
15
|
+
def site
|
16
|
+
SITE
|
17
|
+
end
|
18
|
+
|
19
|
+
def c(path)
|
20
|
+
site.setting(path)
|
21
|
+
end
|