rabl 0.18.0 → 0.19.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +25 -16
- data/SECURITY.md +14 -0
- data/lib/rabl/cache_engine.rb +17 -18
- data/lib/rabl/digestor.rb +2 -22
- data/lib/rabl/engine.rb +5 -15
- data/lib/rabl/railtie.rb +10 -14
- data/lib/rabl/renderer.rb +10 -5
- data/lib/rabl/sources.rb +5 -13
- data/lib/rabl/template.rb +2 -45
- data/lib/rabl/version.rb +1 -1
- data/lib/rabl.rb +3 -5
- metadata +10 -8
- data/lib/rabl/digestor/rails3.rb +0 -14
- data/lib/rabl/digestor/rails41.rb +0 -14
- data/lib/rabl/digestor/rails5.rb +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8bcb492fc67214455ff0bce236a63bdf0d2cb8a696253f3c3b1fa2eef3d6a08a
|
|
4
|
+
data.tar.gz: 79a96efbd90a60df008fd50313ef1f097bfbac97cee4298529491e00dac3f13c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfe2684ff81aa3b56be1a911da48f779f0493746cd996dd48d63715a9ebdfcfc544684cbf0b1fcd5ed86ba0526a536d356cbf10fc8fae48b02c7b7a9e5cc8ab1
|
|
7
|
+
data.tar.gz: 5241f944033242864fe36ec1ddca572b35e0cbad72067340de2c7be76a8d4d43b854d6caaebd4fec9c303ac96488091d857764a06c81cd1d3f5daf79daf2f021
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.19.0 (Nov 1, 2026)
|
|
4
|
+
|
|
5
|
+
### Requirements
|
|
6
|
+
|
|
7
|
+
* Require ActiveSupport 6.1 or newer, and so Rails 6.1 or newer under Rails. The code rabl kept for Rails 2 to 5 (their template handlers, digestors and template lookups) is removed; Rails 6.1 and newer, Sinatra and Padrino render as before. Apps on an older Rails or ActiveSupport can stay on 0.18.x (@nesquena)
|
|
8
|
+
|
|
9
|
+
### Fixes
|
|
10
|
+
|
|
11
|
+
* Load rabl's Rails integration on Rails 9 and later: rabl recognised Rails 3 to 8 by the first digit of `Rails.version`, so on a newer Rails the railtie and the `.rabl` template handler never loaded and actions rendered empty responses. rabl no longer checks the Rails version, so its integration loads on every Rails from 6.1 on, with no upper bound; Rails 6.1 to 8 load the same parts as before (@nesquena)
|
|
12
|
+
* Fix rabl defining a top-level `LRU` class for its own cache, which raised `TypeError: superclass mismatch for class LRU` in apps with an `LRU` class of their own; it is now `Rabl::CacheEngine::LRU` (use that name if your code used rabl's `LRU`). Once that cache (used outside Rails) held its 100,000 entries, each write also copied every key to drop the oldest one, about 0.5 ms per write; it now drops the same entries in a few µs (@nesquena)
|
|
13
|
+
* Fix `Rabl::Renderer` and `Rabl.render` raising `NoMethodError` (`undefined method 'underscore' for nil`) for an object, or a collection, whose class has no name, such as a `Struct.new` or `Class.new` object. The renderer sets an instance variable named after the object's class (`@post` for a `Post`); for an unnamed class it now sets none, and the template gets the object as for any other (@nesquena)
|
|
14
|
+
|
|
15
|
+
### Other changes
|
|
16
|
+
|
|
17
|
+
* `Rabl::Renderer#process_source` and the JSONP callback check in `Rabl::Engine` answer their yes/no question about a string with `String#include?` and `Regexp#match?` instead of `=~`, which built a `MatchData` neither check read: creating a renderer for a template string is about 1.2x faster and allocates 3 objects fewer, a full render about 2% faster and 3 objects fewer, and a render with `enable_json_callbacks` 3 objects fewer. The output is unchanged, and a source that is not valid in its encoding still raises the same `ArgumentError: invalid byte sequence in UTF-8`, from `Engine#eval_source` when it has a newline and from the template lookup when it doesn't; a source in a non-ASCII-compatible encoding, such as UTF-16LE, still raises `Encoding::CompatibilityError` from the check, now with Ruby's `incompatible character encodings` message rather than `incompatible encoding regexp match` (@tagliala; change written by DeepSeek Flash, reviewed by Claude Opus 5.5 and Claude Fable 5.1)
|
|
18
|
+
* CI now generates fresh Rails 7.2, Rails 8.1 and Sinatra apps that use rabl from the checkout and runs their tests (`test/apps/build_and_test.sh`), in place of the checked-in fixture apps for Rails 2 to 6 and Padrino under `fixtures/`, which CI never ran. No change to the gem (@nesquena)
|
|
19
|
+
* README: a `child` block is passed the child's data (e.g. the posts) and a `glue` block the glued object, not the parent, with examples that run; the partial example passes the post (`:object => post`, not `:post`); the JSON engine is Oj when it is loaded and Ruby's JSON otherwise (yajl isn't used); and under Rails, Rails sets the content type from the template's format. No behaviour change (@nesquena; reported by @nirvdrum in #393 and @adie in #580)
|
|
20
|
+
* The gem's rubygems.org page links the changelog, source code and issue tracker, and pushes to rubygems.org now require MFA (@nesquena)
|
|
21
|
+
|
|
3
22
|
## 0.18.0 (Oct 31, 2026)
|
|
4
23
|
|
|
5
24
|
### Requirements
|
data/README.md
CHANGED
|
@@ -26,6 +26,9 @@ For a breakdown of common misconceptions about RABL, please check out our guide
|
|
|
26
26
|
|
|
27
27
|
## Breaking Changes ##
|
|
28
28
|
|
|
29
|
+
* v0.19.0 requires ActiveSupport 6.1 or newer (and so Rails 6.1 or newer under Rails). Apps on an older Rails or
|
|
30
|
+
ActiveSupport can stay on 0.18.x.
|
|
31
|
+
|
|
29
32
|
* v0.18.0 requires Ruby 2.7 or newer (older Rubies can stay on 0.17.0). Every cache key changes once: expect a cold
|
|
30
33
|
cache after upgrading. It also fixes several long-standing output bugs in ways that can change existing output. Check the
|
|
31
34
|
[CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md) before upgrading.
|
|
@@ -55,12 +58,12 @@ or add to your Gemfile:
|
|
|
55
58
|
```ruby
|
|
56
59
|
# Gemfile
|
|
57
60
|
gem 'rabl'
|
|
58
|
-
#
|
|
61
|
+
# Optionally add `oj`: RABL encodes JSON with Oj when it is loaded, and with Ruby's JSON library otherwise
|
|
59
62
|
# If using `oj`, Rabl renders with Oj's :compat mode and sets it as Oj's default (with Oj 3.17.7+, only if you haven't configured Oj yet)
|
|
60
63
|
gem 'oj'
|
|
61
64
|
```
|
|
62
65
|
|
|
63
|
-
and run `bundle install` to install the dependency. RABL needs Ruby 2.7 or newer.
|
|
66
|
+
and run `bundle install` to install the dependency. RABL needs Ruby 2.7 or newer and ActiveSupport 6.1 or newer (on Rails, Rails 6.1 or newer).
|
|
64
67
|
|
|
65
68
|
To render XML, also add `gem 'builder'` (Rails apps already include it); RABL loads ActiveSupport's XML conversions itself.
|
|
66
69
|
|
|
@@ -135,7 +138,7 @@ Rabl.configure do |config|
|
|
|
135
138
|
# config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache
|
|
136
139
|
# config.perform_caching = false
|
|
137
140
|
# config.escape_all_output = false
|
|
138
|
-
# config.json_engine = nil # Class with #dump class method (defaults JSON)
|
|
141
|
+
# config.json_engine = nil # Class with #dump class method (defaults to Oj when it is loaded, else ::JSON)
|
|
139
142
|
# config.msgpack_engine = nil # Defaults to ::MessagePack
|
|
140
143
|
# config.bson_engine = nil # Defaults to ::BSON
|
|
141
144
|
# config.plist_engine = nil # Defaults to ::Plist::Emit
|
|
@@ -369,15 +372,18 @@ child :posts => :foobar do
|
|
|
369
372
|
end
|
|
370
373
|
```
|
|
371
374
|
|
|
372
|
-
|
|
375
|
+
The block is passed the child's data (here the user's posts, not the user), and the parent is still
|
|
376
|
+
available as `@user`:
|
|
373
377
|
|
|
374
378
|
```ruby
|
|
375
379
|
object @user
|
|
376
|
-
child :posts do |
|
|
377
|
-
attribute :title unless user.suspended?
|
|
380
|
+
child :posts do |posts|
|
|
381
|
+
attribute :title unless @user.suspended?
|
|
378
382
|
end
|
|
379
383
|
```
|
|
380
384
|
|
|
385
|
+
To decide for each post, use a condition, which is passed the post: `attribute :title, :if => lambda { |post| post.published? }`.
|
|
386
|
+
|
|
381
387
|
### Gluing Attributes ###
|
|
382
388
|
|
|
383
389
|
You can also append child attributes back to the root node:
|
|
@@ -391,11 +397,11 @@ end
|
|
|
391
397
|
|
|
392
398
|
Use glue to add additional attributes to the parent object.
|
|
393
399
|
|
|
394
|
-
|
|
400
|
+
The block is passed the glued object (here `@post`, not the user):
|
|
395
401
|
|
|
396
402
|
```ruby
|
|
397
403
|
object @user
|
|
398
|
-
glue(@post) {|
|
|
404
|
+
glue(@post) { |post| attribute :title if post.published? }
|
|
399
405
|
```
|
|
400
406
|
|
|
401
407
|
### Custom Nodes ###
|
|
@@ -481,7 +487,7 @@ collection @posts
|
|
|
481
487
|
|
|
482
488
|
extends('posts/show', :locals => { :hide_comments => true })
|
|
483
489
|
# or using partial instead of extends
|
|
484
|
-
# node(false) { |post| partial('posts/show', :object =>
|
|
490
|
+
# node(false) { |post| partial('posts/show', :object => post, :locals => { :hide_comments => true })}
|
|
485
491
|
```
|
|
486
492
|
|
|
487
493
|
and then access locals in the sub-template:
|
|
@@ -622,7 +628,7 @@ entry per viewer, apart from the nil case above. Include `root_object` whenever
|
|
|
622
628
|
Under Rails, keys include the Rails template digest when the template is rendered through a controller or view. `Rabl.render` and
|
|
623
629
|
`Rabl::Renderer` used outside a request have no view context, so their keys identify the template differently and don't match the keys of
|
|
624
630
|
a request. To render outside a request with the same keys, for example to warm the cache in a background job, render through the
|
|
625
|
-
controller
|
|
631
|
+
controller:
|
|
626
632
|
|
|
627
633
|
```ruby
|
|
628
634
|
PostsController.render(:show, assigns: { post: post }, formats: [:json])
|
|
@@ -673,13 +679,14 @@ node(:title) { locals[:custom_title] }
|
|
|
673
679
|
|
|
674
680
|
### Content Type Headers ###
|
|
675
681
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
682
|
+
Under Rails, Rails sets the content type from the template's format: `show.json.rabl` is served as
|
|
683
|
+
`application/json` and `show.xml.rabl` as `application/xml`. A template without a format in its name
|
|
684
|
+
(`show.rabl`) is served as `application/json` whatever it renders, so name templates by format when you
|
|
685
|
+
serve more than JSON.
|
|
680
686
|
|
|
681
|
-
|
|
682
|
-
|
|
687
|
+
Outside Rails, RABL doesn't set the content type, as it is intended to work for any Rack-based framework and
|
|
688
|
+
to be as agnostic to format as possible (see [this issue](https://github.com/nesquena/rabl/issues/185#issuecomment-4501232)).
|
|
689
|
+
Set it in your app, e.g. with Sinatra's `content_type :json` in the route or a `before` filter.
|
|
683
690
|
|
|
684
691
|
## Resources ##
|
|
685
692
|
|
|
@@ -741,6 +748,8 @@ Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full l
|
|
|
741
748
|
|
|
742
749
|
* Rigorous benchmarking and performance optimizations
|
|
743
750
|
|
|
751
|
+
To report a security vulnerability, don't open an issue; see [SECURITY.md](https://github.com/nesquena/rabl/blob/master/SECURITY.md).
|
|
752
|
+
|
|
744
753
|
## Authors and Contributors ##
|
|
745
754
|
|
|
746
755
|
Active Maintainers:
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes go into the latest release line of rabl. Please check that the problem occurs on the latest release.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Please report vulnerabilities privately, through GitHub's private vulnerability reporting: on the repository's
|
|
10
|
+
[Security tab](https://github.com/nesquena/rabl/security), choose "Report a vulnerability". Don't open a public issue or
|
|
11
|
+
pull request for a vulnerability.
|
|
12
|
+
|
|
13
|
+
Include the rabl version, the steps to reproduce the problem and its impact. The discussion continues in the report
|
|
14
|
+
until a fix is released.
|
data/lib/rabl/cache_engine.rb
CHANGED
|
@@ -7,29 +7,28 @@
|
|
|
7
7
|
# config.cache_engine = AdvancedCacheEngine.new
|
|
8
8
|
#
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
module Rabl
|
|
11
|
+
class CacheEngine
|
|
12
|
+
# A Hash holding at most max_size entries, which drops the entries added first
|
|
13
|
+
class LRU < Hash
|
|
14
|
+
attr_accessor :max_size
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
def initialize
|
|
17
|
+
super
|
|
18
|
+
self.max_size = 100_000
|
|
19
|
+
end
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def []= k,v
|
|
22
|
+
r = super
|
|
23
|
+
limit_size
|
|
24
|
+
r
|
|
25
|
+
end
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
def limit_size
|
|
28
|
+
shift while size > max_size
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
31
|
|
|
31
|
-
module Rabl
|
|
32
|
-
class CacheEngine
|
|
33
32
|
def initialize
|
|
34
33
|
unless defined?(Rails)
|
|
35
34
|
@cache = LRU.new
|
data/lib/rabl/digestor.rb
CHANGED
|
@@ -3,28 +3,8 @@
|
|
|
3
3
|
require 'action_view'
|
|
4
4
|
|
|
5
5
|
module Rabl
|
|
6
|
+
# Rails' digestor, under rabl's name: rabl.rb defines it only with the rest of the Rails integration, so
|
|
7
|
+
# Engine#digestor_available? checks for it before adding a template digest to a cache key
|
|
6
8
|
class Digestor < ActionView::Digestor
|
|
7
|
-
# Override the original digest function to ignore partial which
|
|
8
|
-
# rabl doesn't use the Rails conventional _ symbol.
|
|
9
|
-
if Gem::Version.new(Rails.version) >= Gem::Version.new('5.0.0.beta1')
|
|
10
|
-
require 'rabl/digestor/rails5'
|
|
11
|
-
elsif Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
|
|
12
|
-
require 'rabl/digestor/rails41'
|
|
13
|
-
else
|
|
14
|
-
require 'rabl/digestor/rails3'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
def dependency_digest
|
|
19
|
-
template_digests = (dependencies - [template.virtual_path]).collect do |template_name|
|
|
20
|
-
if Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
|
|
21
|
-
Digestor.digest(:name => template_name, :finder => finder)
|
|
22
|
-
else
|
|
23
|
-
Digestor.digest(template_name, format, finder)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
(template_digests + injected_dependencies).join("-")
|
|
28
|
-
end
|
|
29
9
|
end
|
|
30
10
|
end
|
data/lib/rabl/engine.rb
CHANGED
|
@@ -60,9 +60,7 @@ module Rabl
|
|
|
60
60
|
# count when no rule matches.
|
|
61
61
|
def singular_rule_rank(word)
|
|
62
62
|
inflections = ActiveSupport::Inflector.inflections
|
|
63
|
-
|
|
64
|
-
# ActiveSupport < 5 keeps them in a plain Array, checked by the last word
|
|
65
|
-
return -1 if uncountables.respond_to?(:uncountable?) ? uncountables.uncountable?(word) : uncountables.include?(word.downcase[/\b\w+\Z/])
|
|
63
|
+
return -1 if inflections.uncountables.uncountable?(word)
|
|
66
64
|
|
|
67
65
|
rules = inflections.singulars
|
|
68
66
|
rules.index { |(rule, _)| rule.is_a?(Regexp) ? rule.match?(word) : word.include?(rule) } || rules.size
|
|
@@ -149,16 +147,7 @@ module Rabl
|
|
|
149
147
|
if digestor_available? && respond_to?(:lookup_context) && lookup_context
|
|
150
148
|
template = @_options[:template] || @virtual_path
|
|
151
149
|
|
|
152
|
-
digest
|
|
153
|
-
if Rails.version.to_s =~ /^[678]/
|
|
154
|
-
Digestor.digest(name: template, finder: lookup_context, format: :rabl)
|
|
155
|
-
elsif Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
|
|
156
|
-
Digestor.digest(:name => template, :finder => lookup_context)
|
|
157
|
-
else
|
|
158
|
-
Digestor.digest(template, :rabl, lookup_context)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
cache_key << digest
|
|
150
|
+
cache_key << Digestor.digest(name: template, finder: lookup_context, format: :rabl)
|
|
162
151
|
# The digest covers the template source, but not the block that defines this engine
|
|
163
152
|
if @_block_identity
|
|
164
153
|
block, parent = @_block_identity
|
|
@@ -594,7 +583,7 @@ module Rabl
|
|
|
594
583
|
|
|
595
584
|
callback = request_params[:callback]
|
|
596
585
|
return unless callback.is_a?(String) && callback.length <= RABL_JSON_CALLBACK_MAX_LENGTH
|
|
597
|
-
return unless callback.ascii_only? && callback
|
|
586
|
+
return unless callback.ascii_only? && callback.match?(RABL_JSON_CALLBACK_NAME)
|
|
598
587
|
|
|
599
588
|
callback
|
|
600
589
|
end
|
|
@@ -647,8 +636,9 @@ module Rabl
|
|
|
647
636
|
end
|
|
648
637
|
end
|
|
649
638
|
|
|
639
|
+
# rabl.rb loads Rabl::Digestor with the rest of the Rails integration
|
|
650
640
|
def digestor_available?
|
|
651
|
-
defined?(
|
|
641
|
+
defined?(::Rabl::Digestor)
|
|
652
642
|
end
|
|
653
643
|
|
|
654
644
|
def valid_format?(format)
|
data/lib/rabl/railtie.rb
CHANGED
|
@@ -5,18 +5,16 @@ module Rabl
|
|
|
5
5
|
initializer "rabl.initialize" do |app|
|
|
6
6
|
# Force Rails to load view templates even in API mode
|
|
7
7
|
# Stolen shamelessly from jbuilder: https://github.com/rails/jbuilder/blob/master/lib/jbuilder/railtie.rb
|
|
8
|
-
|
|
9
|
-
module
|
|
10
|
-
|
|
11
|
-
include ActionView::Rendering
|
|
12
|
-
end
|
|
8
|
+
module ::ActionController
|
|
9
|
+
module ApiRendering
|
|
10
|
+
include ActionView::Rendering
|
|
13
11
|
end
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
14
|
+
ActiveSupport.on_load :action_controller do
|
|
15
|
+
if self == ActionController::API
|
|
16
|
+
include ActionController::Helpers
|
|
17
|
+
include ActionController::ImplicitRender
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
20
|
|
|
@@ -24,10 +22,8 @@ module Rabl
|
|
|
24
22
|
Rabl.register!
|
|
25
23
|
|
|
26
24
|
# Inject dependency tracker for :rabl
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ActionView::DependencyTracker.register_tracker :rabl, Rabl::Tracker
|
|
30
|
-
end
|
|
25
|
+
require 'action_view/dependency_tracker'
|
|
26
|
+
ActionView::DependencyTracker.register_tracker :rabl, Rabl::Tracker
|
|
31
27
|
end
|
|
32
28
|
end
|
|
33
29
|
end # Railtie
|
data/lib/rabl/renderer.rb
CHANGED
|
@@ -63,24 +63,26 @@ module Rabl
|
|
|
63
63
|
|
|
64
64
|
# Returns the source given a relative template path
|
|
65
65
|
def process_source(source)
|
|
66
|
-
return source if source.is_a?(String) && source
|
|
66
|
+
return source if source.is_a?(String) && source.include?("\n")
|
|
67
67
|
|
|
68
68
|
source, location = engine.fetch_source(source, { :view_path => options[:view_path] })
|
|
69
69
|
options[:source_location] ||= location
|
|
70
70
|
source
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
# Internal: Sets an instance variable named after the class of `object
|
|
73
|
+
# Internal: Sets an instance variable named after the class of `object`,
|
|
74
|
+
# unless the class has no name (Struct.new or Class.new)
|
|
74
75
|
#
|
|
75
76
|
# Example:
|
|
76
77
|
# object.class.name # => User
|
|
77
78
|
# set_object_instance_variable # => @user == object
|
|
78
79
|
#
|
|
79
80
|
def set_object_instance_variable
|
|
80
|
-
|
|
81
|
+
name = object_model_name
|
|
82
|
+
instance_variable_set(:"@#{name}", object) if name
|
|
81
83
|
end
|
|
82
84
|
|
|
83
|
-
# Internal: Returns the model name for an object
|
|
85
|
+
# Internal: Returns the model name for an object, or nil when its class has no name
|
|
84
86
|
#
|
|
85
87
|
# Example:
|
|
86
88
|
# object.class.name # => User
|
|
@@ -92,7 +94,10 @@ module Rabl
|
|
|
92
94
|
is_collection = item.is_a?(Array)
|
|
93
95
|
item = item.first if is_collection
|
|
94
96
|
|
|
95
|
-
name = item.class.name
|
|
97
|
+
name = item.class.name
|
|
98
|
+
return unless name
|
|
99
|
+
|
|
100
|
+
name = name.underscore
|
|
96
101
|
|
|
97
102
|
name = name.pluralize if is_collection
|
|
98
103
|
|
data/lib/rabl/sources.rb
CHANGED
|
@@ -189,7 +189,7 @@ module Rabl
|
|
|
189
189
|
end
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
-
# Returns the format Rails
|
|
192
|
+
# Returns the format Rails looks templates up in:
|
|
193
193
|
# the request's format, or for HTML requests the format being rendered (json for
|
|
194
194
|
# the default handler and for hash), as a Symbol, the only form Rails 7.0 and higher match
|
|
195
195
|
def rails_source_format
|
|
@@ -252,26 +252,18 @@ module Rabl
|
|
|
252
252
|
File.join(view_path.first.to_s, (file_path.to_s + ".rabl"))
|
|
253
253
|
end
|
|
254
254
|
|
|
255
|
-
# Returns the rabl template path for Rails,
|
|
255
|
+
# Returns the rabl template path for Rails, using Rails' own lookup
|
|
256
256
|
def fetch_rails_source(file, options = {})
|
|
257
|
-
# use Rails template resolution mechanism if possible (find_template)
|
|
258
257
|
source_format = request_format if defined?(request_format)
|
|
259
258
|
|
|
260
|
-
if source_format && context_scope.respond_to?(:lookup_context)
|
|
259
|
+
if source_format && context_scope.respond_to?(:lookup_context)
|
|
261
260
|
lookup_proc = lambda do |partial|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
else # Rails 3.2 and higher
|
|
265
|
-
# pull format directly from rails unless it is html
|
|
266
|
-
context_scope.lookup_context.find(file, [], partial, [], { :formats => [rails_source_format] })
|
|
267
|
-
end
|
|
261
|
+
# pull format directly from rails unless it is html
|
|
262
|
+
context_scope.lookup_context.find(file, [], partial, [], { :formats => [rails_source_format] })
|
|
268
263
|
end
|
|
269
264
|
template = lookup_proc.call(false) rescue nil
|
|
270
265
|
template ||= lookup_proc.call(true) rescue nil
|
|
271
266
|
template.identifier if template
|
|
272
|
-
elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
|
|
273
|
-
template = context_scope.view_paths.find_template(file, source_format, false)
|
|
274
|
-
template.filename if template
|
|
275
267
|
end
|
|
276
268
|
end
|
|
277
269
|
|
data/lib/rabl/template.rb
CHANGED
|
@@ -22,51 +22,8 @@ if defined?(Tilt)
|
|
|
22
22
|
Tilt.register 'rabl', RablTemplate
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
# Rails
|
|
26
|
-
if defined?(ActionView) && defined?(Rails) && Rails.respond_to?(:version)
|
|
27
|
-
require 'action_view/base'
|
|
28
|
-
require 'action_view/template'
|
|
29
|
-
|
|
30
|
-
module ActionView
|
|
31
|
-
module TemplateHandlers
|
|
32
|
-
class RablHandler < TemplateHandler
|
|
33
|
-
include Compilable
|
|
34
|
-
|
|
35
|
-
def compile(template) %{
|
|
36
|
-
::Rabl::Engine.new(#{template.source.inspect}, { :format => #{template.format.inspect} }).
|
|
37
|
-
render(self, assigns.merge(local_assigns))
|
|
38
|
-
} end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
ActionView::Template.register_template_handler :rabl, ActionView::TemplateHandlers::RablHandler
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Rails 3.X / 4.X / 5.X Template
|
|
47
|
-
if defined?(ActionView) && defined?(Rails) && Rails.respond_to?(:version) && Rails.version.to_s =~ /^[345]/
|
|
48
|
-
module ActionView
|
|
49
|
-
module Template::Handlers
|
|
50
|
-
class Rabl
|
|
51
|
-
class_attribute :default_format
|
|
52
|
-
self.default_format = Mime[:json]
|
|
53
|
-
|
|
54
|
-
def self.call(template)
|
|
55
|
-
source = template.source
|
|
56
|
-
|
|
57
|
-
%{ ::Rabl::Engine.new(#{source.inspect}, :source_location => #{template.identifier.inspect}).
|
|
58
|
-
apply(self, assigns.merge(local_assigns)).
|
|
59
|
-
render }
|
|
60
|
-
end # call
|
|
61
|
-
end # rabl class
|
|
62
|
-
end # handlers
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
ActionView::Template.register_template_handler :rabl, ActionView::Template::Handlers::Rabl
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Rails 6.X / 7.X / 8.X Template
|
|
69
|
-
if defined?(ActionView) && defined?(Rails) && Rails.respond_to?(:version) && Rails.version.to_s =~ /^[678]/
|
|
25
|
+
# Rails Template
|
|
26
|
+
if defined?(ActionView) && defined?(Rails) && Rails.respond_to?(:version)
|
|
70
27
|
module ActionView
|
|
71
28
|
module Template::Handlers
|
|
72
29
|
class Rabl
|
data/lib/rabl/version.rb
CHANGED
data/lib/rabl.rb
CHANGED
|
@@ -21,9 +21,9 @@ require 'rabl/cache_engine'
|
|
|
21
21
|
require 'rabl/template_cache_key'
|
|
22
22
|
|
|
23
23
|
if defined?(Rails) && Rails.respond_to?(:version)
|
|
24
|
-
require 'rabl/tracker'
|
|
25
|
-
require 'rabl/digestor'
|
|
26
|
-
require 'rabl/railtie'
|
|
24
|
+
require 'rabl/tracker'
|
|
25
|
+
require 'rabl/digestor'
|
|
26
|
+
require 'rabl/railtie'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# Rabl.register!
|
|
@@ -99,6 +99,4 @@ end
|
|
|
99
99
|
if defined?(Padrino)
|
|
100
100
|
require 'padrino-core'
|
|
101
101
|
Padrino.after_load { Rabl.register! }
|
|
102
|
-
elsif defined?(Rails.version) && Rails.version =~ /^2/
|
|
103
|
-
Rabl.register!
|
|
104
102
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rabl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Esquenazi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: '6.1'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: '6.1'
|
|
27
27
|
description: General ruby templating with json, bson, xml and msgpack support
|
|
28
28
|
email:
|
|
29
29
|
- nesquena@gmail.com
|
|
@@ -35,14 +35,12 @@ files:
|
|
|
35
35
|
- CONTRIBUTING.md
|
|
36
36
|
- MIT-LICENSE
|
|
37
37
|
- README.md
|
|
38
|
+
- SECURITY.md
|
|
38
39
|
- lib/rabl.rb
|
|
39
40
|
- lib/rabl/builder.rb
|
|
40
41
|
- lib/rabl/cache_engine.rb
|
|
41
42
|
- lib/rabl/configuration.rb
|
|
42
43
|
- lib/rabl/digestor.rb
|
|
43
|
-
- lib/rabl/digestor/rails3.rb
|
|
44
|
-
- lib/rabl/digestor/rails41.rb
|
|
45
|
-
- lib/rabl/digestor/rails5.rb
|
|
46
44
|
- lib/rabl/engine.rb
|
|
47
45
|
- lib/rabl/helpers.rb
|
|
48
46
|
- lib/rabl/multi_builder.rb
|
|
@@ -57,7 +55,11 @@ files:
|
|
|
57
55
|
homepage: https://github.com/nesquena/rabl
|
|
58
56
|
licenses:
|
|
59
57
|
- MIT
|
|
60
|
-
metadata:
|
|
58
|
+
metadata:
|
|
59
|
+
changelog_uri: https://github.com/nesquena/rabl/blob/master/CHANGELOG.md
|
|
60
|
+
source_code_uri: https://github.com/nesquena/rabl
|
|
61
|
+
bug_tracker_uri: https://github.com/nesquena/rabl/issues
|
|
62
|
+
rubygems_mfa_required: 'true'
|
|
61
63
|
post_install_message:
|
|
62
64
|
rdoc_options: []
|
|
63
65
|
require_paths:
|
data/lib/rabl/digestor/rails3.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'action_view'
|
|
4
|
-
|
|
5
|
-
module Rabl
|
|
6
|
-
class Digestor < ActionView::Digestor
|
|
7
|
-
def self.digest(name, format, finder, options = {})
|
|
8
|
-
cache_key = [name, format] + Array.wrap(options[:dependencies])
|
|
9
|
-
@@cache[cache_key.join('.')] ||= begin
|
|
10
|
-
Digestor.new(name, format, finder, options).digest
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'action_view'
|
|
4
|
-
|
|
5
|
-
module Rabl
|
|
6
|
-
class Digestor < ActionView::Digestor
|
|
7
|
-
def self.digest(options = {})
|
|
8
|
-
cache_key = [options[:name]] + Array.wrap(options[:dependencies])
|
|
9
|
-
@@cache[cache_key.join('.')] ||= begin
|
|
10
|
-
Digestor.new({ :name => options[:name], :finder => options[:finder] }.merge!(options)).digest
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|