rail 0.0.5 → 0.0.6

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: 37044477e117facbe9e5e675ee19e1b8088d5aa6
4
- data.tar.gz: 0588d8fd31eab039d6fc11344a4779a6b068f848
3
+ metadata.gz: 43471296d43318f06e1781bfea739eb39bf8da7f
4
+ data.tar.gz: be098116b23160188c2696295bc7758d8876f1d7
5
5
  SHA512:
6
- metadata.gz: 2a4eda036b542c53e9fdb22a25c13d476beb4cb6fdb370404ac3e5796abf9f90bd418fb32a4d3162d31edc27f335be4ab97dc948327d3679cfcdc96042d7422d
7
- data.tar.gz: dde7176c4d1b6c5bae9b79cc3e39dec81188dbdd0ffe49bc0973f312720282357e0318b762c7893ef45b8920ba951fbfc31606487d5da8dd83ff8bcbc4b4ed68
6
+ metadata.gz: 4f0f8b61cfef6396c5a1cc20cf14b04413eff13161ea2bc347b7131cc2ad036432ce5dab6162e93e48cf87b9721af39b7ecee7147810c00b4b2eacdc97bb84c7
7
+ data.tar.gz: 8143e93f3ec6e07273f04d0ac0854977a67a72373f70bdaa4c2659895b6a3cee2bb933b18079dda6c242855a30e570b11ad6b508df896bafcfe82be61883c323
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.swp
2
- Gemfile.lock
3
- pkg
2
+ .sass-cache
4
3
  .yardoc
4
+ Gemfile.lock
5
5
  doc
6
+ pkg
data/CHANGELOG.md CHANGED
@@ -1,14 +1,19 @@
1
+ ## Rail (develop)
2
+
3
+ * Dropped the dependency on Sprockets.
4
+ * Implemented the rendering of templates inside layouts.
5
+
1
6
  ## Rail 0.0.5 (June 29, 2014)
2
7
 
3
- * Enforced usage of the pipeline when precompiling assets.
8
+ * Enforced the usage of the pipeline when precompiling assets.
4
9
 
5
10
  ## Rail 0.0.4 (June 26, 2014)
6
11
 
7
- * Proper format of README making YARD happy.
12
+ * Changed the format of README to make YARD happy.
8
13
 
9
14
  ## Rail 0.0.3 (June 24, 2014)
10
15
 
11
- * Proper response headers when pipelining assets.
16
+ * Set proper response headers when pipelining assets.
12
17
 
13
18
  ## Rail 0.0.2 (June 21, 2014)
14
19
 
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # Rail [![Gem Version](https://badge.fury.io/rb/rail.svg)](http://badge.fury.io/rb/rail) [![Dependency Status](https://gemnasium.com/IvanUkhov/rail.svg)](https://gemnasium.com/IvanUkhov/rail) [![Build Status](https://travis-ci.org/IvanUkhov/rail.svg?branch=master)](https://travis-ci.org/IvanUkhov/rail)
2
2
 
3
3
  A light framework for front-end development inspired by
