gumdrop 0.2.4 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/ChangeLog.md +12 -0
  2. data/Notes.md +5 -1
  3. data/examples/simple/Gemfile +4 -1
  4. data/examples/simple/data/config.yml +8 -0
  5. data/examples/simple/data/posts.yamldb +28 -0
  6. data/examples/simple/lib/site.rb +24 -0
  7. data/examples/simple/source/.htaccess +16 -0
  8. data/examples/simple/source/_pager_control.html.erb +14 -0
  9. data/examples/simple/source/_sidebar.html.haml +2 -0
  10. data/examples/simple/source/feed.xml.builder +23 -0
  11. data/examples/simple/source/index.html.erb +4 -1
  12. data/examples/simple/source/posts.generator.rb +11 -0
  13. data/examples/simple/source/posts/index.html.erb +6 -0
  14. data/examples/simple/source/theme/templates/post.template.haml +3 -0
  15. data/examples/simple/source/theme/templates/post_page.template.haml +6 -0
  16. data/examples/simple/source/theme/templates/site.template.haml +1 -1
  17. data/examples/simple/source/theme/templates/test.template.erb +1 -0
  18. data/lib/gumdrop.rb +32 -10
  19. data/lib/gumdrop/content.rb +8 -6
  20. data/lib/gumdrop/context.rb +45 -70
  21. data/lib/gumdrop/deferred_loader.rb +97 -0
  22. data/lib/gumdrop/generator.rb +75 -0
  23. data/lib/gumdrop/pager.rb +49 -0
  24. data/lib/gumdrop/server.rb +28 -13
  25. data/lib/gumdrop/template/Gemfile +7 -2
  26. data/lib/gumdrop/template/Rakefile +0 -5
  27. data/lib/gumdrop/template/config.ru +1 -0
  28. data/lib/gumdrop/template/data/config.yml +2 -0
  29. data/lib/gumdrop/template/lib/site.rb +14 -0
  30. data/lib/gumdrop/template/source/feed.xml.builder.txt +23 -0
  31. data/lib/gumdrop/template/source/theme/scripts/app.js.coffee +4 -0
  32. data/lib/gumdrop/version.rb +1 -1
  33. data/lib/gumdrop/view_helpers.rb +9 -4
  34. metadata +28 -13
@@ -1,3 +1,15 @@
1
+ # v0.2.7
2
+ - Added support for `yield` in templates
3
+ - Added support for content_for -- only tested in SLIM
4
+
5
+ # v0.2.6
6
+ - Update pager_for to accept a symbol or an array
7
+
8
+ # v0.2.5
9
+ - New feature: Generators, from source tree or centreally in lib/site.rb
10
+ - Server can reload the entire site for each request, by default this feature is off
11
+ - Added Pager class for creating tumblr-like pagesets
12
+
1
13
  # v0.2.4
2
14
  - Modernized Sinatra usage. Added an example site (just boilerplate at this point).
3
15
 
data/Notes.md CHANGED
@@ -1,4 +1,8 @@
1
1
  # Future Features/Changes
2
- - Generator support of some kind... Where you can define how pages can be built from data. Include support for paging and RSS/ATOM feeds.
2
+ - Add support for `data.pager_for(key, opts={})`
3
+ - Add support for Sprockets
4
+ - Add support for js and css compression
3
5
  - Add options to config for `source/` and `output/` folder names. `data/` too?
6
+ - Page generation from lib/site.rb
7
+ - HTML Manifest generation??
4
8
  - Some kind of admin? What would that even do?
@@ -2,9 +2,9 @@ source "http://rubygems.org"
2
2
 
3
3
  here= File.dirname(__FILE__)
4
4
 
5
+ gem "i18n"
5
6
  gem "sinatra"
6
7
  gem "active_support"
7
- gem "i18n"
8
8
  gem "rake"
9
9
  gem "gumdrop", :path=>"#{here}/../../"
10
10
 
@@ -16,4 +16,7 @@ gem "coffee-script"
16
16
  # gem "rdiscount"
17
17
  # gem "less"
18
18
  # gem "haml"
19
+ gem "slim"
19
20
 
21
+ gem 'maruku'
22
+ gem 'builder'
@@ -1,2 +1,10 @@
1
1
  title: My Site
2
2
  tagline: My home on thar intarwebs!
