scorched 0.5 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7468f10cbee0373d243fd4d66dd081ea4b1cecc9
4
- data.tar.gz: 6225d5221e70a5ba5f3b68d8c6db0144f34d9dfc
3
+ metadata.gz: dc95df5b8180579cc08c6d839b56dc64ad9105b1
4
+ data.tar.gz: 0a445e9f72ee7aaf30c7f0aa8a9cc93ec5c919ee
5
5
  SHA512:
6
- metadata.gz: 91385d8f1501c564b9ba510ab3d4faef763ea4d6cee6d79b2a23c74cf8511352c8b0c7443360031e8b4ae3149c33c216c4b4b7311eac03d3bee9ce348d075b81
7
- data.tar.gz: e0d15fc7205e937a8249599833bf9b2a74c9e3abaa3db4decef548eb6292185b53d3da0eede09439efdf5b4deb205b9563d256ed4a93365c3b31270c8db6f5e1
6
+ metadata.gz: 2a46ef33d42014a33f3d0abc9d0009714f088caeaaba24633e72c1d25ad033838b5a693c53bfdf5dbaf9b1ae6c0dd714d5d8f52c17e0dcceadc9773dad558ac9
7
+ data.tar.gz: 2446404ea7aa8a28d140921d66142fd292f51b492fabb7029f7a3d632ba97a1707425589b11ecf46b58b1e35563f2f7d6e530d88ae26ca04858d24bba7890033
data/Gemfile CHANGED
File without changes
data/LICENSE CHANGED
File without changes
@@ -3,6 +3,9 @@ Milestones
3
3
 
4
4
  Changelog
5
5
  ---------
6
+ ### v0.5.1
7
+ * Added URL helpers, #absolute and #url
8
+ * Render helper now loads files itself as Tilt still has issues with UTF-8 files.
6
9
 
7
10
  ### v0.5
8
11
  * Implemented view rendering using Tilt.
data/README.md CHANGED
@@ -21,7 +21,14 @@ Design Philosophy
21
21
  -----------------
22
22
  Scorched has a relatively simple design philosophy. The main objective is to keep Scorched lean and generic. Scorched refrains from expressing too much opinion. The general idea behind Scorched is to give developers all the tools to quickly put together small, medium and perhaps even large websites and applications.
23
23
 
24
- There's little need for a framework to be opinionated if the opinions of the developer can be quickly and easily built into it on a per-application basis. To do this effectively, developers really need to understand Scorched, and the best way to lower facilitate that is to lower the learning curve by keeping the core design, logical, predictable, and concise.
24
+ There's little need for a framework to be opinionated if the opinions of the developer can be quickly and easily built into it on a per-application basis. To do this effectively, developers really need to understand Scorched, and the best way to lower facilitate that is to lower the learning curve by keeping the core design, logical, predictable, and concise.
25
+
26
+
27
+ Magicians Not Welcome
28
+ ---------------------
29
+ Scorched aims to be raw and transparent. Magic has no place, or need, in the world of Scorched. A thoughtful and simple design means there's no requirement for magic. Because of that, most developers should be able to master scorched in an evening, if that.
30
+
31
+ Part of what keeps Scorched lightweight, is that unlike other lightweight web frameworks that attempt to hide Rack in the background, Scorched makes no such attempts, very rarely providing functionality that overlaps with that already provided by Rack. In fact, familiarity is somewhat of a pre-requisite to mastering Scorched.
25
32
 
26
33
 
27
34
  First Impressions
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -11,7 +11,6 @@ require_relative 'scorched/static'
11
11
  require_relative 'scorched/dynamic_delegate'
12
12
  require_relative 'scorched/options'
13
13
  require_relative 'scorched/collection'
14
- require_relative 'scorched/view_helpers'
15
14
  require_relative 'scorched/controller'
16
15
  require_relative 'scorched/error'
17
16
  require_relative 'scorched/request'
File without changes
@@ -1,6 +1,5 @@
1
1
  module Scorched
2
2
  class Controller
3
- include ViewHelpers
4
3
  include Scorched::Options('config')
5
4
  include Scorched::Options('view_config')
6
5
  include Scorched::Options('conditions')
@@ -52,7 +51,7 @@ module Scorched
52
51
  use Rack::Head
53
52
  use Rack::MethodOverride
54
53
  use Rack::Accept
55
- use Scorched::Static, :dir => this.config[:static_dir] if this.config[:static_dir]
54
+ use Scorched::Static, this.config[:static_dir] if this.config[:static_dir]
56
55
  use Rack::Logger, this.config[:logger] if this.config[:logger]
57
56
  }
58
57
 
@@ -328,6 +327,68 @@ module Scorched
328
327
  end
329
328
  end
330
329
 
