brite 0.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/HISTORY.rdoc +30 -0
  2. data/LICENSE +199 -17
  3. data/README.rdoc +61 -0
  4. data/Syckfile +76 -0
  5. data/bin/brite +3 -3
  6. data/bin/brite-server +4 -0
  7. data/lib/brite.rb +11 -0
  8. data/lib/brite/command.rb +53 -56
  9. data/lib/brite/config.rb +94 -18
  10. data/lib/brite/controller.rb +181 -0
  11. data/lib/brite/layout.rb +24 -19
  12. data/lib/brite/meta/data.rb +26 -0
  13. data/lib/brite/meta/package +8 -0
  14. data/lib/brite/meta/profile +19 -0
  15. data/lib/brite/models/model.rb +97 -0
  16. data/lib/brite/models/page.rb +142 -0
  17. data/lib/brite/models/post.rb +9 -0
  18. data/lib/brite/models/site.rb +46 -0
  19. data/lib/brite/rackup.rb +6 -0
  20. data/lib/brite/server.rb +144 -0
  21. data/lib/plugins/sow/brite/awesome/Sowfile +11 -0
  22. data/lib/plugins/sow/brite/awesome/about.page +28 -0
  23. data/lib/plugins/sow/brite/awesome/assets/custom.less +96 -0
  24. data/lib/plugins/sow/brite/awesome/assets/fade.png +0 -0
  25. data/lib/plugins/sow/brite/awesome/assets/highlight.css +96 -0
  26. data/lib/plugins/sow/brite/awesome/assets/highlight.js +1 -0
  27. data/lib/plugins/sow/brite/awesome/assets/jquery.js +19 -0
  28. data/lib/plugins/sow/brite/awesome/assets/jquery.tabs.js +1 -0
  29. data/lib/plugins/sow/brite/awesome/assets/reset.css +57 -0
  30. data/lib/plugins/sow/brite/awesome/assets/ruby.png +0 -0
  31. data/lib/plugins/sow/brite/awesome/brite.yaml +3 -0
  32. data/lib/plugins/sow/brite/awesome/history.page +15 -0
  33. data/lib/plugins/sow/brite/awesome/index.page +18 -0
  34. data/lib/plugins/sow/brite/awesome/legal.page +28 -0
  35. data/lib/plugins/sow/brite/awesome/logs.page +14 -0
  36. data/lib/plugins/sow/brite/awesome/page.layout +75 -0
  37. data/lib/plugins/sow/brite/blog1/.rsync-filter +12 -0
  38. data/lib/plugins/sow/brite/blog1/2011/01/sample.html +293 -0
  39. data/lib/plugins/sow/brite/blog1/2011/01/sample.post +44 -0
  40. data/lib/plugins/sow/brite/blog1/Sowfile +10 -0
  41. data/lib/plugins/sow/brite/blog1/assets/images/bg.jpg +0 -0
  42. data/lib/plugins/sow/brite/blog1/assets/images/icon.jpg +0 -0
  43. data/lib/plugins/sow/brite/blog1/assets/styles/class.css +15 -0
  44. data/lib/plugins/sow/brite/blog1/assets/styles/id.css +85 -0
  45. data/lib/plugins/sow/brite/blog1/assets/styles/misc.css +0 -0
  46. data/lib/plugins/sow/brite/blog1/assets/styles/print.css +76 -0
  47. data/lib/plugins/sow/brite/blog1/assets/styles/reset.css +77 -0
  48. data/lib/plugins/sow/brite/blog1/assets/styles/tag.css +68 -0
  49. data/lib/plugins/sow/brite/blog1/brite.yml +3 -0
  50. data/lib/plugins/sow/brite/blog1/index.page +23 -0
  51. data/lib/plugins/sow/brite/blog1/page.layout +88 -0
  52. data/lib/plugins/sow/brite/blog1/post.layout +25 -0
  53. data/meta/data.rb +26 -0
  54. data/meta/package +8 -0
  55. data/meta/profile +19 -0
  56. metadata +86 -47
  57. data/HISTORY +0 -16
  58. data/MANIFEST +0 -28
  59. data/README +0 -42
  60. data/lib/brite/page.rb +0 -235
  61. data/lib/brite/part.rb +0 -31
  62. data/lib/brite/post.rb +0 -37
  63. data/lib/brite/site.rb +0 -137
  64. data/lib/brite/template.rb +0 -215
  65. data/meta/authors +0 -1
  66. data/meta/contact +0 -1
  67. data/meta/copyright +0 -1
  68. data/meta/description +0 -4
  69. data/meta/homepage +0 -1
  70. data/meta/license +0 -1
  71. data/meta/name +0 -1
  72. data/meta/repository +0 -1
  73. data/meta/requires +0 -1
  74. data/meta/ruby +0 -2
  75. data/meta/subtitle +0 -1
  76. data/meta/suite +0 -1
  77. data/meta/summary +0 -1
  78. data/meta/title +0 -1
  79. data/meta/version +0 -1
