1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #30666 from urkle/fix-actionview-fixtureresolver

Fix checking for template variants when using the ActionView::FixtureResolver
This commit is contained in:
Rafael França 2019-04-03 18:32:18 -04:00 committed by GitHub
commit 4ecca4cd05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 2 deletions

View file

@ -6,6 +6,10 @@
*John Hawthorn*
* Fix `ActionView::FixtureResolver` so that it handles template variants correctly.
*Edward Rudd*
## Rails 6.0.0.beta3 (March 11, 2019) ##

View file

@ -25,8 +25,8 @@ module ActionView #:nodoc:
def query(path, exts, _, locals)
query = +""
EXTENSIONS.each_key do |ext|
query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
EXTENSIONS.each do |ext, prefix|
query << "(" << exts[ext].map { |e| e && Regexp.escape("#{prefix}#{e}") }.join("|") << "|)"
end
query = /^(#{Regexp.escape(path)})#{query}$/

View file

@ -17,4 +17,14 @@ class FixtureResolverTest < ActiveSupport::TestCase
assert_equal "arbitrary/path", templates.first.virtual_path
assert_nil templates.first.format
end
def test_should_match_templates_with_variants
resolver = ActionView::FixtureResolver.new("arbitrary/path.html+variant.erb" => "this text")
templates = resolver.find_all("path", "arbitrary", false, locale: [], formats: [:html], variants: [:variant], handlers: [:erb])
assert_equal 1, templates.size, "expected one template"
assert_equal "this text", templates.first.source
assert_equal "arbitrary/path", templates.first.virtual_path
assert_equal [:html], templates.first.formats
assert_equal ["variant"], templates.first.variants
end
end

View file

@ -1,3 +1,8 @@
* Added documentation about the `variants` option to `render`
*Edward Rudd*
## Rails 6.0.0.beta3 (March 11, 2019) ##
* No changes.

View file

@ -296,6 +296,7 @@ Calls to the `render` method generally accept five options:
* `:location`
* `:status`
* `:formats`
* `:variants`
##### The `:content_type` Option
@ -417,6 +418,44 @@ render formats: [:json, :xml]
If a template with the specified format does not exist an `ActionView::MissingTemplate` error is raised.
##### The `:variants` Option
This tells rails to look for template variations of the same format.
You can specify a list of variants by passing the `:variants` option with a symbol or an array.
An example of use would be this.
```ruby
# called in HomeController#index
render variants: [:mobile, :desktop]
```
With this set of variants Rails will look for the following set of templates and use the first that exists.
- `app/views/home/index.html+mobile.erb`
- `app/views/home/index.html+desktop.erb`
- `app/views/home/index.html.erb`
If a template with the specified format does not exist an `ActionView::MissingTemplate` error is raised.
Instead of setting the variant on the render call you may also set it on the request object in your controller action.
```ruby
def index
request.variant = determine_variant
end
private
def determine_variant
variant = nil
# some code to determine the variant(s) to use
variant = :mobile if session[:use_mobile]
variant
end
```
#### Finding Layouts
To find the current layout, Rails first looks for a file in `app/views/layouts` with the same base name as the controller. For example, rendering actions from the `PhotosController` class will use `app/views/layouts/photos.html.erb` (or `app/views/layouts/photos.builder`). If there is no such controller-specific layout, Rails will use `app/views/layouts/application.html.erb` or `app/views/layouts/application.builder`. If there is no `.erb` layout, Rails will use a `.builder` layout if one exists. Rails also provides several ways to more precisely assign specific layouts to individual controllers and actions.