3
+ author: Matt McCray
4
+ url: http://www.mysite.com
5
+
6
+ gumdrop:
7
+ js:
8
+ compress: true
9
+ css:
10
+ compress: true
@@ -0,0 +1,28 @@
1
+ ---
2
+ __proto__: true
3
+ title: String
4
+ slug: String
5
+ date: Date
6
+ filter: String
7
+ content: Text
8
+ tags: String
9
+
10
+ ---
11
+ title: Testing
12
+ slug: testing
13
+ date: 2011-09-09
14
+ filter: markdown
15
+ content: |
16
+ This is just a *test*.
17
+
18
+ Enjoy!
19
+
20
+ ---
21
+ title: The Second
22
+ slug: the-second
23
+ date: 2011-09-10
24
+ filter: markdown
25
+ content: |
26
+ This is just another *test*.
27
+
28
+ Enjoy! ReallY!
@@ -0,0 +1,24 @@
1
+ # Any specialized code for your site goes here...
2
+
3
+ puts "Building: #{Gumdrop.data.config.title}"
4
+
5
+ new_posts= Gumdrop.data.posts.map do |post|
6
+ mdt= Tilt['markdown'].new { post.content }
7
+ post.body = mdt.render
8
+ post
9
+ end
10
+
11
+ Gumdrop.data.set :blog, new_posts, :persist=>true
12
+
13
+
14
+ generate do
15
+
16
+ page "my-root-page.html", :template=>'test', :info=>"FROM SITE.RB"
17
+
18
+ pager= Gumdrop.data.pager_for :blog, :base_path=>'posts/page', :page_size=>1
19
+
20
+ pager.each do |pageset|
21
+ page "#{pageset.uri}.html", :template=>'post_page', :posts=>pageset.items, :pager=>pager, :current_page=>pager.current_page
22
+ end
23
+
24
+ end
@@ -0,0 +1,16 @@
1
+ # For clean urls
2
+ DirectoryIndex index.html
3
+
4
+ <IfModule mod_rewrite.c>
5
+ RewriteEngine On
6
+ RewriteBase /
7
+
8
+ # Do not do anything for already existing files and folders
9
+ RewriteCond %{REQUEST_FILENAME} -f [OR]
10
+ RewriteCond %{REQUEST_FILENAME} -d
11
+ RewriteRule .+ - [L]
12
+
13
+ # add .html file extension (if such file does exist)
14
+ RewriteCond %{DOCUMENT_ROOT}/$1\.html -f
15
+ RewriteRule ^(.+[^/])/?$ $1.html [L,QSA]
16
+ </IfModule>
@@ -0,0 +1,14 @@
1
+ <%
2
+ previous_page = [(current_page - 1), 1].max
3
+ next_page = [(current_page + 1), pager.length].min
4
+ %>
5
+ <div class="page">
6
+ <a href="<%= uri pager[previous_page - 1].uri %>">&larr;</a>
7
+ <%
8
+ pager.each do |pager_page|
9
+ class_name= pager_page.page == current_page ? 'current' : ''
10
+ %>
11
+ <a href="<%= uri pager_page.uri %>" class="<%= class_name %>"><%= pager_page.page %></a>
12
+ <% end %>
13
+ <a href="<%= uri pager[next_page - 1].uri %>">&rarr;</a>
14
+ </div>
@@ -0,0 +1,2 @@
1
+ :markdown
2
+ I'm the sidebar.
@@ -0,0 +1,23 @@
1
+ xml.instruct!
2
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3
+ xml.title data.config.title
4
+ xml.subtitle data.config.tagline
5
+ xml.id data.config.url
6
+ xml.link "href" => data.config.url
7
+ xml.link "href" => "#{data.config.url}/feed.xml", "rel" => "self"
8
+ xml.updated data.blog.first.date.to_time.iso8601
9
+ xml.author { xml.name data.config.author }
10
+
11
+ data.blog.each do |post|
12
+ xml.entry do
13
+ url= "#{data.config.url}/posts/#{post.slug}"
14
+ xml.title post.title
15
+ xml.link "rel" => "alternate", "href" => url
16
+ xml.id url
17
+ xml.published post.date.to_time.iso8601
18
+ xml.updated post.date.to_time.iso8601
19
+ xml.author { xml.name data.config.author }
20
+ xml.content post.body, "type" => "html"
21
+ end
22
+ end
23
+ end
@@ -1 +1,4 @@
1
- <p>Welcome to <%= data.config.title %></p>
1
+ <p>Welcome to <%= data.config.title %></p>
2
+
3
+
4
+ <p>POSTS: <%= data.blog.length %></p>
@@ -0,0 +1,11 @@
1
+
2
+ set :template, "post"
3
+
4
+ data.blog.each do |post|
5
+ # mdt= Tilt['markdown'].new { post.content }
6
+ # post.body = mdt.render
7
+
8
+ page "#{post.slug}.html", :template=>'post', :post=>post
9
+ end
10
+
11
+ #page "index.html"
@@ -0,0 +1,6 @@
1
+ <h2>Post Archive</h2>
2
+ <ul>
3
+ <% data.blog.each do |post| %>
4
+ <li><a href="<%= uri "/posts/#{post.slug}" %>"><%= post.title %></a></li>
5
+ <% end %>
6
+ </ul>
@@ -0,0 +1,3 @@
1
+ %div.post
2
+ %div.title= post.title
3
+ %div.content= post.body
@@ -0,0 +1,6 @@
1
+ %ul
2
+ - posts.each do |post|
3
+ %li= post.title
4
+
5
+ = render 'pager_control'
6
+
@@ -30,4 +30,4 @@
30
30
  .row
