soxer 0.9.4 → 0.9.5

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.
data/CHANGES ADDED
@@ -0,0 +1,34 @@
1
+ = 0.9.5 / 2010-10-00
2
+
3
+ * Inline documentation has been adjusted and slightly improved.
4
+
5
+ * The value of settings.origin is now a global system path, rather than a
6
+ local path from settings.root. Default is set to 'content', but you can
7
+ change it by Sinatra's standards.
8
+
9
+ * Atom file as progressed from -atom to .atom (dot atom) and soxer will now
10
+ server /any/path/to/file.atom with the application/atom+xml content type.
11
+
12
+ * Soxer has been modularized to Sinatra's standards, with the exception of
13
+ the name. It's still named soxer and not sinatra-soxer. This might change
14
+ in the future as we hit stable.
15
+
16
+ * Changed get_list method. It only accepts a block for filtering yaml files
17
+ Any sorting is now done by Array.sort {} afterwards.
18
+
19
+ * Fixed partial generator so it properly handles strings and symbols
20
+
21
+ * Cleaned up "soxer test" and only choose "thin" webserver if available.
22
+ Defaults to webrick (very slow).
23
+
24
+ = 0.9.4 / 2010-10-27
25
+
26
+ * Added executable 'soxer' to help generating application directories and
27
+ running developement versions
28
+
29
+ * Added skeletal directories, and 'empty' skeleton application
30
+
31
+ = 0.9.0 / 2010-10-24
32
+
33
+ * Initial release
34
+
data/bin/soxer CHANGED
@@ -85,7 +85,6 @@ def create
85
85
  FileUtils.mkdir(dir)
86
86
  FileUtils.cp_r(src+"/.", dir)
87
87
  return notice "Successfuly created '"+dir+"' Directory."
88
- #return Dir.glob(src+"/**/*").to_s
89
88
  else
90
89
  return err 'The destination directory exists.'
91
90
  end
@@ -96,27 +95,21 @@ end
96
95
 
97
96
  def test
98
97
  port = $*[1]!=nil ? $*[1] : '9394'
99
- server = false
100
- servers = %w[webrick mongrel thin]
101
- servers.each do |s|
102
- ENV['PATH'].split(':').each {|folder| server = s if File.exists?(folder+'/'+s)}
103
- end
104
- if server!=false
105
- system("rackup -s #{server} -p #{port}")
106
- return notice "End of developement mode."
107
- else
108
- return err "Please install a sinatra compatible web server (thin, mongrel or webrick.)"
109
- end
98
+ server = 'webrick'
99
+ ENV['PATH'].split(':').each {|folder| server = 'thin' if File.exists?(folder+'/thin')}
100
+ x = system("rackup -s #{server} -p #{port}")
101
+ return "Developement mode ends."
110
102
  end
111
103
 
112
104
  case $*[0]
113
105
  when 'create' then printf create
114
106
  when 'test' then printf test
107
+ when 'prank' then printf prank
115
108
  when 'help' then printf @help
116
109
  else printf err 'You did not specify an action!'
117
110
  end
118
111
 
119
-
112
+ # TO COME LATER
120
113
  x = <<END
121
114
  #{b 'corporate'} - Creates a corporate web page mockup
122
115
  #{b 'blog'} - Creates a blog mockup
data/lib/soxer/main.rb CHANGED
@@ -5,7 +5,7 @@ require 'uuid'
5
5
 
6
6
 
7
7
  module Sinatra
8
-
8
+
9
9
  #== Soxer, the web publishing tool.
10
10
  #
11
11
  # Soxer is a Sinatra module that adds additional methods to sinatra routes.
@@ -20,6 +20,14 @@ module Sinatra
20
20
  # License: Distributed under the GPL licence. http://www.gnu.org/licenses/gpl.html
21
21
  module Soxer
22
22
 
23
+ # === The Filereader class
24
+ #
25
+ # In addition to reading the YAML file it also adds two fields to the file:
26
+ # uuid: Universally Unique Identifier for atom and other feeds. Please, note
27
+ # that this id is not compared to other uuids. When creating a new
28
+ # document it's best to let soxer generate it.
29
+ # date: A standard date field. When creating a new document it's best to
30
+ # let soxer generate it.
23
31
  class Filereader