data/lib/brite/config.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'yaml'
1
2
  require 'ostruct'
2
3
 
3
4
  module Brite
@@ -5,26 +6,101 @@ module Brite
5
6
  # Configuration
6
7
  class Config
7
8
 
8
- #
9
- DEFAULTS = {
10
- :stencil => 'rhtml',
11
- #:format => 'html',
12
- :pagelayout => 'page',
13
- :postlayout => 'post',
14
- :maxchars => 500,
15
- }
16
-
17
- attr :defaults
18
-
19
- def initialize
20
- if File.exist?('.config/defaults')
21
- custom_defaults = YAML.load(File.new('.config/defaults'))
22
- else
23
- custom_defaults = {}
9
+ # Configuration file name glob.
10
+ CONFIG_FILE = '{.brite,brite.yml,brite.yaml}'
11
+
12
+ # Default URL, which is just for testing purposes.
13
+ DEFAULT_URL = 'http://0.0.0.0:4321'
14
+
15
+ # Default stencil.
16
+ DEFAULT_STENCIL = 'rhtml' #'liquid' # 'rhtml'
17
+
18
+ # Default format.
19
+ DEFAULT_FORMAT = nil #html
20
+
21
+ # Default page layout file name (less `.layout` extension).
22
+ DEFAULT_PAGE_LAYOUT = 'page'
23
+
24
+ # Default post layout file name (less `.layout` extension).
25
+ DEFAULT_POST_LAYOUT = 'post'
26
+
27
+ # Location of brite files.
28
+ attr :location
29
+
30
+ # Site's absolute URL. Where possible links are relative,
31
+ # but it is not alwasy possible. So a URL should *ALWAYS*
32
+ # be provided for the site.
33
+ #--
34
+ # TODO: Allow +url+ to be set via the command line when generating the site.
35
+ #++
36
+ attr_accessor :url
37
+
38
+ # Defaut section template engine.
39
+ attr_accessor :stencil
40
+
41
+ # Default section markup format.
42
+ attr_accessor :format
43
+
44
+ # Default page layout file name (less extension).
45
+ attr_accessor :page_layout
46
+
47
+ # Default post layout file name (less extension).
48
+ attr_accessor :post_layout
49
+
50
+ # New instance of Config.
51
+ def initialize(location=nil)
52
+ @location = location || Dir.pwd
53
+
54
+ @url = DEFAULT_URL
55
+ @stencil = DEFAULT_STENCIL
56
+ @format = DEFAULT_FORMAT
57
+
58
+ @page_layout = DEFAULT_PAGE_LAYOUT
59
+ @post_layout = DEFAULT_POST_LAYOUT
60
+
61
+ configure
62
+ end
63
+
64
+ # Load configuration file.
65
+ def configure
66
+ if file = Dir[File.join(location, CONFIG_FILE)].first
67
+ data = YAML.load(File.new(file))
68
+ data.each do |k,v|
69
+ __send__("#{k}=", v)
70
+ end
71
+ end
72
+ end
73
+
74
+ #def initialize_defaults
75
+ # if file = Dir['{.,}config/defaults{,.yml,.yaml}'].first
76
+ # custom_defaults = YAML.load(File.new(file))
77
+ # else
78
+ # custom_defaults = {}
79
+ # end
80
+ # @defaults = OpenStruct.new(DEFAULTS.merge(custom_defaults))
81
+ #end
82
+
83
+ # FIXME: Is this used? What about page vs pagelayout?
84
+ #def defaults
85
+ # @defaults ||= OpenStruct.new(
86
+ # :stencil => stencil,
87
+ # :format => format,
88
+ # :pagelayout => page,
89
+ # :postlayout => post
90
+ # )
91
+ #end
92
+
93
+ # Use Gemdo.
94
+ def gemdo=(set)
95
+ return unless set
96
+ require 'gemdo'
97
+ Brite::Context.class_eval do
98
+ def project
99
+ @project ||= Gemdo::Project.new
100
+ end
24
101
  end
