在控制器中使用content_for

时间:2011-06-05 17:43:39

标签: ruby-on-rails-3

这是一个奇怪的要求,可能需要另一种方法,但我的大脑卡住了。

我想完成这样的事情:

class UsersController < ApplicationController
  before_filter Proc.new { share_params :user_name }, :only => :show
  render_djs
end

class ApplicationController < ActionController::Base
  include ActionView::Helpers::CaptureHelper
  def share_params(*shared)
    content_for(:djs) { shared.inspect }
  end

  def self.render_djs
    before_filter Proc.new {
      render :inline => "<%= yield(:djs) %>" if request.format.djs?
    }
  end
end

我想使用content_for,因为我可能希望在其他过滤器中为:djs产量添加内容。

但是,此代码会引发undefined method output_buffer=

我想我可以使用一个实例变量,但这看起来更干净,不是吗?

5 个答案:

答案 0 :(得分:14)

您需要使用#view_context方法来访问视图上下文,然后您可以像在视图中那样执行相同操作:

view_context.content_for(:something, view_context.render(partial: 'some_partial'))

答案 1 :(得分:4)

我发现这对于为我的页面设置标题非常有帮助。

我可以从控制器

设置content_for
class PostsController < ApplicationController
  def index
    content_for :title, "List of posts"
    ...
  end
end

https://gist.github.com/hiroshi/985457
https://github.com/clmntlxndr/content_for_in_controllers

答案 2 :(得分:3)

如果像我一样,你只是想把控制器中的内容设置为标题,那么最好只使用一个自动传递给视图和助手的变量。例如

控制器:

<!DOCTYPE html>
<html>
<head>
  <title>Standard Title<%= title_suffix %></title>
...

和帮手:

{{1}}

和模板:

{{1}}

答案 3 :(得分:0)

我找到了一种比从控制器设置content_for更简洁的方法。

在我的情况下,我需要为每个视图显示侧边栏。

在我的布局中我有

<%= yield :sidebar %>

然后我有一个名为_set_sidebar.html.erb的部分来做这个

<% content for :sidebar do %>
   <% render :partial => "layouts/sidebar", locals => {:locs => locs} %>
<% end %>

然后我只在每个视图中放置一个衬垫,我也希望有侧边栏

<%= render :partial => "layouts/set_sidebar", locals => {:locs => locs}

否则我之前使用过这个

当我使用render_to_string

时,使用.html_safe

https://gist.github.com/985457

答案 4 :(得分:0)

即使您知道content_for可以提供该方法,您也不能在控制器中使用view_context。 请在此处查看问题:https://github.com/rails/rails/issues/4906

方法view_context始终返回新对象。当您调用view_context.content_for(:somethin, 'content')时,它将内容存储在新对象的实例变量中。

您可以在如下所示的控制器中进行实验:

view_context.content_for(:title, 'hello')
view_context.view_flow.content # => {}

a = view_context
a.content_for(:title, 'hello')
a.view_flow.content # =>  {:title=>"hello"}

无论如何,如果您仍然想在控制器中使用content_for,则可以替代控制器中的view_contxt作为解决方法。但我不知道是否有任何副作用。

def view_context
  @_view_context ||= super
end