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.
Files changed (60) hide show
  1. data/README.markdown +155 -0
  2. data/lib/broadway.rb +64 -4
  3. data/lib/broadway/{core_ext.rb → ext.rb} +40 -6
  4. data/lib/broadway/filters/erb.rb +10 -0
  5. data/lib/broadway/filters/haml.rb +10 -0
  6. data/lib/broadway/filters/liquid.rb +14 -0
  7. data/lib/broadway/filters/markdown.rb +10 -0
  8. data/lib/broadway/filters/textile.rb +11 -0
  9. data/lib/broadway/migrators/blogger.rb +7 -0
  10. data/lib/broadway/migrators/wordpress.rb +7 -0
  11. data/lib/broadway/mixins/assetable.rb +48 -0
  12. data/lib/broadway/mixins/configurable.rb +32 -0
  13. data/lib/broadway/mixins/convertible.rb +25 -0
  14. data/lib/broadway/mixins/hierarchical.rb +61 -0
  15. data/lib/broadway/mixins/layoutable.rb +18 -0
  16. data/lib/broadway/mixins/pageable.rb +5 -0
  17. data/lib/broadway/mixins/processable.rb +44 -0
  18. data/lib/broadway/mixins/publishable.rb +36 -0
  19. data/lib/broadway/mixins/readable.rb +73 -0
  20. data/lib/broadway/mixins/resourceful.rb +27 -0
  21. data/lib/broadway/mixins/sluggable.rb +36 -0
  22. data/lib/broadway/mixins/sortable.rb +24 -0
  23. data/lib/broadway/mixins/taggable.rb +46 -0
  24. data/lib/broadway/mixins/themeable.rb +39 -0
  25. data/lib/broadway/processors/link.rb +45 -0
  26. data/lib/broadway/processors/post.rb +117 -0
  27. data/lib/broadway/processors/site.rb +77 -0
  28. data/lib/broadway/processors/tree.rb +121 -0
  29. data/lib/broadway/resources/asset.rb +28 -0
  30. data/lib/broadway/resources/configuration.rb +114 -0
  31. data/lib/broadway/resources/file.rb +88 -0
  32. data/lib/broadway/resources/layout.rb +28 -0
  33. data/lib/broadway/resources/link.rb +16 -0
  34. data/lib/broadway/resources/post.rb +63 -0
  35. data/lib/broadway/resources/site.rb +164 -0
  36. data/lib/broadway/resources/slug.rb +69 -0
  37. data/lib/broadway/sinatra/app.rb +21 -0
  38. data/lib/broadway/sinatra/helpers/collection_helper.rb +2 -1
  39. data/lib/broadway/sinatra/helpers/partial_helper.rb +5 -5
  40. data/lib/broadway/sinatra/helpers/text_helper.rb +5 -11
  41. data/lib/broadway/sinatra/processor.rb +84 -0
  42. data/lib/broadway/tasks.rb +1 -0
  43. data/lib/broadway/tasks/default.rake +85 -0
  44. metadata +46 -41
  45. data/README.textile +0 -306
  46. data/Rakefile +0 -85
  47. data/lib/broadway/api.rb +0 -51
  48. data/lib/broadway/asset.rb +0 -17
  49. data/lib/broadway/base.rb +0 -120
  50. data/lib/broadway/convertible.rb +0 -91
  51. data/lib/broadway/page.rb +0 -71
  52. data/lib/broadway/post.rb +0 -112
  53. data/lib/broadway/rails.rb +0 -3
  54. data/lib/broadway/resource.rb +0 -128
  55. data/lib/broadway/runner.rb +0 -62
  56. data/lib/broadway/sinatra.rb +0 -5
  57. data/lib/broadway/sinatra/base.rb +0 -90
  58. data/lib/broadway/sinatra/helpers.rb +0 -7
  59. data/lib/broadway/site.rb +0 -421
  60. 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