broadway 0.0.3.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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