25
- @defaults = OpenStruct.new(DEFAULTS.merge(custom_defaults))
26
102
  end
103
+
27
104
  end
28
105
 
29
106
  end
30
-
@@ -0,0 +1,181 @@
1
+ require 'neapolitan'
2
+ require 'brite/config'
3
+ require 'brite/layout'
4
+ require 'brite/models/site'
5
+ require 'brite/models/page'
6
+ require 'brite/models/post'
7
+
8
+ module Brite
9
+
10
+ # The Controller class is the primary Brite class, handling
11
+ # the generation of site files.
12
+ class Controller
13
+
14
+ # New Controller.
15
+ def initialize(options={})
16
+ @location = options[:location] || Dir.pwd
17
+ @output = options[:output]
18
+ @url = options[:url]
19
+ @dryrun = options[:dryrun]
20
+ @trace = options[:trace]
21
+
22
+ @layouts = []
23
+
24
+ initialize_site
25
+ end
26
+
27
+ # Returns an instance of Site.
28
+ def initialize_site
29
+ @site = Site.new(:url=>url)
30
+
31
+ Dir.chdir(location) do
32
+ files = Dir['**/*']
33
+ files.each do |file|
34
+ name = File.basename(file)
35
+ ext = File.extname(file)
36
+ case ext
37
+ when '.layout'
38
+ layouts << Layout.new(self, file)
39
+ when '.page' #*%w{.markdown .rdoc .textile .whtml}
40
+ @site.pages << initialize_page(file)
41
+ when '.post'
42
+ @site.posts << initialize_post(file)
43
+ end
44
+ end
45
+ end
46
+ @site.posts.sort!{ |a,b| b.date <=> a.date }
47
+ @site
48
+ end
49
+
50
+ # Returns an instance of Page.
51
+ #++
52
+ # TODO: Limit Neapolitan to Markup formats only.
53
+ #--
54
+ def initialize_page(file)
55
+ template = Neapolitan.file(file, :stencil=>config.stencil)
56
+ settings = template.header
57
+
58
+ settings[:site] = site
59
+ settings[:file] = file
60
+
61
+ Page.new(settings){ |page| render(template, page) }
62
+ end
63
+
64
+ # Returns an instance of Post.
65
+ def initialize_post(file)
66
+ template = Neapolitan.file(file, :stencil=>config.stencil)
67
+ settings = template.header
68
+
69
+ settings[:site] = site
70
+ settings[:file] = file
71
+
72
+ Post.new(settings){ |post| render(template, post) }
73
+ end
74
+
75
+ # Returns an instance of Site.
76
+ attr :site
77
+
78
+ #
79
+ attr :location
80
+
81
+ #
82
+ attr :output
83
+
84
+ # Is `dryrun` mode on?
85
+ def dryrun?
86
+ @dryrun
87
+ end
88
+
89
+ # Is `trace` mode on?
90
+ def trace?
91
+ @trace
92
+ end
93
+
94
+ # Returns an Array of Layouts.
95
+ def layouts
96
+ @layouts
97
+ end
98
+
99
+ # Access to configuration file data.
100
+ def config
101
+ @config ||= Config.new(location)
102
+ end
103
+
104
+ # URL of site as set in initializer or configuration file.
105
+ def url
106
+ @url ||= config.url
107
+ end
108
+
109
+ #
110
+ def render(template, model) #scope=nil, &body)
111
+ #if scope
112
+ # scope.merge!(attributes)
113
+ #else
114
+ # scope = to_scope
115
+ #end
116
+
117
+ render = template.render(model) #, &body)
118
+
119
+ model.summary = render.summary # TODO: make part of neapolitan?
120
+
121
+ result = render.to_s
122
+
123
+ if model.layout
124
+ layout = lookup_layout(model.layout)
125
+ raise "No such layout -- #{layout}" unless layout
126
+ result = layout.render(model){ result }
127
+ end
128
+
129
+ result.to_s.strip
130
+ end
131
+
132
+ # Lookup layout by name.
133
+ def lookup_layout(name)
134
+ layouts.find{ |layout| name == layout.name }
135
+ end
136
+
137
+ # Build site.
138
+ def build
139
+ if trace?
140
+ puts "Layouts: " + layouts.map{ |layout| layout.name }.join(", ")
141
+ puts "Pages: " + pages.map{ |page| page.file }.join(", ")
142
+ puts "Posts: " + posts.map{ |post| post.file }.join(", ")
143
+ puts
144
+ end
145
+ Dir.chdir(location) do
146
+ site.posts.each do |post|
147
+ save(post)
148
+ end
149
+ site.pages.each do |page|
150
+ save(page)
151
+ end
152
+ end
153
+ puts "#{site.pages.size + site.posts.size} Files: #{site.pages.size} Pages, #{site.posts.size} Posts"
154
+ end
155
+
156
+ # Save page/post redering to disk.
157
+ def save(model)
158
+ file = output ? File.join(output, model.output) : model.output
159
+ text = model.to_s
160
+
161
+ if File.exist?(file)
162
+ current = File.read(file)
163
+ else
164
+ current = nil
165
+ end
166
+
167
+ if current != text or $FORCE
168
+ if dryrun?
169
+ puts " dry run: #{file}"
170
+ else
171
+ puts " write: #{file}"
172
+ File.open(file, 'w'){ |f| f << text }
173
+ end
174
+ else
175
+ puts " unchanged: #{file}"
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ end
data/lib/brite/layout.rb CHANGED
@@ -1,34 +1,39 @@
1
1
  module Brite