31
31
  .col.span-12
32
32
  %footer
33
- = copyright_years 2011
33
+ = copyright_years 2010
@@ -0,0 +1 @@
1
+ <p>A Message: <%= info %></p>
@@ -6,6 +6,7 @@ DEFAULT_OPTIONS= {
6
6
  :cache_data => false,
7
7
  :relative_paths => true,
8
8
  :auto_run => false,
9
+ :force_reload => false,
9
10
  :root => "."
10
11
  }
11
12
 
@@ -13,8 +14,12 @@ module Gumdrop
13
14
 
14
15
  autoload :Context, "gumdrop/context"
15
16
  autoload :Content, "gumdrop/content"
17
+ autoload :DeferredLoader, "gumdrop/deferred_loader"
16
18
  autoload :Generator, "gumdrop/generator"
19
+ autoload :GeneratedrContent, "gumdrop/generator"
20
+ autoload :GenerationDSL, "gumdrop/generator"
17
21
  autoload :HashObject, "gumdrop/hash_object"
22
+ autoload :Pager, "gumdrop/pager"
18
23
  autoload :Server, "gumdrop/server"
19
24
  autoload :Utils, "gumdrop/utils"
20
25
  autoload :VERSION, "gumdrop/version"
@@ -22,7 +27,7 @@ module Gumdrop
22
27
 
23
28
  class << self
24
29
 
25
- attr_accessor :root_path, :source_path, :site, :layouts, :generators, :partials, :config
30
+ attr_accessor :root_path, :source_path, :site, :layouts, :generators, :partials, :config, :data
26
31
 
27
32
  def run(opts={})
28
33
  # Opts
@@ -30,8 +35,8 @@ module Gumdrop
30
35
 
31
36
  root= File.expand_path Gumdrop.config.root
32
37
  src= File.join root, 'source'
38
+ $: << "#{root}/lib"
33
39
  if File.exists? "#{root}/lib/view_helpers.rb"
34
- $: << "#{root}/lib"
35
40
  require 'view_helpers'
36
41
  end
37
42
 
@@ -41,6 +46,17 @@ module Gumdrop
41
46
  @partials = Hash.new {|h,k| h[k]= nil }
42
47
  @root_path = root.split '/'
43
48
  @source_path = src.split '/'
49
+ @data = Gumdrop::DeferredLoader.new()
50
+
51
+ if File.exists? "#{root}/lib/site.rb"
52
+ # In server mode, we want to reload it every time... right?
53
+ source= IO.readlines("#{root}/lib/site.rb").join('')
54
+
55
+ GenerationDSL.class_eval source
56
+
57
+ #load "#{root}/lib/site.rb"
58
+ # require 'site'
59
+ end
44
60
 
45
61
  # Scan
46
62
  #puts "Running in: #{root}"
@@ -58,7 +74,7 @@ module Gumdrop
58
74
  @layouts[File.basename(path)]= @site.delete(path)
59
75
 
60
76
  elsif File.extname(path) == ".generator"
61
- @generators[File.basename(path)]= @site.delete(path)
77
+ @generators[File.basename(path)]= Generator.new( @site.delete(path) )
62
78
 
63
79
  elsif File.basename(path).starts_with?("_")
64
80
  partial_name= File.basename(path)[1..-1].gsub(File.extname(File.basename(path)), '')
@@ -67,16 +83,22 @@ module Gumdrop
67
83
  end
68
84
  end
69
85
 
70
- # Render
71
- site.keys.each do |path|
72
- node= site[path]
73
- output_path= "output/#{node.to_s}"
74
- FileUtils.mkdir_p File.dirname(output_path)
75
- node.renderTo output_path
86
+ @generators.each_pair do |path, generator|
87
+ generator.execute()
76
88
  end
77
89
 
78
- puts "Done."
90
+ # Render
91
+ unless opts[:dry_run]
92
+ site.keys.sort.each do |path|
93
+ node= site[path]
94
+ output_path= "output/#{node.to_s}"
95
+ FileUtils.mkdir_p File.dirname(output_path)
96
+ node.renderTo output_path
97
+ end
98
+ puts "Done."
99
+ end
79
100
  end
101
+
80
102
  end
81
103
 
82
104
  Gumdrop.config= Gumdrop::HashObject.new(DEFAULT_OPTIONS)
@@ -3,9 +3,10 @@ module Gumdrop
3
3
 
