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,155 @@
1
+ <h1>
2
+ <span>Broadway</span>
3
+ <span><img src="http://viatropos.github.com/broadway/favicon.png"/></span>
4
+ </h1>
5
+
6
+ Pluggable, portable, framework-friendly static site generator. Setting the Stage for the Ruby CMS.
7
+
8
+ ## Usage
9
+
10
+ ### Install
11
+
12
+ sudo gem install broadway
13
+
14
+ #### Test
15
+
16
+ rake test
17
+
18
+ ### Structure
19
+
20
+ Everything uses relative paths from the site root.
21
+
22
+ .
23
+ |-- _config.yml
24
+ |-- _layouts
25
+ |-- _posts (generated output)
26
+ |-- _site (github's place)
27
+ |-- _source (sinatra application for development)
28
+ | |-- files (blog files to-be published)
29
+ | |-- posts (blog files)
30
+ | |-- lib (sinatra helpers)
31
+ | `-- public (sinatra public directory)
32
+ |-- shared (javascripts, css, media, etc.)
33
+ |-- index.html
34
+ |-- robots.txt (what google should ignore)
35
+ `-- sitemap.xml (google's sitemap from jekyll)
36
+
37
+ ### Run
38
+
39
+ If you want to use this entirely as a web server, run this at your source root:
40
+
41
+ broadway
42
+
43
+ If you want to use it inside of Sinatra or Rails, create the site manually:
44
+
45
+ site = Broadway.build!
46
+
47
+ ### Models
48
+
49
+ Broadway uses Site, Post, Asset, File, Link, Slug, and Configuration to solve pretty much everything for creating a fully featured site using just Textmate.
50
+
51
+ #### The Site
52
+
53
+ The `Site` is basically the static database.
54
+
55
+ - It holds a reference to all of your other models.
56
+ - It reads a `_config.yml` file from a directory.
57
+ - Creates `File` objects out of the directory tree.
58
+ - Converts `Files` into `Posts` with slugs, tags, categories, and dates if they fit the profile.
59
+ - Finds `Assets` from within `Posts`.
60
+ - And uses a DSL to build menus out of `Links`.
61
+
62
+ ##### Api
63
+
64
+ site = Broadway::Site.new
65
+ # dynamic finders
66
+ site.(models) #=> array of all models
67
+ site.find_(model)_by_(property)(value) #=> first model matching property value
68
+ site.find_(models)_by_(property)(value) #=> all models matching property value
69
+ site.find_(model)(attributes) #=> first model matching attributes
70
+ site.find_(models)(attributes) #=> all models matching attributes
71
+ site.(model)_roots #=> all hierarchical models without a parent
72
+
73
+ #### The Post
74
+
75
+ The `Post` works just like the other static site generators, it is the content input.
76
+
77
+ - It has `metadata` (YAML header) which defines (nested) key-value attributes.
78
+ - It has a `Slug` based on the folder structure, title, date, and is customizable.
79
+ - It has `tags` defined by `metadata`, which can be scoped (e.g tags by "skill" vs. "favorite")
80
+ - It has `categories` based on the folder structure.
81
+ - It has a `kind`, specifying how the post should be treated (currently `post` or `page`).
82
+ - It has `children` if it is a `page`.
83
+ - It has `Assets` defined by `metadata`, if desired.
84
+ - It has a `date` if a) its title was formatted like `yyyy-mm-dd-title.extension`, or b) metadata has defined a `date` attribute.
85
+
86
+ ##### Api
87
+
88
+ post = site.posts.first #=> e.g...
89
+ post.tags #=> ["ruby", "sinatra", "rails"]
90
+ post.categories #=> ["path", "to", "post"]
91
+ post.assets #=> array of Asset objects, if defined
92
+ post.file #=> associate file object, where all calculations are based
93
+ post.slug #=> slug calculation object
94
+ post.path #=> "/path/to/post"
95
+ post.url #=> "http://site.com/path/to/post"
96
+ post.kind #=> "page" or "post" (or whatever you define)
97
+ post.children #=> array of Post objects, if it's a "page"
98
+ post.title
99
+ post.data #=> access to everything in the yaml header
100
+
101
+ ### The Configuration
102
+
103
+ The `Configuration` object is defined from `_config.yml` in the Broadway Site root.
104
+
105
+ - Nested YAML properties
106
+ - Can be used to store arbitrary data, such as site seo stuff, author, etc.
107
+ - Accessed in views via `c("path.to.attribute")`.
108
+
109
+ ## Context
110
+
111
+ There are plenty of static site generators out there: [Jekyll](http://github.com/mojombo/jekyll), [Webby](http://github.com/TwP/webby), [Nanoc](http://github.com/ddfreyne/nanoc), [StaticMatic](http://github.com/staticmatic/staticmatic), [Middleman](http://github.com/tdreyno/middleman), [Mercury](http://github.com/jackhq/mercury), [Frank](http://github.com/blahed/frank), [DynamicMatic](http://github.com/nex3/dynamicmatic), [WebGen](http://github.com/gettalong/webgen), [Pekky](http://github.com/lukesutton/pekky), [Awestruct](http://github.com/bobmcwhirter/awestruct), [Massimo](http://github.com/petebrowne/massimo)... The problem with them is that they are completely separate frameworks from Sinatra and Rails. They're not meant to be used with either of those. It's a lot of work to integrate them.
112
+
113
+ Broadway makes Rails and Sinatra static-compatible.
114
+
115
+ Why integrate static sites with Rails and Sinatra?
116
+
117
+ 1. So you can write posts in Textmate.
118
+ 2. So you can organize your documents and still write complex app code around them.
119
+ 3. So you can use all the helpers the frameworks have built in.
120
+ 4. So you can use Haml and Sass.
121
+ 5. So you can make pretty blogs and still think like a programmer.
122
+ 6. So you can host it on Github Pages if you want.
123
+
124
+ ## Tools
125
+
126
+ - [SeeSaw](http://meetseesaw.com): Convert HTML to HAML, Textile/Markdown to HTML, and lots of other conversions. Useful for converting html you find on sites to Haml for learning.
127
+ - [Sinatra, HAML, JQuery, Textile (cool blog)](http://blog.peepcode.com/tutorials/2010/about-this-blog). Random site I thought was cool.
128
+ - [Tilt](http://github.com/rtomayko/tilt)
129
+
130
+ ## Sinatra on Broadway
131
+
132
+ Here is a [Sinatra + Broadway Example App](http://github.com/viatropos/broadway).
133
+
134
+ Below is a description on how you might setup a Sinatra app to be themeable and run via markdown files. TODO.
135
+
136
+ ### Themes
137
+
138
+ Create a folder called shared/themes/my-theme-name. In there, create folders for html, touch, and flash. In the html folder, you need the following
139
+
140
+ .
141
+ |-- index.haml # home page (layout.haml is somewhere else entirely)
142
+ |-- about
143
+ |-- blog
144
+ |-- features
145
+ |-- demos
146
+ |-- download
147
+ |-- support
148
+ |-- community
149
+ |-- shared
150
+ | |-- stylesheets
151
+ | |-- javascripts
152
+ | |-- images
153
+ | `-- partials
154
+ | |-- _head.haml
155
+ | `-- _header.haml
@@ -1,6 +1,66 @@
1
- libdir = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
1
+ require "rubygems"
2
+ require "active_support"
3
+ require "active_support/core_ext"
4
+ require "fileutils"
5
+ require "time"
6
+ require "yaml"
7
+ require "cgi"
3
8
 
4
- require 'broadway/base'
9
+ # settings
10
+ # require 'cockpit'
11
+ this = File.dirname(__FILE__) + "/broadway"
12
+ require "#{this}/ext"
13
+ requirements = %w(builders processors mixins resources).map { |dir| Dir["#{this}/#{dir}/*"] }
5
14
 
6
- # http://en.wikipedia.org/wiki/Lists_of_musicals
15
+ if defined?(::Sinatra)
16
+ requirements << Dir["#{this}/sinatra/**/*"]
17
+ end
18
+
19
+ requirements.flatten.each { |file| require file if File.extname(file) == ".rb" }
20
+
21
+ module Broadway
22
+ class << self
23
+ attr_accessor :site, :generator
24
+
25
+ def build(options = {})
26
+ process(:build, options)
27
+ end
28
+
29
+ def generator(&block)
30
+ @generator = block if block_given?
31
+ @generator
32
+ end
33
+
34
+ def generate(options = {}, &block)
35
+ block = generator unless block_given?
36
+ process(:generate, options, &block)
37
+ end
38
+
39
+ def process(method, options = {}, &block)
40
+ self.site ||= Broadway::Site.new(options)
41
+ self.site.send(method, &block)
42
+ self.site
43
+ end
44
+
45
+ def menu!(site, name, &block)
46
+ Broadway::Processor::Link.menu!(site, name, &block)
47
+ end
48
+
49
+ # path to views
50
+ def views
51
+ site.views_path
52
+ end
53
+
54
+ def public
55
+ site.public_path
56
+ end
57
+
58
+ def index
59
+ site.index_path
60
+ end
61
+ end
62
+ end
63
+
64
+ def Broadway(*args, &block)
65
+ Broadway.define!(*args, &block)
66
+ end
@@ -1,27 +1,45 @@
1
1
  class Hash
2
- def recursive_symbolize_keys!
2
+ def recursively_symbolize_keys!
3
3
  self.symbolize_keys!
4
4
  self.values.each do |v|
5
5
  if v.is_a? Hash
6
- v.recursive_symbolize_keys!
6
+ v.recursively_symbolize_keys!
7
7
  elsif v.is_a? Array
8
- v.recursive_symbolize_keys!
8
+ v.recursively_symbolize_keys!
9
9
  end
10
10
  end
11
11
  self
12
12
  end
13
13
  end
14
14
 
15
+ class String
16
+ def taggify(separator = "-", quoted = false)
17
+ result = self.dup.downcase.strip.gsub(/[^a-z0-9\.]/, separator).squeeze(separator)
18
+ result = "\"#{result}\"" if quoted && !(result =~ /\s+/).nil?
19
+ result
20
+ end
21
+ end
22
+
15
23
  class Array
16
- def recursive_symbolize_keys!
24
+ def recursively_symbolize_keys!
17
25
  self.each do |item|
18
26
  if item.is_a? Hash
19
- item.recursive_symbolize_keys!
27
+ item.recursively_symbolize_keys!
20
28
  elsif item.is_a? Array
21
- item.recursive_symbolize_keys!
29
+ item.recursively_symbolize_keys!
22
30
  end
23
31
  end
24
32
  end
33
+
34
+ # separator = ", ",
35
+ # max = 10_000
36
+ # quote = true|false
37
+ def taggify(space = " ", separator = ", ", max = 10_000)
38
+ quoted = !(separator =~ /\s+/).nil?
39
+ chop(separator, max) do |word|
40
+ word.taggify(space, quoted)
41
+ end.join(separator)
42
+ end
25
43
 
26
44
  # http://snippets.dzone.com/posts/show/3486
27
45
  def chunk(pieces)
@@ -39,6 +57,22 @@ class Array
39
57
  end
40
58
  end
41
59
 
60
+ class String
61
+ def nested_parameterize(sep = '-')
62
+ parameterized_string = self.dup
63
+ # Turn unwanted chars into the seperator
64
+ parameterized_string = parameterized_string.gsub(/'/, "").gsub(/[^a-z0-9\-_\+\/]+/i, sep)
65
+ unless sep.blank?
66
+ re_sep = Regexp.escape(sep)
67
+ # No more than one of the separator in a row.
68
+ parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
69
+ # Remove leading/trailing separator.
70
+ parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
71
+ end
72
+ parameterized_string.downcase
73
+ end
74
+ end
75
+
42
76
  class Hash
43
77
  # Merges self with another hash, recursively.
44
78
  #
@@ -0,0 +1,10 @@
1
+ module Broadway
2
+ class Erb
3
+
4
+ class << self
5
+ def transform(content)
6
+ end
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Broadway
2
+ class Haml
3
+
4
+ class << self
5
+ def transform(content)
6
+ end
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Broadway
2
+ class Liquid
3
+
4
+ class << self
5
+ def transform(payload, layouts)
6
+ info = { :filters => [], :registers => { :site => self.site } }
7
+ # render and transform content (this becomes the final content of the object)
8
+ payload["content_type"] = self.content_type
9
+ self.output = Liquid::Template.parse(self.content).render(payload, info)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module Broadway
2
+ class Markdown
3
+
4
+ class << self
5
+ def transform(content)
6
+ end
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module Broadway
2
+ module Filter
3
+ class Textile
4
+
5
+ def transform(content)
6
+ RedCloth.new(content).to_html
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Broadway
2
+ module Converter
3
+ class Blogger
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Broadway
2
+ module Converter
3
+ class Wordpress
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,48 @@
1
+ module Broadway
2
+ module Assetable
3
+ def self.included(base)
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module InstanceMethods
8
+ def asset_types
9
+ %w(image video audio asset)
10
+ end
11
+
12
+ def assets
13
+ unless @assets
14
+ @assets = []
15
+ if self.data.has_key?("asset")
16
+ @assets << ::Broadway::Asset.new(self, "asset", data["asset"])
17
+ elsif self.data.has_key?("assets")
18
+ self.data["assets"].each do |name, asset|
19
+ @assets << ::Broadway::Asset.new(self, name, asset)
20
+ end
21
+ end
22
+ end
23
+
24
+ @assets
25
+ end
26
+
27
+ def asset
28
+ assets.first
29
+ end
30
+
31
+ def num_assets
32
+ assets.length
33
+ end
34
+
35
+ def find_asset_by_name(name)
36
+ assets.detect { |asset| asset.name == name }
37
+ end
38
+
39
+ def method_missing(meth, *args, &block)
40
+ if asset_types.detect { |type| meth.to_s =~ /(\w+)_#{type}/ }
41
+ find_asset_by_name($1.to_s)
42
+ else
43
+ super(meth, *args, &block)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ module Broadway
2
+ module Configurable
3
+ def self.included(base)
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module InstanceMethods
8
+ attr_accessor :data
9
+
10
+ # should only read the beginning of the file
11
+ def configure
12
+ self.content = file.read
13
+
14
+ if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
15
+ self.content = self.content[($1.size + $2.size)..-1]
16
+
17
+ self.data.merge!(YAML.load($1))
18
+ end
19
+
20
+ self.data ||= {}
21
+ end
22
+
23
+ def method_missing(meth, *args, &block)
24
+ if self.data && self.data.has_key?(meth.to_s)
25
+ self.data[meth.to_s]
26
+ else
27
+ super(meth, *args, &block)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end