4
- [Rails](http://rubyonrails.org/). It is solely based on
5
- [Sprockets](https://github.com/sstephenson/sprockets) and includes the
6
- following components out of the box:
4
+ [Rails](http://rubyonrails.org/). The sole purpose of Rail is to compile
5
+ assets, and it includes the following components:
7
6
 
8
7
  * [CoffeeScript](http://coffeescript.org/) for JavaScript,
9
- * [Haml](http://haml.info/) for HTML,
10
- * [Sass](http://sass-lang.com/) for CSS, and
11
- * [Uglifier](https://github.com/lautis/uglifier) for compression.
8
+ * [Haml](http://haml.info/) for HTML, and
9
+ * [Sass](http://sass-lang.com/) for CSS.
12
10
 
13
11
  ## Installation
14
12
 
@@ -17,7 +15,7 @@ First of all, include the gem in your `Gemfile`. Here is an example:
17
15
  ```ruby
18
16
  source 'https://rubygems.org'
19
17
 
20
- gem 'rail', '~> 0.0.5'
18
+ gem 'rail', '~> 0.0.6'
21
19
 
22
20
  # The rest is optional
23
21
  gem 'redcarpet', '~> 3.1.2' # your favorit complement to Haml
@@ -75,8 +73,13 @@ Organize your code according to the following convention:
75
73
  * `app/helpers` for helper modules, and
76
74
  * `public` for other static content.
77
75
 
78
- In addition, `app/views/layouts/application.html.haml` will be used for
79
- rendering the root of your application (both `/` and `/index.html`).
76
+ The templates in `app/views/layouts` have a special purpose. First,
77
+ `application.html.haml` is used for rendering the root of your application
78
+ (both `/` and `/index.html`). Second, any template in `layouts` is used as
79
+ a layout for the templates in the subfolder of `views` that has the same name
80
+ as the layout. For example, `articles/what-is-the-meaning-of-life.html.haml`
81
+ will be rendered in the context of `layouts/articles.html.haml` provided
82
+ that the latter has a placeholder for the former via the `yield` keyword.
80
83
 
81
84
  ### Configuration
82
85
 
@@ -124,7 +127,7 @@ delete the precompiled files when you change your code in `app`.
124
127
  ### Examples
125
128
 
126
129
  Additional usage examples can be found
127
- [here](https://github.com/IvanUkhov/type-works),
130
+ [here](https://github.com/IvanUkhov/opentype-works),
128
131
  [here](https://github.com/IvanUkhov/photography), and
129
132
  [here](https://github.com/IvanUkhov/liu-profile).
130
133
 
@@ -0,0 +1,12 @@
1
+ module Rail
2
+ class Context
3
+ def initialize(options = {})
4
+ (options[:mixins] || []).each { |mixin| extend(mixin) }
5
+ singleton_class.class_eval do
6
+ (options[:locals] || {}).each do |name, value|
7
+ define_method(name) { value }
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/rail/pipeline.rb CHANGED
@@ -9,58 +9,45 @@ module Rail
9
9
  end
10
10
 
11
11
  def process(request)
12
- Thread.current[:request] = request
12
+ context = Context.new(locals: { request: request }, mixins: helpers)
13
13
 
14
- path = request.path
14
+ asset = rewrite(request.path)
15
+ klass = Processor.find(asset) or raise NotFoundError
16
+ asset = klass.extensify(asset)
17
+ filename = find(asset) or raise NotFoundError
15
18
 
16
- case path
17
- when '', 'index.html'
18
- path = 'layouts/application'
19
- end
19
+ processor = klass.new(self)
20
+ body = processor.compile(filename, context: context)
20
21
 
21
- path = "#{ path }.html" if File.extname(path).empty?
22
+ headers = { 'Content-Type' => klass.mime_type }
22
23
 
23
- sprockets.call('PATH_INFO' => path)
24
+ [ 200, headers, Array(body) ]
25
+ rescue NotFoundError
26
+ [ 404, {}, [] ]
24
27
  end
25
28
 
26
- private
27
-
28
- def sprockets
29
- @sprockets ||= build_sprockets
30
- end
31
-
32
- def build_sprockets
33
- environment = Sprockets::Environment.new
34
-
35
- paths.each do |directory|
36
- environment.append_path(directory)
29
+ def find(asset)
30
+ paths.each do |path|
31
+ filename = File.join(path, asset)
32
+ return filename if File.exist?(filename)
37
33
  end
34
+ nil
35
+ end
38
36
 
39
- if compress?
40
- environment.js_compressor = :uglify
41
- environment.css_compressor = :scss
42
- end
43
-
44
- # TODO: Find a per-instance way to configure HAML.
45
- Haml::Options.defaults[:ugly] = compress?
46
-
47
- helpers.each do |helper|
48
- environment.context_class.class_eval do
49
- include helper
50
- end
51
- end
37
+ private
52
38
 
53
- environment.context_class.class_eval do
54
- define_method(:request) do
55
- Thread.current[:request]
56
- end
39
+ def rewrite(path)
40
+ if [ '', 'index.html' ].include?(path)
41
+ 'layouts/application.html'
42
+ elsif File.extname(path).empty?
43
+ "#{ path }.html"
44
+ else
45
+ path
57
46
  end
58
-
59
- environment
60
47
  end
61
48
 
62
49
  def paths
63
- (application_paths + gems.map { |name| gem_paths(name) }).flatten
50
+ @paths ||= (application_paths + gems.map { |gem| gem_paths(gem) }).flatten
64
51
  end
65
52
 
66
53
  def application_paths
@@ -0,0 +1,22 @@
1
+ module Rail
2
+ module Processor
3
+ class Base
4
+ extend Forwardable
5
+
6
+ def self.capable?(extension)
7
+ Array(output_extension).include?(extension)
8
+ end
9
+
10
+ def self.extensify(filename)
11
+ "#{ filename }.#{ input_extension }"
12
+ end
13
+
14
+ attr_reader :pipeline
15
+ def_delegator :pipeline, :compress?
16
+
17
+ def initialize(pipeline)
18
+ @pipeline = pipeline
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+ module Rail
2
+ module Processor
3
+ class CoffeeScript < Base
4
+ def self.input_extension
5
+ 'coffee'
6
+ end
7
+
8
+ def self.output_extension
9
+ 'js'
10
+ end
11
+
12
+ def self.mime_type
13
+ 'application/javascript'
14
+ end
15
+
16
+ def compile(filename, options = {})
17
+ code = process(filename, options)
18
+ code = Uglifier.new.compile(code) if compress?
19
+ code
20
+ end
21
+
22
+ private
23
+
24
+ def process(filename, options = {})
25
+ output = []
26
+
27
+ code = File.read(filename)
28
+
29
+ extract_requirements(code).each do |name|
30
+ requirement_filename = find_requirement(name, filename)
31
+ raise NotFoundError unless requirement_filename
32
+ output << compile(requirement_filename, options)
33
+ end
34
+
35
+ output << ::CoffeeScript.compile(code, options)
36
+
37
+ output.join
38
+ end
39
+
40
+ def find_requirement(name, referrer)
41
+ assets = [ name, "#{ name }.coffee", "#{ name }.js.coffee" ]
42
+
43
+ if name =~ /^\.\// # relative?
44
+ path = File.dirname(referrer)
45
+ assets.each do |asset|
46
+ filename = File.join(path, asset)
47
+ return filename if File.exist?(filename)
48
+ end
49
+ else
50
+ assets.each do |asset|
51
+ filename = pipeline.find(asset)
52
+ return filename if filename
53
+ end
54
+ end
55
+
56
+ nil
57
+ end
58
+
59
+ def extract_requirements(code)
60
+ match = /\A(?:\s*(?:\#.*\n?)+)+/.match(code) or return []
61
+ match[0].split(/\n/).map(&:strip).reject(&:empty?).map do |line|
62
+ match = /^\s*\#\s*=\s*require\s+(.*)$/.match(line)
63
+ match ? match[1].strip.gsub(/(^['"])|(['"]$)/, '') : nil
64
+ end.compact
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,50 @@
1
+ module Rail
2
+ module Processor
3
+ class Haml < Base
4
+ def self.input_extension
5
+ 'haml'
6
+ end
7
+
8
+ def self.output_extension
9
+ 'html'
10
+ end
11
+
12
+ def self.mime_type
13
+ 'text/html'
14
+ end
15
+
16
+ def compile(filename, options = {}, &block)
17
+ options = {
18
+ filename: filename,
19
+ line: 1,
20
+ ugly: compress?
21
+ }.merge(options)
22
+
23
+ engine = ::Haml::Engine.new(File.read(filename), options)
24
+
25
+ layout_filename = find_layout(filename)
26
+
27
+ if layout_filename
28
+ compile(layout_filename, options) do
29
+ engine.render(options[:context], {}, &block)
30
+ end
31
+ else
32
+ engine.render(options[:context], {}, &block)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def find_layout(filename)
39
+ asset = "layouts/#{ filename.split('/')[-2] }"
40
+
41
+ [ "#{ asset }.haml", "#{ asset }.html.haml" ].each do |asset|
42
+ filename = pipeline.find(asset)
43
+ return filename if filename
44
+ end
45
+
46
+ nil
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ module Rail
2
+ module Processor
3
+ class Sass < Base
4
+ def self.input_extension
5
+ 'scss'
6
+ end
7
+
8
+ def self.output_extension
9
+ 'css'
10
+ end
11
+
12
+ def self.mime_type
13
+ 'text/css'
14
+ end
15
+
16
+ def compile(filename, options = {})
17
+ options = {
18
+ filename: filename,
19
+ line: 1,
20
+ syntax: :scss,
21
+ style: compress? ? :compressed : :nested
22
+ }.merge(options)
23
+
24
+ engine = ::Sass::Engine.new(File.read(filename), options)
25
+ engine.render
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'processor/base'
2
+ require_relative 'processor/coffee_script'
3
+ require_relative 'processor/haml'
4
+ require_relative 'processor/sass'
5
+
6
+ module Rail
7
+ module Processor
8
+ def self.processors
9
+ @processors ||= Processor.constants.map do |name|
10
+ object = Processor.const_get(name)
11
+ object.is_a?(Class) && object < Base ? object : nil
12
+ end.compact
13
+ end
14
+
15
+ def self.find(filename)
16
+ extension = File.extname(filename).slice(1..-1)
17
+ processors.find { |processor| processor.capable?(extension) }
18
+ end
19
+ end
20
+ end
data/lib/rail/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rail
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/rail.rb CHANGED
@@ -2,21 +2,26 @@ require 'ostruct'
2
2
  require 'forwardable'
3
3
 
4
4
  require 'rack'
5
+
6
+ require 'coffee-script'
5
7
  require 'haml'
8
+ require 'sass'
9
+
6
10
  require 'uglifier'
7
- require 'sprockets'
8
11
 
9
12
  require_relative 'rail/application'
10
13
  require_relative 'rail/browser'
14
+ require_relative 'rail/context'
11
15
  require_relative 'rail/pipeline'
16
+ require_relative 'rail/processor'
12
17
  require_relative 'rail/request'
13
18
  require_relative 'rail/server'
14
19
  require_relative 'rail/support'
15
20
  require_relative 'rail/version'
16
21
 
17
- Sprockets.register_engine('.haml', Tilt::HamlTemplate)
18
-
19
22
  module Rail
23
+ NotFoundError = Class.new(StandardError)
24
+
20
25
  def self.env
21
26
  @env ||= build_env
22
27
  end
data/rail.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency 'rake'
26
26
 
27
- spec.add_dependency 'sprockets', '~> 2.12'
27
+ spec.add_dependency 'rack', '~> 1.5'
28
28
 
29
29
  spec.add_dependency 'coffee-script', '~> 2.2'
30
30
  spec.add_dependency 'haml', '~> 4.0'
data/spec/coffee_spec.rb CHANGED
@@ -10,6 +10,17 @@ describe Rail::Application do
10
10
  end
11
11
  body = controller.process('/application.js')
12
12
  assert_equal body.strip, <<-BODY.strip
13
+ (function() {
14
+ window.Parser = (function() {
15
+ function Parser(format) {
16
+ this.format = format;
17
+ }
18
+
19
+ return Parser;
20
+
21
+ })();
22
+
23
+ }).call(this);
13
24
  (function() {
14
25
  window.Font = (function() {
15
26
  function Font(name) {
@@ -36,7 +47,7 @@ describe Rail::Application do
36
47
  end
37
48
  body = controller.process('/application.js')
38
49
  assert_equal body.strip, <<-BODY.strip
39
- (function(){window.Font=function(){function n(n){this.name=n}return n}()}).call(this),function(){var n;n=new Font(\"Benton Modern Display\")}.call(this);
50
+ (function(){window.Parser=function(){function n(n){this.format=n}return n}()}).call(this),function(){window.Font=function(){function n(n){this.name=n}return n}()}.call(this),function(){var n;n=new Font(\"Benton Modern Display\")}.call(this);
40
51
  BODY
41
52
  end
42
53
  end
data/spec/haml_spec.rb CHANGED
@@ -36,6 +36,24 @@ describe Rail::Application do
36
36
  <body>
37
37
  <h1>Hello</h1>
38
38
  </body>
39
+ </html>
40
+ BODY
41
+ end
42
+
43
+ it 'handles layouts' do
44
+ controller = Controller.new do
45
+ config.compress = false
46
+ end
47
+ body = controller.process('/articles/about')
48
+ assert_equal body.strip, <<-BODY.strip
49
+ <!DOCTYPE html>
50
+ <html>
51
+ <head>
52
+ <title>Hello</title>
53
+ </head>
54
+ <body>
55
+ <h1>About</h1>
56
+ </body>
39
57
  </html>
40
58
  BODY
41
59
  end
@@ -1,2 +1,4 @@
1
+ #= require "./parser.js"
2
+
1
3
  class window.Font
2
4
  constructor: (@name) ->
@@ -0,0 +1,2 @@
1
+ class window.Parser
2
+ constructor: (@format) ->
@@ -0,0 +1,5 @@
1
+ module ApplicationHelper
2
+ def title
3
+ 'Hello'
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ %h1 About
@@ -1,6 +1,6 @@
1
1
  !!! 5
2
2
  %html
3
3
  %head
4
- %title Hello
4
+ %title= title
5
5
  %body
6
- %h1 Hello
6
+ %h1= request.host || title
@@ -0,0 +1,6 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title= title
5
+ %body
6
+ = yield
@@ -8,6 +8,6 @@ class Controller
8
8
 
9
9
  def process(path)
10
10
  _, _, body = @application.call('PATH_INFO' => path)
11
- body.to_s
11
+ body.join.to_s
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Ukhov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-29 00:00:00.000000000 Z
11
+ date: 2014-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: sprockets
28
+ name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.12'
33
+ version: '1.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.12'
40
+ version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: coffee-script
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +127,13 @@ files:
127
127
  - lib/rail.rb
128
128
  - lib/rail/application.rb
129
129
  - lib/rail/browser.rb
130
+ - lib/rail/context.rb
130
131
  - lib/rail/pipeline.rb
132
+ - lib/rail/processor.rb
133
+ - lib/rail/processor/base.rb
134
+ - lib/rail/processor/coffee_script.rb
135
+ - lib/rail/processor/haml.rb
136
+ - lib/rail/processor/sass.rb
131
137
  - lib/rail/request.rb
132
138
  - lib/rail/server.rb
133
139
  - lib/rail/support.rb
@@ -139,9 +145,13 @@ files:
139
145
  - spec/haml_spec.rb
140
146
  - spec/project/app/assets/javascripts/application.js.coffee
141
147
  - spec/project/app/assets/javascripts/font.coffee
148
+ - spec/project/app/assets/javascripts/parser.js.coffee
142
149
  - spec/project/app/assets/stylesheets/_reset.scss
143
150
  - spec/project/app/assets/stylesheets/application.css.scss
151
+ - spec/project/app/helpers/application_helper.rb
152
+ - spec/project/app/views/articles/about.html.haml
144
153
  - spec/project/app/views/layouts/application.html.haml
154
+ - spec/project/app/views/layouts/articles.html.haml
145
155
  - spec/project/config/application.rb
146
156
  - spec/project/controller.rb
147
157
  - spec/sass_spec.rb
@@ -174,9 +184,13 @@ test_files:
174
184
  - spec/haml_spec.rb
175
185
  - spec/project/app/assets/javascripts/application.js.coffee
176
186
  - spec/project/app/assets/javascripts/font.coffee
187
+ - spec/project/app/assets/javascripts/parser.js.coffee
177
188
  - spec/project/app/assets/stylesheets/_reset.scss
178
189
  - spec/project/app/assets/stylesheets/application.css.scss
190
+ - spec/project/app/helpers/application_helper.rb
191
+ - spec/project/app/views/articles/about.html.haml
179
192
  - spec/project/app/views/layouts/application.html.haml
193
+ - spec/project/app/views/layouts/articles.html.haml
180
194
  - spec/project/config/application.rb
181
195
  - spec/project/controller.rb
182
196
  - spec/sass_spec.rb