4
4
  class Content
5
5
 
6
- attr_accessor :path, :level, :filename, :source_filename, :type, :ext, :uri, :slug, :template
6
+ attr_accessor :path, :level, :filename, :source_filename, :type, :ext, :uri, :slug, :template, :params
7
7
 
8
- def initialize(path)
8
+ def initialize(path, params={})
9
+ @params= HashObject.new params
9
10
  @path= path
10
11
  @level= (@path.split('/').length - 2)
11
12
  @source_filename= File.basename path
@@ -26,16 +27,17 @@ module Gumdrop
26
27
  end
27
28
  end
28
29
 
29
- def render(ignore_layout=false, reset_context=true)
30
+ def render(ignore_layout=false, reset_context=true, locals={})
30
31
  if reset_context
31
32
  default_layout= (@ext == '.css' or @ext == '.js' or @ext == '.xml') ? nil : 'site'
32
- Context.reset_data 'current_depth'=>@level, 'current_slug'=>@slug, 'page'=>self, 'layout'=>default_layout
33
+ Context.reset_data 'current_depth'=>@level, 'current_slug'=>@slug, 'page'=>self, 'layout'=>default_layout, 'params'=>self.params
33
34
  end
34
- content= @template.render(Context)
35
+ Context.set_content self, locals
36
+ content= @template.render(Context)
35
37
  return content if ignore_layout
36
38
  layout= Context.get_template()
37
39
  while !layout.nil?
38
- content = layout.template.render(Context, :content=>content)
40
+ content = layout.template.render(Context, :content=>content) { content }
39
41
  layout= Context.get_template()
40
42
  end
41
43
  content
@@ -1,85 +1,27 @@
1
- require 'yaml'
2
- require 'ostruct'
3
-
4
- def hashes2ostruct(object)
5
- return case object
6
- when Hash
7
- object = object.clone
8
- object.each do |key, value|
9
- object[key] = hashes2ostruct(value)
10
- end
11
- OpenStruct.new(object)
12
- when Array
13
- object = object.clone
14
- object.map! { |i| hashes2ostruct(i) }
15
- else
16
- object
17
- end
18
- end
19
1
 
20
2
  module Gumdrop
21
3
 
22
- class DeferredLoader
23
- attr_reader :cache
24
-
25
- # def initialize
26
- # puts "@!@"
27
- # end
28
-
29
- def method_missing(key, value=nil)
30
- @cache= Hash.new {|h,k| h[k]= load_data(k) } if @cache.nil?
31
- @cache[key]
32
- end
33
-
34
- private
35
-
36
- def load_data(key)
37
- path=get_filename(key)
38
- if File.extname(path) == ".yamldb"
39
- docs=[]
40
- File.open(path, 'r') do |f|
41
- YAML.load_documents(f) do |doc|
42
- docs << hashes2ostruct( doc )
43
- end
44
- end
45
- docs
46
- else
47
- hashes2ostruct( YAML.load_file(path) )
48
- end
49
- end
50
-
51
- # TODO: Support './data/collection_name/*.(yaml|json)' data loading?
52
-
53
- def get_filename(path)
54
- if File.exists? "data/#{path}.json"
55
- "data/#{path}.json"
56
- elsif File.exists? "data/#{path}.yml"
57
- "data/#{path}.yml"
58
- elsif File.exists? "data/#{path}.yaml"
59
- "data/#{path}.yaml"
60
- elsif File.exists? "data/#{path}.yamldb"
61
- "data/#{path}.yamldb"
62
- else
63
- raise "No data found for #{path}"
64
- end
65
- end
66
- end
67
-
68
4
  module Context
69
5
  class << self
70
6
 
71
7
  include ::Gumdrop::ViewHelpers
72
8
 
73
9
  attr_accessor :state
74
- attr_reader :data
10
+ #attr_reader :data
75
11
 
76
12
  def uri(path)
13
+ path= path[1..-1] if path.starts_with?('/')
77
14
  if Gumdrop.config.relative_paths
78
15
  "#{'../'*@state['current_depth']}#{path}"
79
16
  else
80
17
  "/#{path}"
81
18
  end
82
19
  end
20
+
21
+ def url(path)
22
+ path= path[1..-1] if path.starts_with?('/')
23
+ "#{data.config.url}/#{path}"
24
+ end
83
25
 
84
26
  def slug
85
27
  @state['current_slug']
@@ -99,34 +41,67 @@ module Gumdrop
99
41
  @state['layout']= name
100
42
  end
101
43
 
102
- def render(path)
44
+ def render(path, opts={})
103
45
  page= get_page path
104
46
  unless page.nil?
105
47
  #TODO: nested state for an inline rendered page?
106
48
  old_layout= @state['layout']
