frank 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.md +42 -1
  2. data/Rakefile +6 -3
  3. data/VERSION +1 -1
  4. data/bin/frank +3 -26
  5. data/bin/frankup +1 -0
  6. data/frank.gemspec +65 -12
  7. data/lib/frank.rb +10 -3
  8. data/lib/frank/base.rb +80 -55
  9. data/lib/frank/imager.rb +39 -0
  10. data/lib/frank/lorem.rb +54 -0
  11. data/lib/frank/output.rb +7 -8
  12. data/lib/frank/rescue.rb +6 -6
  13. data/lib/frank/statik.rb +23 -21
  14. data/lib/frank/template_helpers.rb +8 -2
  15. data/lib/frank/templates/404.haml +1 -1
  16. data/lib/frank/templates/imager/frank0.jpg +0 -0
  17. data/lib/frank/templates/imager/frank1.jpg +0 -0
  18. data/lib/frank/templates/imager/frank2.jpg +0 -0
  19. data/lib/frank/templates/imager/frank3.jpg +0 -0
  20. data/lib/frank/templates/imager/frank4.jpg +0 -0
  21. data/lib/frank/templates/imager/frank5.jpg +0 -0
  22. data/lib/frank/templates/imager/frank6.jpg +0 -0
  23. data/lib/frank/templates/imager/frank7.jpg +0 -0
  24. data/lib/frank/templates/imager/frank8.jpg +0 -0
  25. data/lib/frank/templates/imager/frank9.png +0 -0
  26. data/test/helper.rb +29 -0
  27. data/test/suite.rb +4 -0
  28. data/test/template/dynamic/_partial.haml +1 -0
  29. data/test/template/dynamic/builder.builder +1 -0
  30. data/test/template/dynamic/coffee.coffee +1 -0
  31. data/test/template/dynamic/erb.erb +1 -0
  32. data/test/template/dynamic/helper_test.haml +1 -0
  33. data/test/template/dynamic/index.haml +2 -0
  34. data/test/template/dynamic/layout.haml +2 -0
  35. data/test/template/dynamic/layout2.haml +2 -0
  36. data/test/template/dynamic/layout2_test.haml +1 -0
  37. data/test/template/dynamic/layout_test.haml +1 -0
  38. data/test/template/dynamic/liquid.liquid +1 -0
  39. data/test/template/dynamic/lorem_test.haml +4 -0
  40. data/test/template/dynamic/markdown.md +1 -0
  41. data/test/template/dynamic/mustache.mustache +1 -0
  42. data/test/template/dynamic/partial_test.haml +2 -0
  43. data/test/template/dynamic/redcloth.textile +1 -0
  44. data/test/template/dynamic/sass.sass +2 -0
  45. data/test/template/helpers.rb +5 -0
  46. data/test/template/settings.yml +67 -0
  47. data/test/template/static/static.html +1 -0
  48. data/test/test_base.rb +81 -0
  49. data/test/test_helpers.rb +53 -0
  50. data/test/test_output.rb +81 -0
  51. data/test/test_render.rb +89 -0
  52. metadata +71 -7
