This is a weird requirement that may need another approach, but my brain is stuck.
I want to accomplish something like this:
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.n开发者_如何学JAVAew {
render :inline => "<%= yield(:djs) %>" if request.format.djs?
}
end
end
I want to use content_for
because I may want to add content to the :djs
yield in other filters.
However, this code raises undefined method output_buffer=
.
I suppose I could use an instance variable, but this seems cleaner, doesn't it?
You need to use the #view_context
method to reach the view context and then you can do the same as you would do in a view:
view_context.content_for(:something, view_context.render(partial: 'some_partial'))
you can't use content_for
in controllers, even you knew view_context
can provide the method.
see the issue here: https://github.com/rails/rails/issues/4906
the method view_context
always returns a new object. when you call view_context.content_for(:somethin, 'content')
it will store content in instance variable of the new object.
you can do an experiment in controllers like the following:
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"}
anyway, if you still want to use content_for
in controllers, you can override view_context
in controllers as a workaround. but I don't know whether any side effects.
def view_context
@_view_context ||= super
end
I found this helpful very much in case of setting title for my page.
I can just set content_for from controller
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
If like me you are just looking to set content in the controller like a title, then it's probably better to just use a variable that's automatically passed to views and helpers. eg.
controller:
class AController < ApplicationController
before_action :set_title
private
def set_title
@title = 'Email Subscription'
end
end
and the helper:
module ApplicationHelper
def title_suffix
" - #{@title}" unless @title.nil?
end
end
and the template:
<!DOCTYPE html>
<html>
<head>
<title>Standard Title<%= title_suffix %></title>
...
I've found a cleaner way than setting content_for from the controller.
In my case I have sidebar which needs to be displayed for every view.
In my layout I have
<%= yield :sidebar %>
Then I have a partial called _set_sidebar.html.erb
which does this
<% content for :sidebar do %>
<% render :partial => "layouts/sidebar", locals => {:locs => locs} %>
<% end %>
Then I just put a one liner in every view that I want to also have that sidebar
<%= render :partial => "layouts/set_sidebar", locals => {:locs => locs}
Otherwise I was previously using this
https://gist.github.com/985457 with .html_safe when I used render_to_string
view_context
did not work in 5.1.4
render inline: erb
however, did:
render inline: <<~ERB, layout: 'layout_expecting_subtabs'
<% content_for(:subtabs, render(partial: 'somewhere/subtabs') ) %>
<h1> yielded content </h1>
ERB
精彩评论