107
- content= page.render(true, false)
49
+ content= page.render(true, false, opts)
108
50
  old_layout= @state['layout']
109
51
  content
110
52
  else
111
53
  ""
112
54
  end
113
55
  end
56
+
57
+ def data
58
+ Gumdrop.data
59
+ end
114
60
 
115
61
  def reset_data(preset={})
116
62
  # TODO: Add a setting for reloading data on every request/page
117
- @data= DeferredLoader.new if @data.nil? or !Gumdrop.config.cache_data
63
+ #@data= DeferredLoader.new if @data.nil? or !Gumdrop.config.cache_data
64
+ Gumdrop.data.reset if !Gumdrop.config.cache_data
118
65
  @state = preset
119
66
  end
120
67
 
121
68
  def method_missing(name, value=nil)
122
69
  @state= Hash.new {|h,k| h[k]= nil } if @state.nil?
70
+ # puts "Looking for >> #{name} in #{@state.keys}"
123
71
  unless value.nil?
124
- @state[name]= value
72
+ @state[name.to_s]= value
73
+ else
74
+ @state[name.to_s]
75
+ end
76
+ end
77
+
78
+ def params
79
+ @content.params
80
+ end
81
+
82
+ def set_content(content, locals)
83
+ @content= content
84
+ @state= @state.reverse_merge(content.params).merge(locals)
85
+ end
86
+
87
+ def content_for(key, &block)
88
+ keyname= "_content_#{key}"
89
+ if block_given?
90
+ @state[keyname]= block
125
91
  else
126
- @state[name]
92
+ if @state.has_key?(keyname)
93
+ @state[keyname].call
94
+ else
95
+ nil
96
+ end
127
97
  end
128
98
  end
129
99
 
100
+ def content_for?(key)
101
+ keyname= "_content_#{key}"
102
+ @state.has_key?(keyname)
103
+ end
104
+
130
105
  protected
131
106
 
132
107
  def get_page(path)
@@ -0,0 +1,97 @@
1
+ require 'yaml'
2
+ require 'ostruct'
3
+
4
+ def hashes2ostruct(object)
5
+ return case object
6
+ when Hash
7
+ object = object.clone
8
+ object.each do |key, value|
9
+ object[key] = hashes2ostruct(value)
10
+ end
11
+ OpenStruct.new(object)
12
+ when Array
13
+ object = object.clone
14
+ object.map! { |i| hashes2ostruct(i) }
15
+ else
16
+ object
17
+ end
18
+ end
19
+
20
+ module Gumdrop
21
+
22
+ class DeferredLoader
23
+ attr_reader :cache
24
+
25
+ def initialize
26
+ #puts "@!@"
27
+ @cache= {}
28
+ @persisted= {}
29
+ end
30
+
31
+ def method_missing(key, value=nil)
32
+ cache_or_load_data(key)
33
+ @cache[key]
34
+ end
35
+
36
+ def set(key, value, opts={})
37
+ @cache[key]= value
38
+ @persisted[key]= value if opts[:persist]
39
+ end
40
+
41
+ def reset
42
+ @cache= @persisted.clone #Hash.new(@persisted) #{|h,k| h[k]= load_data(k) }
43
+ end
44
+
45
+ def pager_for(key, opts={})
46
+ base_path= opts.fetch(:base_path, 'page')
47
+ page_size= opts.fetch(:page_size, 5)
48
+ data= if key.is_a? Symbol
49
+ cache_or_load_data(key)
50
+ @cache[key]
51
+ else
52
+ key
53
+ end
54
+ Pager.new( data, base_path, page_size )
55
+ end
56
+
57
+
58
+ private
59
+
60
+ def cache_or_load_data(key)
61
+ @cache[key]= load_data(key) unless @cache.has_key? key
62
+ end
63
+
64
+ def load_data(key)
65
+ path=get_filename(key)
66
+ return nil if path.nil?
67
+ if File.extname(path) == ".yamldb"
68
+ docs=[]
69
+ File.open(path, 'r') do |f|
70
+ YAML.load_documents(f) do |doc|
71
+ docs << hashes2ostruct( doc ) unless doc.has_key?("__proto__")
72
+ end
73
+ end
74
+ docs
75
+ else
76
+ hashes2ostruct( YAML.load_file(path) )
77
+ end
78
+ end
79
+
80
+ # TODO: Support './data/collection_name/*.(yaml|json)' data loading?
81
+
82
+ def get_filename(path)
83
+ if File.exists? "data/#{path}.json"
84
+ "data/#{path}.json"
85
+ elsif File.exists? "data/#{path}.yml"
86
+ "data/#{path}.yml"
87
+ elsif File.exists? "data/#{path}.yaml"
88
+ "data/#{path}.yaml"
89
+ elsif File.exists? "data/#{path}.yamldb"
90
+ "data/#{path}.yamldb"
91
+ else
92
+ raise "No data found for #{path}"
93
+ #nil #TODO: Should it die if it can't find data?
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,6 +1,81 @@
1
1
  module Gumdrop