@@ -0,0 +1,39 @@
1
+ module Frank
2
+ begin
3
+ require 'mini_magick'
4
+ rescue LoadError
5
+ end
6
+
7
+ class Imager
8
+
9
+ def initialize(app, options={})
10
+ @app = app
11
+ end
12
+
13
+ # choose a random image if random is in the query
14
+ def image_filename(dims, query)
15
+ if query.include?('random')
16
+ "frank#{rand(10)}.jpg"
17
+ else
18
+ "frank#{dims.hash.to_s[-1..-1]}.jpg"
19
+ end
20
+ end
21
+
22
+ # catch a request for _img/0x0, get an image, resize it to given dims
23
+ def call(env)
24
+ path = env['PATH_INFO']
25
+ image_path = File.expand_path(File.dirname(__FILE__)) + '/templates/imager/'
26
+
27
+ if defined?(MiniMagick) && path.include?('_img')
28
+ dims = '!' + path.split('/').last.match(/\d+x\d+/i).to_s
29
+ filename = image_filename(dims, env['QUERY_STRING'])
30
+
31
+ image = MiniMagick::Image.from_file(image_path + filename)
32
+ image.resize dims
33
+ return [ 200, { 'Content-Type' => 'image/jpg' }, image.to_blob ]
34
+ end
35
+ @app.call(env)
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ module Frank
2
+ class Lorem
3
+ WORDS = %w(alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo aspernatur aut odit aut fugit sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt neque dolorem ipsum quia dolor sit amet consectetur adipisci velit sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem ut enim ad minima veniam quis nostrum exercitationem ullam corporis nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam nisi ut aliquid ex ea commodi consequatur quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi id est laborum et dolorum fuga et harum quidem rerum facilis est et expedita distinctio nam libero tempore cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est qui minus id quod maxime placeat facere possimus omnis voluptas assumenda est omnis dolor repellendus temporibus autem quibusdam et aut consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur at vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae itaque earum rerum hic tenetur a sapiente delectus ut aut reiciendis voluptatibus maiores doloribus asperiores repellat)
4
+
5
+ class << self
6
+
7
+ def word
8
+ words 1
9
+ end
10
+
11
+ def words(total)
12
+ (1..total).map do
13
+ randm(WORDS)
14
+ end.join(' ')
15
+ end
16
+
17
+ def sentence
18
+ sentences 1
19
+ end
20
+
21
+ def sentences(total)
22
+ (1..total).map do
23
+ words(randm(4..15)).capitalize
24
+ end.join('. ')
25
+ end
26
+
27
+ def paragraph
28
+ paragraphs 1
29
+ end
30
+
31
+ def paragraphs(total)
32
+ (1..total).map do
33
+ sentences(randm(3..7)).capitalize
34
+ end.join("\n\n")
35
+ end
36
+
37
+ def image(width, height, random=false)
38
+ if defined? MiniMagick
39
+ "/_img/#{width.to_s}x#{height.to_s}.jpg#{'?random' + (10000 + rand(10000)).to_s if random}"
40
+ else
41
+ raise Frank::ConfigError, 'mini_magick is required for lorem.image, please install it with `gem install mini_magick`'
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def randm(range)
48
+ a = range.to_a
49
+ a[rand(a.length)]
50
+ end
51
+
52
+ end
53
+ end
54
+ end
data/lib/frank/output.rb CHANGED
@@ -4,7 +4,7 @@ module Frank
4
4
  class Output < Frank::Base
5
5
  include Frank::Render
6
6
 
7
- attr_accessor :static_folder, :dynamic_folder, :templates, :output_folder, :proj_dir
7
+ attr_accessor :environment, :proj_dir, :static_folder, :dynamic_folder, :templates, :output_folder
8
8
 
9
9
  def initialize(&block)
10
10
  instance_eval &block
@@ -12,31 +12,30 @@ module Frank
12
12
  end
13
13
 
14
14
  def compile_templates
15
- dir = File.join( @proj_dir, @dynamic_folder )
15
+ dir = File.join(@proj_dir, @dynamic_folder)
16
16
 
17
17
  Find.find(dir) do |path|
18
- if FileTest.file?(path) and !File.basename(path).match(/^\./)
18
+ if FileTest.file?(path) and !File.basename(path).match(/^(\.|_)/)
19
19
  path = path[ dir.size + 1 ..-1 ]
20
20
  name, ext = name_ext(path)
21
21
  new_ext = reverse_ext_lookup(ext)
22
- new_file = File.join( @output_folder, "#{name}.#{new_ext}")
22
+ new_file = File.join(@proj_dir, @output_folder, "#{name}.#{new_ext}")
23
23
  FileUtils.makedirs(new_file.split('/').reverse[1..-1].reverse.join('/'))
24
-
25
24
  File.open(new_file, 'w') {|f| f.write render_path(path) }
26
- puts "Create #{name}.#{new_ext}"
25
+ puts "Create #{name}.#{new_ext}" unless @environment == :test
27
26
  end
28
27
  end
29
28
  end
30
29
 
31
30
  def copy_static
32
- puts "Copying over your static content"
31
+ puts "Copying over your static content" unless @environment == :test
33
32
  static_folder = File.join(@proj_dir, @static_folder)
34
33
  FileUtils.cp_r(File.join(static_folder, '/.'), @output_path)
35
34
  end
36
35
 
37
36
  def dump
38
37
  FileUtils.mkdir(@output_path)
39
- puts "Create #{@output_folder}"
38
+ puts "Create #{@output_folder}" unless @environment == :test
40
39
 
41
40
  compile_templates
42
41
  copy_static
data/lib/frank/rescue.rb CHANGED
@@ -3,21 +3,21 @@ module Frank
3
3
 
4
4
  def render_404
5
5
  template = File.expand_path(File.dirname(__FILE__)) + '/templates/404.haml'
