Ruby-on-rails 如何在 Rails 中呈现不同格式的部分内容?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/339130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:49:28  来源:igfitidea点击:

How do I render a partial of a different format in Rails?

ruby-on-railsformatrenderpartialactionview

提问by James A. Rosen

I'm trying to generate a JSON response that includes some HTML. Thus, I have /app/views/foo/bar.json.erb:

我正在尝试生成包含一些 HTML 的 JSON 响应。因此,我有/app/views/foo/bar.json.erb

{
  someKey: 'some value',
  someHTML: "<%= h render(:partial => '/foo/baz') -%>"
}

I want it to render /app/views/foo/_baz.html.erb, but it will only render /app/views/foo/_baz.json.erb. Passing :format => 'html'doesn't help.

我希望它呈现/app/views/foo/_baz.html.erb,但它只会呈现/app/views/foo/_baz.json.erb。通过:format => 'html'没有帮助。

采纳答案by James A. Rosen

Building on roninek's response, I've found the best solution to be the following:

基于roninek 的响应,我找到了以下最佳解决方案:

in /app/helpers/application.rb:

在/app/helpers/application.rb:

def with_format(format, &block)
  old_format = @template_format
  @template_format = format
  result = block.call
  @template_format = old_format
  return result
end

In /app/views/foo/bar.json:

在/app/views/foo/bar.json:

<% with_format('html') do %>
  <%= h render(:partial => '/foo/baz') %>
<% end %>

An alternate solution would be to redefine renderto accept a :formatparameter.

一种替代的解决方案是重新定义render以接受一个:format参数。

I couldn't get render :fileto work with locals and without some path wonkiness.

我无法render :file与当地人一起工作,而且没有一些道路上的怪癖。

回答by Tim Haines

Beginning with Rails 3.2.3, when calling render :partial (only works outside of the respond_toblock).

从 Rails 3.2.3 开始,当调用 render :partial 时(只能在respond_to块之外工作)。

:formats => [:html]

instead of

代替

:format => 'html'

回答by Sam Stokes

What's wrong with

怎么了

render :partial => '/foo/baz.html.erb'

? I just tried this to render an HTML ERB partial from inside an Atom builder template and it worked fine. No messing around with global variables required (yeah, I know they have "@" in front of them, but that's what they are).

? 我只是尝试从 Atom 构建器模板内部渲染 HTML ERB 部分,它工作正常。不需要搞乱全局变量(是的,我知道它们前面有“@”,但这就是它们)。

Your with_format &blockapproachis cool though, and has the advantage that you only specify the format, whereas the simple approach specifies the template engine (ERB/builder/etc) as well.

不过,您的with_format &block方法很酷,并且具有您只指定格式的优点,而简单的方法也指定了模板引擎(ERB/builder/etc)。

回答by zgchurch

For Rails 3, the with_format block works, but it's a little different:

对于 Rails 3, with_format 块可以工作,但有点不同:

  def with_format(format, &block)
    old_formats = formats
    self.formats = [format]
    block.call
    self.formats = old_formats
    nil
  end

回答by DrewB

Rails 4 will allow you to pass a formats parameter. So you can do

Rails 4 将允许您传递格式参数。所以你可以做

render(:partial => 'form', :formats => [:html])} 

Note you can do something similar in Rails 3 but it wouldn't pass that format to any sub partials (if form calls other partials).

请注意,您可以在 Rails 3 中做类似的事情,但它不会将该格式传递给任何子部分(如果表单调用其他部分)。

You can have the Rails 4 ability in Rails 3 by creating config/initializers/renderer.rb:

您可以通过创建 config/initializers/renderer.rb 来在 Rails 3 中使用 Rails 4 功能:

class ActionView::PartialRenderer
  private
  def setup_with_formats(context, options, block)
    formats = Array(options[:formats])
    @lookup_context.formats = formats | @lookup_context.formats
    setup_without_formats(context, options, block)
  end

  alias_method_chain :setup, :formats
end

See http://railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/

http://railsguides.net/2012/08/29/rails3-does-not-render-partial-for-specific-format/

回答by Tony Stubblebine

In Rails 3, the View has a formats array, which means you can set it to look for [:mobile, :html]. Setting that will default to looking for :mobile templates, but fall back to :html templates. The effects of setting this will cascade down into inner partials.

在 Rails 3 中,视图有一个格式数组,这意味着您可以将其设置为查找 [:mobile, :html]。设置将默认寻找 :mobile 模板,但回退到 :html 模板。设置它的效果将级联到内部部分。

The best, but still flawed way, that I could find to set this was to put this line at the top of each full mobile template (but not partials).

我能找到的最好但仍有缺陷的方法是将此行放在每个完整移动模板(但不是部分)的顶部。

<% self.formats = [:mobile, :html] %>

The flaw is that you have to add that line to multiple templates. If anyone knows a way to set this once, from application_controller.rb, I'd love to know it. Unfortunately, it doesn't work to add that line to your mobile layout, because the templates are rendered before the layout.

缺陷是您必须将该行添加到多个模板中。如果有人知道从application_controller.rb 设置一次的方法,我很想知道。不幸的是,将该行添加到您的移动布局中是行不通的,因为模板是在布局之前呈现的。

回答by viphe

Just elaborating on what zgchurch wrote:

只是详细说明 zgchurch 所写的内容:

  • taking exceptions into account
  • returning the result of the called block
  • 考虑到例外情况
  • 返回被调用块的结果

Thought it might be useful.

认为它可能有用。

def with_format(format, &block)
  old_formats = formats
  begin
    self.formats = [format]
    return block.call
  ensure
    self.formats = old_formats
  end
end

回答by roninek

You have two options:

您有两个选择:

1) use render :file

1) 使用 render :file

render :file => "foo/_baz.json.erb"

2) change template format to html by setting @template_format variable

2) 通过设置@template_format 变量将模板格式更改为 html

<% @template_format = "html" %>
<%= h render(:partial => '/foo/baz') %>

回答by Dorian

I had a file named 'api/item.rabl' and I wanted to render it from an HTML view so I had to use:

我有一个名为“api/item.rabl”的文件,我想从 HTML 视图呈现它,所以我不得不使用:

render file: 'api/item', formats: [:json]

render file: 'api/item', formats: [:json]

(filebecause the file have no underscore in the name, formatsand not format(and passes and array))

file因为文件名称中没有下划线,formats并且没有format(以及传递和数组))

回答by Mario Uher

It seems that passing a formatsoption will render it properly in newer Rails version, at least 3.2:

似乎传递一个formats选项将在较新的 Rails 版本中正确呈现它,至少 3.2:

{
  someKey: 'some value',
  someHTML: "<%= h render('baz', formats: :html) -%>"
}