2
2
 
3
3
  class Generator
4
+ attr_reader :filename, :base_path, :params, :pages
5
+
6
+ def initialize(content, opts={})
7
+ @content= content
8
+ if @content.is_a? Proc
9
+ @filename= ""
10
+ @base_path= ""
11
+ else
12
+ @filename= content.filename || ""
13
+ @base_path= content.slug || ""
14
+ end
15
+ @params= HashObject.new
16
+ @pages= []
17
+ end
18
+
19
+ def execute
20
+ if @content.is_a? Proc
21
+ run_dsl_from_proc @content
22
+ else
23
+ run_dsl_from_source IO.readlines(@content.path).join('')
24
+ end
25
+ end
26
+
27
+ def data
28
+ Gumdrop.data
29
+ end
30
+
31
+ def set(var_name, value)
32
+ params[var_name]= value
33
+ end
34
+
35
+ def page(name, opts={}, &block)
36
+ opts= params.reverse_merge(opts)
37
+ filepath= if @base_path.empty?
38
+ "/#{name}"
39
+ else
40
+ "/#{@base_path}/#{name}"
41
+ end
42
+ content= GeneratedContent.new(filepath, opts)
43
+ content.template = if Gumdrop.layouts.has_key?( opts[:template] )
44
+ Gumdrop.layouts[ opts[:template] ]
45
+ else
46
+ Gumdrop.layouts[ "#{opts[:template]}.template" ]
47
+ end.template
48
+
49
+ Gumdrop.site[content.uri]= content
50
+ end
51
+
52
+ def run_dsl_from_source(source)
53
+ # puts source
54
+ instance_eval source
55
+ end
56
+
57
+ def run_dsl_from_proc(proc)
58
+ # puts source
59
+ instance_eval &proc
60
+ end
61
+
62
+ end
63
+
64
+ class GeneratedContent < Content
65
+ # Nothing special, per se...
66
+ end
67
+
68
+ module GenerationDSL
69
+
70
+ # attr_accessor :generators
71
+ # @generators=[]
72
+
73
+ def self.generate(&block)
74
+
75
+ # Auto-generated, numerical, key for a site-level generator
76
+ Gumdrop.generators[Gumdrop.generators.keys.length] = Generator.new(block)
77
+ end
78
+
4
79
  end
5
80
 
6
81
  end
@@ -0,0 +1,49 @@
1
+ module Gumdrop
2
+ class Pager
3
+ attr_reader :all, :pages, :base_url, :current_page, :page_sets
4
+
5
+ def initialize(articles, base_path="/page", page_size=5)
6
+ @all= articles
7
+ @page_size= page_size
8
+ @base_path= base_path
9
+ @page_sets= @all.in_groups_of(page_size, false)
10
+ @pages= []
11
+ @current_page=1
12
+ @page_sets.each do |art_ary|
13
+ @pages << HashObject.new({
14
+ 'items' => art_ary,
15
+ 'page' => @current_page,
16
+ 'uri' => "#{base_path}/#{current_page}",
17
+ 'pager' => self
18
+ })
19
+ @current_page += 1
20
+ end
21
+ @current_page= nil
22
+ end
23
+
24
+ def length
25
+ @pages.length
26
+ end
27
+
28
+ def first
29
+ @pages.first
30
+ end
31
+
32
+ def last
33
+ @pages.last
34
+ end
35
+
36
+ def each
37
+ @current_page=1
38
+ @pages.each do |page_set|
39
+ yield page_set
40
+ @current_page += 1
41
+ end
42
+ @current_page= nil
43
+ end
44
+
45
+ def [](key)
46
+ @pages[key]
47
+ end
48
+ end
49
+ end
@@ -8,26 +8,25 @@ module Gumdrop
8
8
 
9
9
  set :port, Gumdrop.config.port if Gumdrop.config.port
10
10
 
11
- get '/' do
12
- redirect '/index.html'
13
- end
14
-
11
+ # get '/' do
12
+ # redirect '/index.html'
13
+ # end
14
+
15
15
  get '/*' do
16
- file_path= params[:splat].join('/')
17
- matches= Dir["source/#{file_path}*"]
18
- if matches.length > 0
19
-
20
- Gumdrop.site= Gumdrop.layouts= Gumdrop.generators= Utils.content_hash("source/**/")
21
- Gumdrop.partials= Utils.content_hash("source/**/_")
22
-
23
- content= Content.new matches[0]
16
+
17
+ Gumdrop.run :dry_run=>true if Gumdrop.config.force_reload
18
+
19
+ file_path= get_content_path params[:splat].join('/')
20
+
21
+ if Gumdrop.site.has_key? file_path
22
+ content= Gumdrop.site[file_path]
24
23
  if content.useLayout?
