gumdrop 0.2.4 → 0.2.7

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 (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