brite 0.5 → 0.6.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 (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
+