6
-
6
+ locals = { :request => @env, :dynamic_folder => @dynamic_folder }
7
+
7
8
  @response['Content-Type'] = 'text/html'
8
9
  @response.status = 404
9
- @response.body = tilt_lang(template, 'haml', Object.new, locals = { :request => @env, :params => @request.params, :dynamic_folder => @dynamic_folder })
10
-
10
+ @response.body = Tilt.new(template, 1).render(Object.new, locals = locals)
11
11
  log_request('404')
12
12
  end
13
13
 
14
14
  def render_500(excp)
15
15
  template = File.expand_path(File.dirname(__FILE__)) + '/templates/500.haml'
16
-
16
+ locals = { :request => @env, :params => @request.params, :exception => excp }
17
+
17
18
  @response['Content-Type'] = 'text/html'
18
19
  @response.status = 500
19
- @response.body = tilt_lang(template, 'haml', Object.new, locals = { :request => @env, :params => @request.params, :exception => excp })
20
-
20
+ @response.body = Tilt.new(template, 1).render(Object.new, locals = locals)
21
21
  log_request('500', excp)
22
22
  end
23
23
  end
data/lib/frank/statik.rb CHANGED
@@ -1,27 +1,29 @@
1
- class Rack::Statik
1
+ module Frank
2
+ class Statik
2
3
 
3
- def initialize(app, options={})
4
- @app = app
5
- frank_root = File.expand_path(File.dirname(__FILE__)) + '/templates'
6
- root = options[:root] || Dir.pwd
7
- @frank_server = Rack::File.new(frank_root)
8
- @static_server = Rack::File.new(root)
9
- end
4
+ def initialize(app, options={})
5
+ @app = app
6
+ frank_root = File.expand_path(File.dirname(__FILE__)) + '/templates'
7
+ root = options[:root] || Dir.pwd
8
+ @frank_server = Rack::File.new(frank_root)
9
+ @static_server = Rack::File.new(root)
10
+ end
10
11
 
11
- # handles serving from __frank__
12
- # looks for static access, if not found,
13
- # passes request to frank
14
- def call(env)
15
- path = env['PATH_INFO']
12
+ # handles serving from __frank__
13
+ # looks for static access, if not found,
14
+ # passes request to frank
15
+ def call(env)
16
+ path = env['PATH_INFO']
16
17
 
17
- if path.include? '__frank__'
18
- env['PATH_INFO'].gsub!('/__frank__', '')
19
- result = @frank_server.call(env)
20
- elsif path.index('/') == 0
21
- result = @static_server.call(env)
18
+ if path.include? '__frank__'
19
+ env['PATH_INFO'].gsub!('/__frank__', '')
20
+ result = @frank_server.call(env)
21
+ elsif path.index('/') == 0
22
+ result = @static_server.call(env)
23
+ end
24
+ return result if result[0] == 200
25
+ @app.call(env)
22
26
  end
23
- return result if result[0] == 200
24
- @app.call(env)
25
- end
26
27
 
28
+ end
27
29
  end
@@ -1,12 +1,18 @@
1
+ require 'frank/lorem'
2
+
1
3
  module Frank
2
4
  module TemplateHelpers
3
- include FrankHelpers
5
+ include FrankHelpers if defined? FrankHelpers
4
6
 
5
7
  def render_partial(path)
6
- pieces = path.split("/")
8
+ pieces = path.split('/')
7
9
  partial = '_' + pieces.pop
8
10
  render_path File.join(pieces.join('/'), partial)
9
11
  end
10
12
 
13
+ def lorem
14
+ Frank::Lorem
15
+ end
16
+
11
17
  end
12
18
  end
@@ -13,4 +13,4 @@
13
13
  #wrapper
14
14
  %img{:src=>'/__frank__/frank-404.png'}
15
15
  %h1= "Not Found&mdash;"