24
32
  attr_accessor :filename
25
33
 
@@ -32,7 +40,7 @@ module Sinatra
32
40
  out = YAML.load_file( @filename )
33
41
  add_date unless out['date']
34
42
  add_id unless out['uuid']
35
- out['url'] = @filename.gsub(/#{@s.root}\/#{@s.origin}(.+)\.yaml$/, "\\1" ).gsub(/(.+)\/index$/, "\\1" )
43
+ out['url'] = @filename.gsub(/#{@s.origin}(.+)\.yaml$/, "\\1" ).gsub(/(.+)\/index$/, "\\1" )
36
44
  out['mtime'] = File.mtime( @filename )
37
45
  out
38
46
  end
@@ -59,6 +67,12 @@ module Sinatra
59
67
  end
60
68
  end
61
69
 
70
+ # === The Urlreader class
71
+ #
72
+ # Urlreader simply checks if the URL recieved can be matched to a file.
73
+ # Currelntly it either matches a file path (ending with .yaml) from origin
74
+ # (the default is "content" directory within application root) or a
75
+ # directory path with index.yaml
62
76
  class Urlreader
63
77
  attr_accessor :url
64
78
 
@@ -69,8 +83,8 @@ module Sinatra
69
83
  def get_content
70
84
  self.settings
71
85
  fn = case true
72
- when File.exist?( f = File.join( @s.root, @s.origin, @url+'.yaml' ) ) then f
73
- when File.exist?( f = File.join( @s.root, @s.origin, @url+'/index.yaml' ) ) then f
86
+ when File.exist?( f = File.join( @s.origin, @url+'.yaml' ) ) then f
87
+ when File.exist?( f = File.join( @s.origin, @url+'/index.yaml' ) ) then f
74
88
  else throw :halt, [404, "Document not found"]
75
89
  end
76
90
  out = Filereader.new
@@ -78,158 +92,190 @@ module Sinatra
78
92
  out.get_content
79
93
  end
80
94
  end
81
-
82
- # === The "get_page", the document reading function
83
- #
84
- # Read the document in yaml format (with .yaml) ending directly mapped from
85
- # the given parameter. Sinatra's *settings.route* and Soxers
86
- # *settings.origin* are prefixed to the path in order to get an absolute
87
- # filename. If the filename cannot be found, a directory by that name and
88
- # an index file within are probed and read.
89
- #
90
- # If no parameter is given, the entire route is taken as the argument.
91
- def get_page url=params[:splat][0]
92
- out = Urlreader.new
93
- out.url = url
94
- out.get_content
95
+
96
+ module Helpers
97
+ # === The "get_page", the document reading function
98
+ #
99
+ # Read the document in yaml format (with .yaml) ending directly mapped from
100
+ # the given parameter. Sinatra's *settings.route* and Soxers
101
+ # *settings.origin* are prefixed to the path in order to get an absolute
102
+ # filename. If the filename cannot be found, a directory by that name and
103
+ # an index file within are probed and read.
104
+ #
105
+ # If no parameter is given, the entire route is taken as the argument.
106
+ def get_page url=params[:splat][0]
107
+ out = Urlreader.new
108
+ out.url = url
109
+ out.get_content
110
+ end
111
+
112
+ #=== The "get_list" the document listing function
113
+ #
114
+ # The get_list function is the aggregator function. It reads all available
115
+ # yaml files (that map to urls directly) and outputs them according to the
116
+ # arguments you send it. Get_list only accepts a block.
117
+ #==== &block
118
+ # Block is a callback, which filters the entire array of yaml files.
119
+ # The result is an array of hashes, representing a subset of all yaml
120
+ # files from "origin" directory. It can be sorted by using Array.sort
121
+ # method.
122
+ def get_list &block
123
+ pattern = File.join( settings.origin, "**", "*.yaml" )
124
+ output = Dir.glob(pattern).map! do |f|
125
+ file = Filereader.new
126
+ file.filename = f
127
+ if block_given?
128
+ f = block.call file.get_content
129
+ end
130
+ end.compact
131
+ end
132
+
133
+ #=== The "sitemap" the sitemap generator
134
+ #
135
+ # This funnction accepts no arguments. It simply renders a sitemap file
136
+ # with all available urls from the site
137
+ def sitemap
138
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'sitemap.haml' )
139
+ out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
140
+ out << haml( template, :layout => false )
141
+ end
142
+
143
+
144
+ #=== The "atom" the atom feed generator
145
+ #
146
+ # This method accepts an author (which is the global feed's author)
147
+ # This is a required option, as the feed is only valid if it has at least
148
+ # the global author. If individual articles have a yaml field "author",
149
+ # the individual article's author is used for that article. In both cases,
150
+ # author is a hash consisting of values 'name', 'email', 'url', of which
151
+ # at least the 'name' should always be present.
152
+ #
153
+ #==== autor
154
+ # Hash of values as required by the Atom standard:
155
+ # 'name', 'email' and 'url'. Only name is reuired.
156
+ #
157
+ #==== &block
158
+ # Block is a callback. Every file (in hash form) is passed to block and
159
+ # the block acts as the filter. That way only pages which are returned by
160
+ # block are included in the feed
161
+ def atom author=author, &block
162
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'atom.haml' )
163
+ pattern = File.join( settings.origin, "**", "*.yaml" )
164
+ output = Dir.glob(pattern).map! do |f|
165
+ file = Filereader.new
166
+ file.filename = f
167
+ if block_given?
168
+ block.call file.get_content
169
+ end
170
+ end.compact!.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
171
+ out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
172
+ out << haml( template, :layout => false, :locals => { :page=>get_page, :feed=>output, :author=>author } )
173
+ end
174
+
175
+ def google_ads options={}
176
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'google_ads.haml' )
177
+ pattern = File.join( settings.origin, "**", "*.yaml" )
178
+ haml( template, options.merge!( :layout => false ) )
179
+ end
180
+
181
+ def disqus options={}
182
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'disqus.haml' )
183
+ haml( template, options.merge!( :layout => false ) )
184
+ end
185
+
186
+ def google_analytics options={}
187
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'google_analytics.haml' )
188
+ haml( template, options.merge!( :layout => false ) )
189
+ end
190
+
191
+ #=== "partial" rails like partial generator
192
+ #
193
+ # This funnction accepts a string and matches it to a haml layout (with a
194
+ # underscore prepended) Sinatra's layouts directory.
195
+ #
196
+ #==== snippet
197
+ # A string that maps to a haml view in the views directory
198
+ # "partial :example, :layout => false" would map to a views/_example.haml
199
+ #
200
+ #==== options={}
201
+ # Any options you pass to this partial ger merged and sent to haml as
202
+ # sinatra's haml options (this is usefull for passing sinatra's :layout,
203
+ # :locals and other variables)
204
+ def partial(snippet, options={})
205
+ haml ('_'+snippet.to_s).to_sym, options.merge!(:layout => false)
206
+ end
207
+
208
+ #=== "link_to" rails like link_to generator
209
+ #
210
+ # This funnction accepts a 1 or 2 strings.
211
+ #
212
+ #==== text
213
+ # A string that becomes the link text. If there is no second parameter,
214
+ # link_to converts the string into a local url by replacing all spaces with
215
+ # an underscore and downcasing the string.
216
+ #
217
+ #==== url
218
+ # This string is used for 'href' in a link
219
+ def link_to(text, url="/#{text.downcase.gsub(/\s/,'_')}")
220
+ url.gsub!(/^\//, '') if url =~ /.+:\/\//
221
+ "<a href=\"#{url}\"> #{text}</a>"
222
+ end
223
+
224
+ # A simple string obuscator.
225
+ # Useful for hiding emails and such
226
+ #=== "obfuscate" simple string obuscator.
227
+ #
228
+ # This funnction accepts a 1 or 2 strings.
229
+ #
230
+ #==== str=nil
231
+ # Obfuscates a string replacing characters with html entities.
232
+ # Useful for hiding emails and such
233
+ def obfuscate(str=nil)
234
+ out = []
235
+ str.each_byte {|c| out << "&##{c};" }
236
+ out.join
237
+ end
238
+
95
239
  end
96
-
97
- #=== The "get_list" the document listing function
98
- #
99
- # The get_list function is the aggregator function. It reads all available
100
- # yaml files (that map to urls directly) and outputs them according to the
101
- # arguments you send it. Get_list only accepts 1 argument and a block.
102
- #
103
- #==== sort='desc'
104
- # Direction of output. 'desc' (descending) or 'asc' (ascending)The default
105
- # is 'desc'. If :sort conatins anything else, the output is unsorted.
106
- #
107
- #==== &block
108
- # Block is a callback. Every file (in hash form) is passed to block and
109
- # the block acts as the filter. :sort only takes the result and sorts it
110
- # according to the first key/value pair, so hash order IS signifficant.
111
- def get_list sort='desc', &block
112
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
113
- output = Dir.glob(pattern).map! do |f|
114
- file = Filereader.new
115
- file.filename = f
116
- if block_given?
117
- f = block.call file.get_content
240
+
241
+ def self.registered(app)
242
+ app.helpers Soxer::Helpers
243
+
244
+ def app.settings
245
+ Sinatra::Application
246
+ end
247
+
248
+ set :origin, File.join(app.settings.root, 'content')
249
+
250
+ app.get("/sitemap.xml") { sitemap }
251
+
252
+ app.get "/*.css" do
253
+ content_type "text/css", :charset => "utf-8"
254
+ sass params[:splat][0].to_sym
255
+ end
256
+
257
+ app.get '*.*' do
258
+ file = File.join( settings.origin, params[:splat].join('.') )
259
+ case params[:splat][1]
260
+ when /[jpg|png|pdf|doc|docx|xls|xlsx|pdf|]/i then send_file(file, :disposition => nil)
118
261
  end
119
- end.compact
120
- case sort
121
- when 'desc' then output.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
122
- when 'asc' then output.sort!{|a,b| a.to_a[0] <=> b.to_a[0] }
123
262
  end
124
- end
125
-
126
- #=== The "sitemap" the sitemap generator
127
- #
128
- # This funnction accepts no arguments. It simply renders a sitemap file
129
- # with all available urls from the site
130
- def sitemap
131
- template = File.read File.join( File.dirname(__FILE__), 'views', 'sitemap.haml' )
132
- out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
133
- out << haml( template, :layout => false )
134
- end
135
-
136
-
137
- #=== The "atom" the atom feed generator
138
- #
139
- # This method accepts an author (which is the global feed's author)
140
- # This is a required option, as the feed is only valid if it has at least
141
- # the global author. If individual articles have a yaml field "author",
142
- # the individual article's author is used for that article. In both cases,
143
- # author is a hash consisting of values 'name', 'email', 'url', of which
144
- # at least the 'name' should always be present.
145
- #
146
- #==== autor
147
- # Hash of values as required by the Atom standard:
148
- # 'name', 'email' and 'url'. Only name is reuired.
149
- #
150
- #==== &block
151
- # Block is a callback. Every file (in hash form) is passed to block and
152
- # the block acts as the filter. That way only pages which are returned by
153
- # block are included in the feed
154
- def atom author=author, &block
155
- template = File.read File.join( File.dirname(__FILE__), 'views', 'atom.haml' )
156
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
157
- output = Dir.glob(pattern).map! do |f|
158
- file = Filereader.new
159
- file.filename = f
160
- if block_given?
161
- block.call file.get_content
263
+
264
+ app.get '*/?' do
265
+ content_type "text/html", :charset => "utf-8"
266
+
267
+ if params[:splat].last =~ /\.atom$/ then
268
+ set :haml, { :format => :xhtml }
269
+ content_type "application/atom+xml", :charset => "utf-8"
162
270
  end
163
- end.compact!.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
164
- out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
165
- out << haml( template, :layout => false, :locals => { :page=>get_page, :feed=>output, :author=>author } )
166
- end
167
-
168
- def google_ads options={}
169
- template = File.read File.join( File.dirname(__FILE__), 'views', 'google_ads.haml' )
170
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
171
- haml( template, options.merge!( :layout => false ) )
172
- end
173
-
174
- def disqus options={}
175
- template = File.read File.join( File.dirname(__FILE__), 'views', 'disqus.haml' )
176
- haml( template, options.merge!( :layout => false ) )
177
- end
178
-
179
- def google_analytics options={}
180
- template = File.read File.join( File.dirname(__FILE__), 'views', 'google_analytics.haml' )
181
- haml( template, options.merge!( :layout => false ) )
182
- end
183
-
184
- #=== "partial" rails like partial generator
185
- #
186
- # This funnction accepts a string and matches it to a haml layout (with a
187
- # underscore prepended) Sinatra's layouts directory.
188
- #
189
- #==== snippet
190
- # A string that maps to a haml view in the views directory
191
- # "partial :example, :layout => false" would map to a views/_example.haml
192
- #
193
- #==== options={}
194
- # Any options you pass to this partial ger merged and sent to haml as
195
- # sinatra's haml options (this is usefull for passing sinatra's :layout,
196
- # :locals and other variables)
197
- def partial(snippet, options={})
198
- haml ('_'+snippet).to_sym, options.merge!(:layout => false)
199
- end
200
-
201
- #=== "link_to" rails like link_to generator
202
- #
203
- # This funnction accepts a 1 or 2 strings.
204
- #
205
- #==== text
206
- # A string that becomes the link text. If there is no second parameter,
207
- # link_to converts the string into a local url by replacing all spaces with
208
- # an underscore and downcasing the string.
209
- #
210
- #==== url
211
- # This string is used for 'href' in a link
212
- def link_to(text, url="/#{text.downcase.gsub(/\s/,'_')}")
213
- url.gsub!(/^\//, '') if url =~ /.+:\/\//
214
- "<a href=\"#{url}\"> #{text}</a>"
215
- end
216
-
217
- # A simple string obuscator.
218
- # Useful for hiding emails and such
219
- #=== "obfuscate" simple string obuscator.
220
- #
221
- # This funnction accepts a 1 or 2 strings.
222
- #
223
- #==== str=nil
224
- # Obfuscates a string replacing characters with html entities.
225
- # Useful for hiding emails and such
226
- def obfuscate(str=nil)
227
- out = []
228
- str.each_byte {|c| out << "&##{c};" }
229
- out.join
271
+
272
+ page = get_page
273
+ page['layout'] ||= 'layout'
274
+ haml page['content'], :layout => page['layout'].to_sym, :locals => { :page => page }
275
+ end
230
276
  end
231
-
232
277
  end
233
-
234
- helpers Soxer
278
+
279
+ register Soxer
235
280
  end
281
+
@@ -5,9 +5,9 @@ require "app"
5
5
  disable :run
6
6
  set :server, %w[thin mongrel webrick]
7
7
  set :origin, "content"
8
- set :haml, {:encoding => 'utf-8',
9
- :format => :html5,
10
- :attr_wrapper => '"' }
8
+ set :haml, {:format => :html5,
9
+ :attr_wrapper => '"'}
10
+ set :haml, {:encoding => 'utf-8'} if RUBY_VERSION=~/1\.9/
11
11
 
12
12
  configure :development do
13
13
  require 'sinatra/reloader'
@@ -15,6 +15,7 @@ configure :development do
15
15
  end
16
16
 
17
17
  configure :production do
18
+ set :haml, {:ugly => true}
18
19
  set :port, 55500
19
20
  end
20
21
 
data/soxer.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.7'
5
5
 
6
6
  s.name = 'soxer'
7
- s.version = '0.9.4'
8
- s.date = '2010-10-27'
7
+ s.version = '0.9.5'
8
+ s.date = '2010-11-01'
9
9
  s.rubyforge_project = 'soxer'
10
10
 
11
11
  s.summary = "Dynamic web site generator engine"
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  # = MANIFEST =
28
28
  s.files = %w[
29
29
  soxer.gemspec
30
+ CHANGES
30
31
  bin/soxer
31
32
  lib/soxer.rb
32
33
  lib/soxer/main.rb
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soxer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
4
+ hash: 49
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 4
10
- version: 0.9.4
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Toni Anzlovar
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-27 00:00:00 +02:00
18
+ date: 2010-11-01 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -70,6 +70,7 @@ extra_rdoc_files: []
70
70
 
71
71
  files:
72
72
  - soxer.gemspec
73
+ - CHANGES
73
74
  - bin/soxer
74
75
  - lib/soxer.rb
75
76
  - lib/soxer/main.rb