25
24
  content_type :css if content.ext == '.css' # Meh?
26
25
  content_type :js if content.ext == '.js' # Meh?
27
26
  content_type :xml if content.ext == '.xml' # Meh?
28
27
  content.render
29
28
  else
30
- send_file matches[0]
29
+ send_file "source/#{file_path}"
31
30
  end
32
31
  else
33
32
  puts "NOT FOUND: #{file_path}"
@@ -35,7 +34,22 @@ module Gumdrop
35
34
  end
36
35
  end
37
36
 
37
+
38
+ def get_content_path(file_path)
39
+ keys= [
40
+ file_path,
41
+ "#{file_path}.html",
42
+ "#{file_path}/index.html"
43
+ ]
44
+ if file_path == ""
45
+ "index.html"
46
+ else
47
+ keys.detect {|k| Gumdrop.site.has_key?(k) }
48
+ end
49
+ end
50
+
38
51
  if Gumdrop.config.auto_run
52
+ Gumdrop.run :dry_run=>true
39
53
  run!
40
54
  end
41
55
 
@@ -43,6 +57,7 @@ module Gumdrop
43
57
  # Options
44
58
  opts.reverse_merge! :auto_run => true, :cache_data => false
45
59
  Gumdrop.config.merge! opts
60
+ Gumdrop.run :dry_run=>true
46
61
  ::Gumdrop::Server
47
62
  end
48
63
 
@@ -1,8 +1,8 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem "i18n"
3
4
  gem "sinatra"
4
5
  gem "active_support"
5
- gem "i18n"
6
6
  gem "rake"
7
7
  gem "gumdrop"
8
8
 
@@ -11,7 +11,12 @@ gem "gumdrop"
11
11
  gem "sass"
12
12
  gem "coffee-script"
13
13
 
14
+ # For markdown support, a couple of options:
14
15
  # gem "rdiscount"
16
+ # gem 'maruku'
17
+
18
+ # For template support:
15
19
  # gem "less"
16
20
  # gem "haml"
17
-
21
+ # gem "slim"
22
+ # gem 'builder'
@@ -8,16 +8,11 @@ SERVER='server.com'
8
8
  FOLDER="~/#{SERVER}"
9
9
 
10
10
 
11
- task :default do
12
- sh 'rake -T'
13
- end
14
-
15
11
  desc "Build source files into output"
16
12
  task :build do
17
13
  Gumdrop.run()
18
14
  end
19
15
 
20
-
21
16
  desc "Run development server"
22
17
  task :serve do
23
18
  Gumdrop.config.auto_run= true
@@ -11,5 +11,6 @@ end
11
11
  require 'gumdrop'
12
12
 
13
13
  Gumdrop.config.auto_run= false
14
+ Gumdrop.run :dry_run=>true
14
15
 
15
16
  run Gumdrop::Server
@@ -1,2 +1,4 @@
1
1
  title: My Site
2
2
  tagline: My home on thar intarwebs!
3
+ author: Matt McCray
4
+ url: http://www.mysite.com
@@ -0,0 +1,14 @@
1
+ # Any specialized code for your site goes here...
2
+
3
+ # Example site-level generator
4
+ # generate do
5
+ #
6
+ # page "about.html", :template=>'about', :passthru=>'Available in the template' # requires a about.template.XX file
7
+ #
8
+ # # Maybe for a tumblr-like pager
9
+ # pager= Gumdrop.data.pager_for :posts, :base_path=>'posts/page', :page_size=>5
10
+ # pager.each do |page|
11
+ # page "#{page.uri}.html", :template=>'post_page', :posts=>page.items, :pager=>pager, :current_page=>pager.current_page
12
+ # end
13
+ #
14
+ # end
@@ -0,0 +1,23 @@
1
+ xml.instruct!
2
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3
+ xml.title data.config.title
4
+ xml.subtitle data.config.tagline
5
+ xml.id data.config.url
6
+ xml.link "href" => data.config.url
7
+ xml.link "href" => "#{data.config.url}/feed.xml", "rel" => "self"
8
+ xml.updated data.blog.first.date.to_time.iso8601
9
+ xml.author { xml.name data.config.author }
10
+
11
+ data.blog.each do |post|
12
+ xml.entry do
13
+ url= "#{data.config.url}/posts/#{post.slug}"
14
+ xml.title post.title
15
+ xml.link "rel" => "alternate", "href" => url
16
+ xml.id url
17
+ xml.published post.date.to_time.iso8601
18
+ xml.updated post.date.to_time.iso8601
19
+ xml.author { xml.name data.config.author }
20
+ xml.content post.body, "type" => "html"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+
2
+ @App=
3
+ init: ->
4
+ # Do something cool here
@@ -1,5 +1,5 @@
1
1
  module Gumdrop
