render_me_pretty 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +50 -0
- data/README.md +64 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/render_me_pretty/version.rb +3 -0
- data/lib/render_me_pretty.rb +145 -0
- data/render_me_pretty.gemspec +27 -0
- data/tilt_examples.rb +18 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bdea15bc599691050a16495af35770790dd186481e8156f500cef67569bd11a3
|
4
|
+
data.tar.gz: e2019115f4e08b8de0779017621ebe3f7175866091a04a35575d3a51e88f1c32
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 655f3e4be15080b24946f7e373e653ac56adc2abd2423f087e3dbb7a876f7dbc8103c29d4143b1c1617ffc7166ee92ee13dc07443482ce6ab65014f1fc1b44c5
|
7
|
+
data.tar.gz: 486e06149bb49c56ac8381bc55543eb42297d13c521bf1e7e1f32650f135093705f208be715e14f592b81da5395f8c1435a213fe3070016a843b2f0da037541f
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
render_me_pretty (0.1.0)
|
5
|
+
activesupport
|
6
|
+
colorize
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (5.1.4)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (~> 0.7)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
colorize (0.8.1)
|
17
|
+
concurrent-ruby (1.0.5)
|
18
|
+
diff-lcs (1.3)
|
19
|
+
i18n (0.9.4)
|
20
|
+
concurrent-ruby (~> 1.0)
|
21
|
+
minitest (5.11.3)
|
22
|
+
rake (12.3.0)
|
23
|
+
rspec (3.7.0)
|
24
|
+
rspec-core (~> 3.7.0)
|
25
|
+
rspec-expectations (~> 3.7.0)
|
26
|
+
rspec-mocks (~> 3.7.0)
|
27
|
+
rspec-core (3.7.1)
|
28
|
+
rspec-support (~> 3.7.0)
|
29
|
+
rspec-expectations (3.7.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.7.0)
|
32
|
+
rspec-mocks (3.7.0)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.7.0)
|
35
|
+
rspec-support (3.7.1)
|
36
|
+
thread_safe (0.3.6)
|
37
|
+
tzinfo (1.2.5)
|
38
|
+
thread_safe (~> 0.1)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
bundler
|
45
|
+
rake
|
46
|
+
render_me_pretty!
|
47
|
+
rspec
|
48
|
+
|
49
|
+
BUNDLED WITH
|
50
|
+
1.16.1
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Render Me Pretty
|
2
|
+
|
3
|
+
Let's say you have an error in your ERB template:
|
4
|
+
|
5
|
+
```
|
6
|
+
line 1
|
7
|
+
<%= sdsd %>
|
8
|
+
line 3
|
9
|
+
```
|
10
|
+
|
11
|
+
Normally, when render it with ERB you get an error message that looks something like this:
|
12
|
+
|
13
|
+
```sh
|
14
|
+
NameError:
|
15
|
+
undefined local variable or method `sdsd' for #<RenderMePretty::Context:0x00007fcda414d358>
|
16
|
+
(erb):2:in `get_binding'
|
17
|
+
./lib/render_me_pretty.rb:71:in `render'
|
18
|
+
./spec/lib/render_me_pretty/erb_spec.rb:41:in `block (3 levels) in <top (required)>'
|
19
|
+
```
|
20
|
+
|
21
|
+
Instead, this library produces an output with an error pointing out the original line in the ERB template like so:
|
22
|
+
|
23
|
+
```
|
24
|
+
NameError evaluating ERB template on line 2 of: spec/fixtures/invalid.erb
|
25
|
+
1 line 1
|
26
|
+
2 <%= sdsd %>
|
27
|
+
3 line 3
|
28
|
+
```
|
29
|
+
|
30
|
+
The output also colorizes the error line in red so it stands out.
|
31
|
+
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Here's a simple example:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
erb = RenderMePretty::Erb.new("/path/to/tempate.erb", a: 3) }
|
39
|
+
erb.render(a: 4)
|
40
|
+
```
|
41
|
+
|
42
|
+
A few more examples are in the [erb_spec.rb](spec/lib/erb_spec.rb)
|
43
|
+
|
44
|
+
## Installation
|
45
|
+
|
46
|
+
Add this line to your application's Gemfile:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
gem 'render_me_pretty'
|
50
|
+
```
|
51
|
+
|
52
|
+
And then execute:
|
53
|
+
|
54
|
+
$ bundle
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
Please fork the project and open a pull request! I'd love your pull requests. Contributions are encouraged and welcomed!
|
59
|
+
|
60
|
+
1. Fork it
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "render_me_pretty"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require "render_me_pretty/version"
|
2
|
+
require "active_support/core_ext/string"
|
3
|
+
require "colorize"
|
4
|
+
|
5
|
+
=begin
|
6
|
+
## Usage examples:
|
7
|
+
|
8
|
+
Given an example template /path/to/template.erb that contains:
|
9
|
+
|
10
|
+
a: <%= @a %>
|
11
|
+
|
12
|
+
### Variables at initialization
|
13
|
+
|
14
|
+
erb = RenderMePretty::Erb.new("/path/to/template.erb", a: 1)
|
15
|
+
erb.render
|
16
|
+
|
17
|
+
Result: a: 1
|
18
|
+
|
19
|
+
### Variables at render time
|
20
|
+
|
21
|
+
erb = RenderMePretty::Erb.new("/path/to/template.erb")
|
22
|
+
erb.render(a: 2)
|
23
|
+
|
24
|
+
Result: a: 2
|
25
|
+
|
26
|
+
### Variables at both initialization and render time:
|
27
|
+
|
28
|
+
erb = RenderMePretty::Erb.new("/path/to/template.erb", a: 3)
|
29
|
+
erb.render(a: "override", a: 4)
|
30
|
+
|
31
|
+
Result: a: 4
|
32
|
+
|
33
|
+
Variables at render time will override variables at initialization time.
|
34
|
+
|
35
|
+
## Context Helpers
|
36
|
+
|
37
|
+
When no context is provided, a built-in context object is created. You can add helpers to the built-in context object with:
|
38
|
+
|
39
|
+
RenderMePretty::Context.load_helpers("lib/helpers")
|
40
|
+
|
41
|
+
This loads modules defined in `lib/helpers` folder and adds their methods of the built-in context object. The helper classes must be defined with the following convetion: FooHelper and foo_helper.rb.
|
42
|
+
|
43
|
+
Note, helpers will only work with the built-in context scope. If you are passing in your own context object to be used, then you should handle adding helper methods to that context object yourself.
|
44
|
+
|
45
|
+
## Custom Context Scope
|
46
|
+
|
47
|
+
A built-in context object is provided for convenience. If you want to use your own context object, pass it as a variable. The context variable is specially treated as a context object. Example:
|
48
|
+
|
49
|
+
person = Person.new # must implement get_binding
|
50
|
+
erb = RenderMePretty::Erb.new("/path/to/template.erb")
|
51
|
+
erb.render(context: person, a: 2)
|
52
|
+
|
53
|
+
The context will be `person`. So person methods and instance variables will be available in the ERB templates.
|
54
|
+
|
55
|
+
=end
|
56
|
+
module RenderMePretty
|
57
|
+
class Erb
|
58
|
+
def initialize(path, variables={})
|
59
|
+
@path = path
|
60
|
+
@variables = variables
|
61
|
+
if variables[:context]
|
62
|
+
@context = variables.delete(:context)
|
63
|
+
else
|
64
|
+
@context = Context.new(variables)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def render(override_vars={})
|
69
|
+
@context.override_variables!(override_vars)
|
70
|
+
template = IO.read(@path)
|
71
|
+
ERB.new(template, nil, "-").result(@context.get_binding)
|
72
|
+
rescue Exception => e
|
73
|
+
handle_exception(e)
|
74
|
+
end
|
75
|
+
|
76
|
+
# How to know where ERB stopped? - https://www.ruby-forum.com/topic/182051
|
77
|
+
# syntax errors have the (erb):xxx info in e.message
|
78
|
+
# undefined variables have (erb):xxx info in e.backtrace
|
79
|
+
def handle_exception(e)
|
80
|
+
error_info = e.message.split("\n").grep(/\(erb\)/)[0]
|
81
|
+
error_info ||= e.backtrace.grep(/\(erb\)/)[0]
|
82
|
+
raise unless error_info # unable to find the (erb):xxx: error line
|
83
|
+
|
84
|
+
line = error_info.split(':')[1].to_i
|
85
|
+
io = StringIO.new
|
86
|
+
io.puts "#{e.class} evaluating ERB template on line #{line.to_s.colorize(:red)} of: #{@path.sub(/^\.\//, '')}"
|
87
|
+
|
88
|
+
template = IO.read(@path)
|
89
|
+
template_lines = template.split("\n")
|
90
|
+
context = 5 # lines of context
|
91
|
+
top, bottom = [line-context-1, 0].max, line+context-1
|
92
|
+
spacing = template_lines.size.to_s.size
|
93
|
+
template_lines[top..bottom].each_with_index do |line_content, index|
|
94
|
+
line_number = top+index+1
|
95
|
+
if line_number == line
|
96
|
+
io.printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
|
97
|
+
else
|
98
|
+
io.printf("%#{spacing}d %s\n", line_number, line_content)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Append the original stack trace also
|
103
|
+
io.puts("\nOriginal backtrace (last 5 lines):")
|
104
|
+
lines = ENV['FULL_STACK_TRACE'] ? e.backtrace : e.backtrace[0..4]
|
105
|
+
io.write(lines.join("\n"))
|
106
|
+
io.puts("\nRe-run with FULL_STACK_TRACE=1 to see all lines")
|
107
|
+
|
108
|
+
if ENV['TEST']
|
109
|
+
io.string
|
110
|
+
else
|
111
|
+
puts io.string
|
112
|
+
exit 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# http://stackoverflow.com/questions/1338960/ruby-templates-how-to-pass-variables-into-inlined-erb
|
118
|
+
class Context
|
119
|
+
def initialize(hash={})
|
120
|
+
hash.each do |key, value|
|
121
|
+
instance_variable_set('@' + key.to_s, value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def override_variables!(vars)
|
126
|
+
vars.each do |key, value|
|
127
|
+
instance_variable_set('@' + key.to_s, value)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_binding
|
132
|
+
binding
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.load_helpers(base_folder)
|
136
|
+
Dir.glob("#{base_folder}/**/*_helper.rb").each do |path|
|
137
|
+
relative_path = path.sub("#{base_folder}/", "")
|
138
|
+
class_name = File.basename(relative_path, '.rb').classify
|
139
|
+
|
140
|
+
require path
|
141
|
+
include const_get(class_name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "render_me_pretty/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "render_me_pretty"
|
7
|
+
spec.version = RenderMePretty::VERSION
|
8
|
+
spec.authors = ["Tung Nguyen"]
|
9
|
+
spec.email = ["tongueroo@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Render ERB template and provide more useful message pointing out the line with the error in the view}
|
12
|
+
spec.homepage = "https://github.com/tongueroo/render_me_pretty"
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
15
|
+
f.match(%r{^(test|spec|features)/})
|
16
|
+
end
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activesupport"
|
22
|
+
spec.add_dependency "colorize"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
end
|
data/tilt_examples.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'tilt/erb'
|
2
|
+
template = Tilt::ERBTemplate.new('templates/foo.erb')
|
3
|
+
joe = Person.find('joe')
|
4
|
+
output = template.render(joe, :x => 35, :y => 42)
|
5
|
+
# If no scope is provided, the template is evaluated within the context of an object created with Object.new.
|
6
|
+
|
7
|
+
# A single Template instance's render method may be called multiple times with different scope and locals arguments. Continuing the previous example, we render the same compiled template but this time in jane's scope:
|
8
|
+
|
9
|
+
jane = Person.find('jane')
|
10
|
+
output = template.render(jane, :x => 22, :y => nil)
|
11
|
+
# Blocks can be passed to render for templates that support running arbitrary ruby code (usually with some form of yield). For instance, assuming the following in foo.erb:
|
12
|
+
|
13
|
+
# Hey <%= yield %>!
|
14
|
+
# The block passed to render is called on yield:
|
15
|
+
|
16
|
+
template = Tilt::ERBTemplate.new('foo.erb')
|
17
|
+
template.render { 'Joe' }
|
18
|
+
# => "Hey Joe!"
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: render_me_pretty
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tung Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- tongueroo@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/console
|
97
|
+
- bin/setup
|
98
|
+
- lib/render_me_pretty.rb
|
99
|
+
- lib/render_me_pretty/version.rb
|
100
|
+
- render_me_pretty.gemspec
|
101
|
+
- tilt_examples.rb
|
102
|
+
homepage: https://github.com/tongueroo/render_me_pretty
|
103
|
+
licenses: []
|
104
|
+
metadata: {}
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.7.3
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Render ERB template and provide more useful message pointing out the line
|
125
|
+
with the error in the view
|
126
|
+
test_files: []
|