16
- %p= "Try creating <tt>#{request['REQUEST_PATH'][1..-1]}.haml</tt> in the <tt>#{dynamic_folder}</tt> folder."
16
+ %p= "Try creating <tt>#{request['REQUEST_PATH'][1..-1] if request['REQUEST_PATH']}.haml</tt> in the <tt>#{dynamic_folder}</tt> folder."
data/test/helper.rb ADDED
@@ -0,0 +1,29 @@
1
+ testdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift testdir unless $LOAD_PATH.include?(testdir)
3
+
4
+ libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
5
+ $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
6
+
7
+ require 'stringio'
8
+ require 'rubygems'
9
+ require 'yaml'
10
+ require 'test/unit'
11
+ require 'rack/test'
12
+ require 'shoulda'
13
+ require 'template/helpers'
14
+ require 'frank'
15
+
16
+ module Kernel
17
+ def capture_stdout
18
+ out = StringIO.new
19
+ $stdout = out
20
+ yield
21
+ return out
22
+ ensure
23
+ $stdout = STDOUT
24
+ end
25
+ end
26
+
27
+ class Test::Unit::TestCase
28
+ include Rack::Test::Methods
29
+ end
data/test/suite.rb ADDED
@@ -0,0 +1,4 @@
1
+ tests = Dir["#{File.dirname(__FILE__)}/test_*.rb"]
2
+ tests.each do |file|
3
+ require file
4
+ end
@@ -0,0 +1 @@
1
+ %p hello from partial
@@ -0,0 +1 @@
1
+ xml.h1('hello' + ' worlds')
@@ -0,0 +1 @@
1
+ greeting: "Hello CoffeeScript"
@@ -0,0 +1 @@
1
+ <h1><%= 'hello worlds' %></h1>
@@ -0,0 +1 @@
1
+ %h1= hello_helper
@@ -0,0 +1,2 @@
1
+ %h1= 'hello worlds'
2
+ = non_method if defined?(params) && params['brok']
@@ -0,0 +1,2 @@
1
+ #layout
2
+ = yield
@@ -0,0 +1,2 @@
1
+ #layout2
2
+ = yield
@@ -0,0 +1 @@
1
+ %h1 hi inside layout2
@@ -0,0 +1 @@
1
+ %h1 hi inside layout
@@ -0,0 +1 @@
1
+ <h1>hello worlds</h1>
@@ -0,0 +1,4 @@
1
+ %p.words= lorem.words 3
2
+ %p.sentences= lorem.sentences 2
3
+ %p.paragraphs= lorem.paragraphs 1
4
+ %img{:src => lorem.image(400, 300, true)}
@@ -0,0 +1 @@
1
+ # hello worlds
@@ -0,0 +1 @@
1
+ <h1>hello worlds</h1>
@@ -0,0 +1,2 @@
1
+ %h1 hello worlds
2
+ = render_partial('partial')
@@ -0,0 +1 @@
1
+ h1. hello worlds
@@ -0,0 +1,2 @@
1
+ #hello-worlds
2
+ background: red
@@ -0,0 +1,5 @@
1
+ module FrankHelpers
2
+ def hello_helper
3
+ 'hello from helper'
4
+ end
5
+ end
@@ -0,0 +1,67 @@
1
+ # -----------------------------------------------
2
+ # Frank settings:
3
+ #
4
+ # These settings will apply to this project only.
5
+ # If you would like to use this project as a
6
+ # template for new projects, just copy this
7
+ # project folder to `~/.frank` and it will be
8
+ # duplicated for you every time you run the
9
+ # `frank` command.
10
+ #
11
+ # Feel free to trash all these comments, too.
12
+ #
13
+
14
+ env: test
15
+
16
+ # ----------------------
17
+ # Server settings:
18
+ #
19
+ # Change the server host/port to bind rack to.
20
+ # 'server' can be any Rack-supported server, e.g.
21
+ # Mongrel, Thin, WEBrick
22
+ #
23
+ server:
24
+ handler: mongrel
25
+ hostname: localhost
26
+ port: 3601
27
+
28
+
29
+ # ----------------------
30
+ # Static folder:
31
+ #
32
+ # All files in this folder will be served up
33
+ # directly, without interpretation
34
+ #
35
+ static_folder: static
36
+
37
+ # ----------------------
38
+ # Dynamic folder:
39
+ #
40
+ # Frank will try to interpret any of the files
41
+ # in this folder based on their extension
42
+ #
43
+ dynamic_folder: dynamic
44
+
45
+ # ----------------------
46
+ # Templates:
47
+ #
48
+ # 'default' is the optional default template to
49
+ # serve from a folder (include the root folder)
50
+ #
51
+ # 'layouts' is a list of layouts to use, where
52
+ # 'name' is the filename (without extension).
53
+ # You can also use multiple layouts, and limit
54
+ # their scopes like so:
55
+ # - name: blog_layout
56
+ # only: [blog]
57
+ # - name: normal
58
+ # not: [blog, ajax]
59
+ templates:
60
+ extension: haml
61
+ default: index
62
+ layouts:
63
+ - name: layout
64
+ not: [builder, erb, liquid, markdown, mustache, redcloth]
65
+ - name: layout2
66
+ only: [layout2_test]
67
+