2
2
 
3
- VERSION = "0.2.4" unless defined?(::Gumdrop::VERSION)
3
+ VERSION = "0.2.7" unless defined?(::Gumdrop::VERSION)
4
4
 
5
5
  end
@@ -2,10 +2,15 @@ module Gumdrop
2
2
 
3
3
  module ViewHelpers
4
4
 
5
- # Handy for hiding a block of unfinished code
6
- # def hidden(&block)
7
- # #no-op
8
- # end
5
+ def hidden(&block)
6
+ #no-op
7
+ end
8
+
9
+ def markdown(source)
10
+ m= Tilt['markdown'].new { source }
11
+ m.render
12
+ end
13
+
9
14
 
10
15
  def gumdrop_version
11
16
  ::Gumdrop::VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gumdrop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-07-22 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70163031231440 !ruby/object:Gem::Requirement
16
+ requirement: &70267787964340 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70163031231440
24
+ version_requirements: *70267787964340
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: tilt
27
- requirement: &70163031231020 !ruby/object:Gem::Requirement
27
+ requirement: &70267787963900 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70163031231020
35
+ version_requirements: *70267787963900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: active_support
38
- requirement: &70163031230600 !ruby/object:Gem::Requirement
38
+ requirement: &70267787963400 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70163031230600
46
+ version_requirements: *70267787963400
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: trollop
49
- requirement: &70163031230180 !ruby/object:Gem::Requirement
49
+ requirement: &70267787962920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70163031230180
57
+ version_requirements: *70267787962920
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: haml
60
- requirement: &70163031229760 !ruby/object:Gem::Requirement
60
+ requirement: &70267787962460 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70163031229760
68
+ version_requirements: *70267787962460
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sass
71
- requirement: &70163031229340 !ruby/object:Gem::Requirement
71
+ requirement: &70267787962000 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70163031229340
79
+ version_requirements: *70267787962000
80
80
  description: A simple cms/prototyping tool.
81
81
  email: matt@elucidata.net
82
82
  executables:
@@ -96,28 +96,43 @@ files:
96
96
  - examples/simple/Rakefile
97
97
  - examples/simple/config.ru
98
98
  - examples/simple/data/config.yml
99
+ - examples/simple/data/posts.yamldb
100
+ - examples/simple/lib/site.rb
99
101
  - examples/simple/lib/view_helpers.rb
102
+ - examples/simple/source/.htaccess
103
+ - examples/simple/source/_pager_control.html.erb
104
+ - examples/simple/source/_sidebar.html.haml
100
105
  - examples/simple/source/favicon.ico
106
+ - examples/simple/source/feed.xml.builder
101
107
  - examples/simple/source/index.html.erb
108
+ - examples/simple/source/posts.generator.rb
109
+ - examples/simple/source/posts/index.html.erb
102
110
  - examples/simple/source/theme/screen.css.scss
103
111
  - examples/simple/source/theme/scripts/app.js.coffee
104
112
  - examples/simple/source/theme/styles/_tools.scss
113
+ - examples/simple/source/theme/templates/post.template.haml
114
+ - examples/simple/source/theme/templates/post_page.template.haml
105
115
  - examples/simple/source/theme/templates/site.template.haml
116
+ - examples/simple/source/theme/templates/test.template.erb
106
117
  - gumdrop.gemspec
107
118
  - lib/gumdrop.rb
108
119
  - lib/gumdrop/cli.rb
109
120
  - lib/gumdrop/content.rb
110
121
  - lib/gumdrop/context.rb
122
+ - lib/gumdrop/deferred_loader.rb
111
123
  - lib/gumdrop/generator.rb
112
124
  - lib/gumdrop/hash_object.rb
125
+ - lib/gumdrop/pager.rb
113
126
  - lib/gumdrop/server.rb
114
127
  - lib/gumdrop/template/.htaccess
115
128
  - lib/gumdrop/template/Gemfile
116
129
  - lib/gumdrop/template/Rakefile
117
130
  - lib/gumdrop/template/config.ru
118
131
  - lib/gumdrop/template/data/config.yml
132
+ - lib/gumdrop/template/lib/site.rb
119
133
  - lib/gumdrop/template/lib/view_helpers.rb
120
134
  - lib/gumdrop/template/source/favicon.ico
135
+ - lib/gumdrop/template/source/feed.xml.builder.txt
121
136
  - lib/gumdrop/template/source/index.html.erb
122
137
  - lib/gumdrop/template/source/theme/screen.css.scss
123
138
  - lib/gumdrop/template/source/theme/scripts/app.js.coffee