2
2
 
3
3
  # Layout class
4
- class Layout < Page
5
- undef_method :save
6
-
7
- #def to_contextual_attributes
8
- # { 'site'=>site.to_h }
9
- #end
4
+ class Layout
10
5
 
11
6
  #
12
- def render(attributes={})
13
- #attributes = to_contextual_attributes
14
- #attributes['content'] = content if content
7
+ def initialize(controller, file)
8
+ @controller = controller
9
+ @file = file
10
+ @name = file.chomp('.layout')
11
+ @path = File.expand_path(file)
12
+ end
13
+
14
+ attr :controller
15
+
16
+ attr :file
15
17
 
16
- output = parts.map{ |part| part.render(stencil, attributes) }.join("\n")
18
+ attr :path
17
19
 
18
- #@content = output
20
+ attr :name
19
21
 
20
- attributes = attributes.merge('content'=>output)
22
+ # TODO: merge in layout header
23
+ def render(model, &content)
24
+ template = Neapolitan.file(path, :stencil=>controller.config.stencil)
25
+
26
+ result = template.render(model, &content).to_s
27
+
28
+ layout = template.header['layout']
21
29
 
22
30
  if layout
23
- output = site.lookup_layout(layout).render(attributes)
31
+ layout = controller.lookup_layout(layout)
32
+ raise "No such layout -- #{layout}" unless layout
33
+ result = layout.render(model){ result }
24
34
  end
25
35
 
26
- output
27
- end
28
-
29
- # Layouts have no default layout.
30
- def default_layout
31
- nil
36
+ result.to_s
32
37
  end
33
38
 
34
39
  end