330
+ # Renders the given string or file path using the Tilt templating library.
331
+ # Options hash is merged with the controllers _view_config_. Tilt template options are passed through.
332
+ # The template engine is derived from file name, or otherwise as specified by the _:engine_ option. If String is
333
+ # given, _:engine_ option must be set.
334
+ #
335
+ # Refer to Tilt documentation for a list of valid template engines.
336
+ def render(string_or_file, options = {}, &block)
337
+ options = view_config.merge(explicit_options = options)
338
+ engine = (derived_engine = Tilt[string_or_file.to_s]) || Tilt[options[:engine]]
339
+ raise Error, "Invalid or undefined template engine: #{options[:engine].inspect}" unless engine
340
+ if Symbol === string_or_file
341
+ file = string_or_file.to_s
342
+ file = file << ".#{options[:engine]}" unless derived_engine
343
+ file = File.join(options[:dir], file) if options[:dir]
344
+ # Tilt still has unresolved file encoding issues. Until that's fixed, we read the file manually.
345
+ template = engine.new(nil, nil, options) { File.read(file) }
346
+ else
347
+ template = engine.new(nil, nil, options) { string_or_file }
348
+ end
349
+
350
+ # The following chunk of code is responsible for preventing the rendering of layouts within views.
351
+ options[:layout] = false if @_no_default_layout && !explicit_options[:layout]
352
+ begin
353
+ @_no_default_layout = true
354
+ output = template.render(self, options[:locals], &block)
355
+ ensure
356
+ @_no_default_layout = false
357
+ end
358
+ output = render(options[:layout], options.merge(layout: false)) { output } if options[:layout]
359
+ output
360
+ end
361
+
362
+ # Takes an optional URL, relative to the applications root, and returns a fully qualified URL.
363
+ # Example: url('/example?show=30') #=> https://localhost:9292/myapp/example?show=30
364
+ def url(path = nil)
365
+ return path if path && URI.parse(path).scheme
366
+ uri = URI::Generic.build(
367
+ scheme: env['rack.url_scheme'],
368
+ host: env['SERVER_NAME'],
369
+ port: env['SERVER_PORT'].to_i,
370
+ path: env['SCRIPT_NAME']
371
+ )
372
+ if path
373
+ path[0,0] = '/' unless path[0] == '/'
374
+ uri.to_s.chomp('/') << path
375
+ else
376
+ uri.to_s
377
+ end
378
+
379
+ end
380
+
381
+ # Takes an optional path, relative to the applications root URL, and returns an absolute path.
382
+ # Example: absolute('/style.css') #=> /myapp/style.css
383
+ def absolute(path = nil)
384
+ return path if path && URI.parse(path).scheme
385
+ if path
386
+ [request.script_name, path].join('/').gsub(%r{/+}, '/')
387
+ else
388
+ request.script_name
389
+ end
390
+ end
391
+
331
392
  private
332
393
 
333
394
  def run_filters(type)
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,14 +1,12 @@
1
1
  module Scorched
2
2
  class Static
3
- def initialize(app, options={})
3
+ def initialize(app, dir = 'public')
4
4
  @app = app
5
- @options = options
6
- dir = options.delete(:dir) || 'public'
7
- options[:cache_control] ||= 'no-cache'
8
- @file_server = Rack::File.new(dir, options)
5
+ @file_server = Rack::File.new(dir)
9
6
  end
10
7
 
11
8
  def call(env)
9
+ @file_server.call(env)
12
10
  response = @file_server.call(env)
13
11
  response[0] >= 400 ? @app.call(env) : response
14
12
  end
@@ -1,3 +1,3 @@
1
1
  module Scorched
2
- VERSION = '0.5'
2
+ VERSION = '0.5.1'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
- require 'scorched/version' # Load scorched to inspect it for information, such as version.
2
+ require 'scorched/version'
3
3
 
4
4
  Gem::Specification.new 'scorched', Scorched::VERSION do |s|
5
5
  s.summary = "Light-weight, DRY as a desert, web framework for Ruby"
File without changes
@@ -560,6 +560,135 @@ module Scorched
560
560
  end
561
561
  end
562
562
 
