Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7682 (new enhancement)

Opened 1 year ago

Last modified 10 months ago

[PATCH] Doc RXML rendering shouldn't use RHTML layouts

Reported by: richie Assigned to: core
Priority: normal Milestone:
Component: ActionPack Version: edge
Severity: normal Keywords: docs layout xml
Cc:

Description

When rendering a xml page, rhtml layouts should not be used. For example, starting with a new rails project:

file: app/controllers/test_controller.rb

= class TestController < ApplicationController
        def my_action
                respond_to do |format|
                        format.html
                        format.xml
                end
        end
end

file: app/views/layout/test.rhtml

<body>
      <%= yield %>
</body>

file: app/views/test/my_action.rxml

xml.instruct!
xml.my_node(:name => 'bubba')

Now if I start script/server up on port 4000 and I run: curl -H "Accept: application/xml" http://localhost/test/my_action I should get:

<?xml version="1.0" encoding="UTF-8"?>
<my_node name="bubba"/>

but it gives me (because the layout is applied)

<body>
      <?xml version="1.0" encoding="UTF-8"?>
<my_node name="bubba"/>

</body>

Attachments

better_document_exempt.diff (1.0 kB) - added by wycats on 06/18/07 02:00:00.

Change History

02/28/07 21:31:16 changed by richie

Slight fix, the curl command should be: curl -H "Accept: application/xml" http://localhost:4000/test/my_action

02/28/07 22:21:33 changed by richie

  • keywords changed from layout, xml to layout xml.

Workaround, add the following to your application controller:

alias true_render render
    
def render(options = nil, deprecated_status = nil, &block)
  options[:layout] = false if options[:action] and options[:action].match /.*\.rxml$/
  true_render options, deprecated_status, &block
end

02/28/07 23:59:50 changed by richie

There's a bug in my previous comment, if options is nil it'll die:

workaround v2

alias true_render render
    
def render(options = nil, deprecated_status = nil, &block)
  options[:layout] = false if options and options[:action] and options[:action].match /.*\.rxml$/
  true_render options, deprecated_status, &block
end

03/01/07 17:47:52 changed by richie

Version 3: this handles if you do render action => :action_name

    alias true_render render
    
    def render(options = nil, deprecated_status = nil, &block)
        options[:layout] = false if options and options[:action] and options[:action].to_s.match /.*\.rxml$/
        true_render options, deprecated_status, &block
    end

04/11/07 12:30:30 changed by crippledcanary

Without the workaround not even overrideing the :layout option works.

format.xml {render :layout => false }

This does still render the layout.

04/11/07 12:45:32 changed by crippledcanary

It might be related to what was done in #307.

If I remove the rhtml layout and tries to access with xml format using Firefox I get a error. In my example the url is "http://localhost:3000/users.xml" ...

 Errno::ENOENT in Users#index

 Showing app/views/layouts/users.rhtml where line # raised:

 No such file or directory - script/../config/../app/views/layouts/users.rhtml


 vendor/rails/actionpack/lib/action_view/base.rb:440:in `mtime'
 vendor/rails/actionpack/lib/action_view/base.rb:440:in `compile_template?'
 vendor/rails/actionpack/lib/action_view/base.rb:317:in `compile_and_render_template'
 vendor/rails/actionpack/lib/action_view/base.rb:301:in `render_template'
 vendor/rails/actionpack/lib/action_view/base.rb:260:in `render_file'
 vendor/rails/actionpack/lib/action_controller/layout.rb:254:in `render_without_benchmark'
 vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
 /usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
 vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
 app/controllers/users_controller.rb:7:in `index'
 app/controllers/users_controller.rb:7:in `index'

 Request

 Parameters: {"format"=>"xml"}

 --- 
 flash: !map:ActionController::Flash::FlashHash {}


 Response
 Headers: {"Status"=>"200 OK", "cookie"=>[], "Content-Type"=>"application/xml", "Cache-Control"=>"no-cache"}

04/11/07 13:17:16 changed by richie

I haven't looked at the code for #307, but looking at the description that definitely seems like it would be the root of the problem.

crippledcanary: did you restart your server before you tried accessing that url (after you deleted the .rhtml file)? The server (mongrel at least) I don't think picks up those sorts of changes.

(follow-up: ↓ 10 ) 04/27/07 17:43:11 changed by jwieland

I have the same issue. While the workarounds might be a temporary solution. I think a more permanent fix is applicable.

05/22/07 19:05:17 changed by josh

  • component changed from Web to ActionPack.

(in reply to: ↑ 8 ) 05/31/07 05:22:30 changed by keegan

Replying to jwieland:

I have the same issue. While the workarounds might be a temporary solution. I think a more permanent fix is applicable.

Pardon me if I'm wrong but, after digging through ActionController and ActionView in 1.2.3, this is actually intended behavior. You're allowed to mix and match ERB and Builder templates to your heart's content.

If you don't want Builder templates rendered with layouts in your app, you can specify that with the following snippet in your ApplicationController:

exempt_from_layout :rxml

I certainly agree that method could be documented better, especially with all of the blogger tutorials on respond_to ignoring it completely.

Hope this helps.

06/18/07 01:59:28 changed by wycats

Attached is a doc-patch that better explains the use of exempt_from_layout in the context of respond_to.

06/18/07 02:00:00 changed by wycats

  • attachment better_document_exempt.diff added.

07/13/07 04:11:46 changed by mikong

  • keywords changed from layout xml to docs layout xml.
  • type changed from defect to enhancement.
  • summary changed from RXML rendering shouldn't use RHTML layouts to [PATCH] Doc RXML rendering shouldn't use RHTML layouts.