@@ -0,0 +1,26 @@
1
+ module Brite
2
+
3
+ def self.package
4
+ @package ||= (
5
+ require 'yaml'
6
+ YAML.load(File.new(File.dirname(__FILE__) + '/package'))
7
+ )
8
+ end
9
+
10
+ def self.profile
11
+ @profile ||= (
12
+ require 'yaml'
13
+ YAML.load(File.new(File.dirname(__FILE__) + '/profile'))
14
+ )
15
+ end
16
+
17
+ def self.const_missing(name)
18
+ key = name.to_s.downcase
19
+ package[key] || profile[key] || super(name)
20
+ end
21
+
22
+ end
23
+
24
+ # becuase Ruby 1.8~ gets in the way
25
+ Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION)
26
+
@@ -0,0 +1,8 @@
1
+ ---
2
+ name : brite
3
+ date : 2010-11-12
4
+ version : 0.6.0
5
+
6
+ requires:
7
+ - neapolitan 0.3.0+
8
+
@@ -0,0 +1,19 @@
1
+ ---
2
+ title : Brite
3
+ subtitle : Light Up Your Site
4
+ summary : Super Simple Static Site Generation
5
+ copyright: Copyright (c) 2006,2009 Thomas Sawyer
6
+ license : Apache v2.0
7
+ suite : proutils
8
+ contact : http://googlegroups.com/group/proutils
9
+ authors : Thomas Sawyer
10
+
11
+ description:
12
+ Brite is a remarkably easy to use, light-weight website
13
+ generator. It supports a variety of backend rendering engines
14
+ including rhtml via eruby, textile via redcloth, markdown
15
+ via rdiscount, with others on the way.
16
+
17
+ resources:
18
+ homepage: http://proutils.github.com/brite
19
+ repository: git://github.com/proutils/brite.git
@@ -0,0 +1,97 @@
1
+ module Brite
2
+
3
+ #
4
+ class Model
5
+
6
+ # Designate a field to be omitted from rendering context.
7
+ def self.omit_field(name)
8
+ omit_fields << (RUBY_VERSION >= "1.9" ? name.to_sym : name.to_s)
9
+ end
10
+
11
+ # Returns an Array of omitted fields for this class.
12
+ def self.omit_fields
13
+ @omit_fields ||= []
14
+ end
15
+
16
+ #
17
+ def self.attr_accessor(name, &default)
18
+ name = name.to_sym
19
+ if default
20
+ define_method(name) do
21
+ value = instance_variable_get("@#{name}") || instance_eval(&default)
22
+ (class << self; self; end).class_eval do
23
+ define_method(name){ value }
24
+ end
25
+ value
26
+ end
27
+ else
28
+ attr_reader(name)
29
+ end
30
+ attr_writer(name)
31
+ end
32
+
33
+ # Define a singleton method for given key-value pair.
34
+ def []=(k,v)
35
+ (class << self; self; end).class_eval do
36
+ define_method(k){v}
37
+ end
38
+ end
39
+
40
+ # Returns a Binding for this instance.
41
+ def to_binding(&block)
42
+ binding
43
+ end
44
+
45
+ # Returns a Hash of rendering fields.
46
+ def to_h
47
+ hash = {}
48
+ fields = rendering_fields
49
+ fields.each do |field|
50
+ hash[field.to_s] = __send__(field)
51
+ end
52
+ #extra.each do |k,v|
53
+ # hash[k.to_s] == v
54
+ #end
55
+ hash
56
+ end
57
+
58
+ # In case Liquid template is used.
59
+ def to_liquid
60
+ to_h
61
+ end
62
+
63
+ # Returns an Array of attribute/method names to be visible to the page
64
+ # rendering.
65
+ def rendering_fields
66
+ list = public_methods
67
+ list -= Model.public_instance_methods
68
+ list -= omit_fields
69
+ list.select do |name|
70
+ case name.to_s
71
+ when /\W+/ then false
72
+ when /^to_/ then false
73
+ else
74
+ true
75
+ end
76
+ end
77
+ end
78
+
79
+ # Returns an Array of attribute/method names explicitly omitted from
80
+ # being visible from the rendering.
81
+ def omit_fields
82
+ list = []
83
+ self.class.ancestors.reverse_each do |ancestor|
84
+ list.concat(ancestor.omit_fields) if ancestor.respond_to?(:omit_fields)
85
+ end
86
+ list
87
+ end
88
+
89
+ #
90
+ def singleton_class
91
+ (class << self; self; end)
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+