563
+ describe "rendering" do
564
+ before(:each) do
565
+ app.view_config.each { |k,v| app.view_config[k] = nil }
566
+ end
567
+
568
+ it "can render a file, relative to the application root" do
569
+ app.get('/') do
570
+ render(:'views/main.erb').should == "3 for me"
571
+ end
572
+ rt.get('/')
573
+ end
574
+
575
+ it "can render a string" do
576
+ app.get('/') do
577
+ render('<%= 1 + 1 %> for you', engine: :erb).should == "2 for you"
578
+ end
579
+ rt.get('/')
580
+ end
581
+
582
+ it "takes an optional view directory, relative to the application root" do
583
+ app.get('/') do
584
+ render(:'main.erb', dir: 'views').should == "3 for me"
585
+ end
586
+ rt.get('/')
587
+ end
588
+
589
+ it "takes an optional block to be yielded by the view" do
590
+ app.get('/') do
591
+ render(:'views/layout.erb'){ "in the middle" }.should == "(in the middle)"
592
+ end
593
+ rt.get('/')
594
+ end
595
+
596
+ it "renders the given layout" do
597
+ app.get('/') do
598
+ render(:'views/main.erb', layout: :'views/layout.erb').should == "(3 for me)"
599
+ end
600
+ rt.get('/')
601
+ end
602
+
603
+ it "merges options with view config" do
604
+ app.get('/') do
605
+ render(:'main.erb').should == "3 for me"
606
+ end
607
+ app.get('/full_path') do
608
+ render(:'views/main.erb', {layout: :'views/layout.erb', dir: nil}).should == "(3 for me)"
609
+ end
610
+ app.view_config[:dir] = 'views'
611
+ rt.get('/')
612
+ rt.get('/full_path')
613
+ end
614
+
615
+ it "derived template engine overrides specified engine" do
616
+ app.view_config[:dir] = 'views'
617
+ app.view_config[:engine] = :erb
618
+ app.get('/str') do
619
+ render(:'other.str').should == "hello hello"
620
+ end
621
+ app.get('/erb_file') do
622
+ render(:main).should == "3 for me"
623
+ end
624
+ app.get('/erb_string') do
625
+ render('<%= 1 + 1 %> for you').should == "2 for you"
626
+ end
627
+ rt.get('/str')
628
+ rt.get('/erb_file')
629
+ rt.get('/erb_string')
630
+ end
631
+
632
+ it "ignores default layout when called within a view" do
633
+ app.view_config << {:dir => 'views', :layout => :layout, :engine => :erb}
634
+ app.get('/') do
635
+ render :composer
636
+ end
637
+ rt.get('/').body.should == '({1 for none})'
638
+ end
639
+ end
640
+
641
+ describe "url helpers" do
642
+ let(:myapp) do
643
+ Class.new(Scorched::Controller)
644
+ end
645
+
646
+ let(:app) do
647
+ the_app = myapp
648
+ builder = Rack::Builder.new
649
+ builder.map('/myapp') { run the_app }
650
+ builder.to_app
651
+ end
652
+
653
+ describe "url" do
654
+ it "returns the fully qualified URL" do
655
+ myapp.get('/') { url }
656
+ rt.get('https://scorchedrb.com:73/myapp?something=true').body.should ==
657
+ 'https://scorchedrb.com:73/myapp'
658
+ end
659
+
660
+ it "can append an optional path" do
661
+ myapp.get('/') { url('hello') }
662
+ rt.get('https://scorchedrb.com:73/myapp?something=true').body.should ==
663
+ 'https://scorchedrb.com:73/myapp/hello'
664
+ end
665
+
666
+ it "returns the given URL if scheme detected" do
667
+ test_url = 'http://google.com/blah'
668
+ myapp.get('/') { url(test_url) }
669
+ rt.get('/myapp').body.should == test_url
670
+ end
671
+ end
672
+
673
+ describe "absolute" do
674
+ it "returns an absolute URL path" do
675
+ myapp.get('/absolute') { absolute }
676
+ rt.get('http://scorchedrb.com/myapp/absolute?something=true').body.should == '/myapp'
677
+ end
678
+
679
+ it "can append an optional path" do
680
+ myapp.get('/absolute') { absolute('hello') }
681
+ rt.get('http://scorchedrb.com/myapp/absolute?something=true').body.should == '/myapp/hello'
682
+ end
683
+
684
+ it "returns the given URL if scheme detected" do
685
+ test_url = 'http://google.com/blah'
686
+ myapp.get('/') { absolute(test_url) }
687
+ rt.get('/myapp').body.should == test_url
688
+ end
689
+ end
690
+ end
691
+
563
692
  end
564
693
  end
565
694
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scorched
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.5'
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Wardrop
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-03 00:00:00.000000000 Z
11
+ date: 2013-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -107,7 +107,6 @@ files:
107
107
  - lib/scorched/response.rb
108
108
  - lib/scorched/static.rb
109
109
  - lib/scorched/version.rb
110
- - lib/scorched/view_helpers.rb
111
110
  - scorched.gemspec
112
111
  - spec/collection_spec.rb
113
112
  - spec/controller_spec.rb
@@ -115,7 +114,6 @@ files:
115
114
  - spec/options_spec.rb
116
115
  - spec/public/static.txt
117
116
  - spec/request_spec.rb
118
- - spec/view_helpers_spec.rb
119
117
  - spec/views/composer.erb
120
118
  - spec/views/layout.erb
121
119
  - spec/views/main.erb
@@ -154,4 +152,3 @@ test_files:
154
152
  - spec/controller_spec.rb
155
153
  - spec/options_spec.rb
156
154
  - spec/request_spec.rb
157
- - spec/view_helpers_spec.rb
@@ -1,39 +0,0 @@
1
- # In its own file for no other reason than to keep all the extra non-essential bells and whistles in their own file,
2
- # which can be easily excluded if needed.
3
-
4
- module Scorched
5
- module ViewHelpers
6
-
7
- # Renders the given string or file path using the Tilt templating library.
8
- # Options hash is merged with the controllers _view_config_. Tilt template options are passed through.
9
- # The template engine is derived from file name, or otherwise as specified by the _:engine_ option. If String is
10
- # given, _:engine_ option must be set.
11
- #
12
- # Refer to Tilt documentation for a list of valid template engines.
13
- def render(string_or_file, options = {}, &block)
14
- options = view_config.merge(explicit_options = options)
15
- engine = (derived_engine = Tilt[string_or_file.to_s]) || Tilt[options[:engine]]
16
- raise Error, "Invalid or undefined template engine: #{options[:engine].inspect}" unless engine
17
- if Symbol === string_or_file
18
- file = string_or_file.to_s
19
- file = file << ".#{options[:engine]}" unless derived_engine
20
- file = File.join(options[:dir], file) if options[:dir]
21
- template = engine.new(file, nil, options)
22
- else
23
- template = engine.new(nil, nil, options) { string_or_file }
24
- end
25
-
26
- # The following chunk of code is responsible for preventing the rendering of layouts within views.
27
- options[:layout] = false if @_no_default_layout && !explicit_options[:layout]
28
- begin
29
- @_no_default_layout = true
30
- output = template.render(self, options[:locals], &block)
31
- ensure
32
- @_no_default_layout = false
33
- end
34
- output = render(options[:layout], options.merge(layout: false)) { output } if options[:layout]
35
- output
36
- end
37
-
38
- end
39
- end
@@ -1,84 +0,0 @@
1
- require_relative './helper.rb'
2
-
3
- module Scorched
4
- describe ViewHelpers do
5
- describe "rendering" do
6
- before(:each) do
7
- app.view_config.each { |k,v| app.view_config[k] = nil }
8
- end
9
-
10
- it "can render a file, relative to the application root" do
11
- app.get('/') do
12
- render(:'views/main.erb').should == "3 for me"
13
- end
14
- rt.get('/')
15
- end
16
-
17
- it "can render a string" do
18
- app.get('/') do
19
- render('<%= 1 + 1 %> for you', engine: :erb).should == "2 for you"
20
- end
21
- rt.get('/')
22
- end
23
-
24
- it "takes an optional view directory, relative to the application root" do
25
- app.get('/') do
26
- render(:'main.erb', dir: 'views').should == "3 for me"
27
- end
28
- rt.get('/')
29
- end
30
-
31
- it "takes an optional block to be yielded by the view" do
32
- app.get('/') do
33
- render(:'views/layout.erb'){ "in the middle" }.should == "(in the middle)"
34
- end
35
- rt.get('/')
36
- end
37
-
38
- it "renders the given layout" do
39
- app.get('/') do
40
- render(:'views/main.erb', layout: :'views/layout.erb').should == "(3 for me)"
41
- end
42
- rt.get('/')
43
- end
44
-
45
- it "merges options with view config" do
46
- app.get('/') do
47
- render(:'main.erb').should == "3 for me"
48
- end
49
- app.get('/full_path') do
50
- render(:'views/main.erb', {layout: :'views/layout.erb', dir: nil}).should == "(3 for me)"
51
- end
52
- app.view_config[:dir] = 'views'
53
- rt.get('/')
54
- rt.get('/full_path')
55
- end
56
-
57
- it "derived template engine overrides specified engine" do
58
- app.view_config[:dir] = 'views'
59
- app.view_config[:engine] = :erb
60
- app.get('/str') do
61
- render(:'other.str').should == "hello hello"
62
- end
63
- app.get('/erb_file') do
64
- render(:main).should == "3 for me"
65
- end
66
- app.get('/erb_string') do
67
- render('<%= 1 + 1 %> for you').should == "2 for you"
68
- end
69
- rt.get('/str')
70
- rt.get('/erb_file')
71
- rt.get('/erb_string')
72
- end
73
-
74
- it "ignores default layout when called within a view" do
75
- app.view_config << {:dir => 'views', :layout => :layout, :engine => :erb}
76
- app.get('/') do
77
- render :composer
78
- end
79
- rt.get('/').body.should == '({1 for none})'
80
- end
81
-
82
- end
83
- end
84
- end