I have a two versions of my application layout, which are differs only in a few lines. Consider following example:
!!!
%html
%head
# a lot of code here
%body
# some more code here
- if defined? flag and flag == true
# variant 1
- else
# variant 2
The question is, how do I pass this flag to the layout?
class ApplicationController < ActionController::Base
layout 'layout', :locals => {:flag => true} #won't work :(
# ...
end
I usually prefer to use helper methods instead of instance variables in these situations. Here is an example of how it could be done:
class ApplicationController < ActionController::Base
layout 'layout'
helper_method :flag
...
protected
def flag
true
end
end
And if you have a controller where flag should not be true then you just overwrite the method:
class PostsController < ApplicationController
...
private
def flag
false # or perhaps do some conditional
end
end
This way you make sure that the flag helper is always available in views so you don't have to do the if defined?
or anything and also, in the cases where no layout is used, then no instance variable is assigned in any before_filter
.
It also helps keep as few instance variables as possible in the views.
Okay, so I found the solution by myself:
class ApplicationController < ActionController::Base
layout 'layout'
before_filter :set_constants
def set_constants
@flag = true
end
end
And the template should be:
!!!
%html
%head
# a lot of code here
%body
# some more code here
- if @flag
# variant 1
- else
# variant 2
There is two another option to do, what actually the OP asked:
in your layout:
- if flag ||= false
# variant 1
- else
# variant 2
in your application controller (this is the trick):
layout 'application' # or whatever
in any kind of controller:
render :locals => { :flag => true }
My guess would be, the layout processing is happening later cause of the "dynamic" (not really) layout
definition and that generates the necessary methods for all the keys inside of local_assigns
. So maybe the instance variable is a performanter solution. Any thoughts about that? Please leave a comment.
You could just use the local_assigns
variable like:
- if local_assigns[:flag] ||= false
# variant 1
- else
# variant 2
and then in any of your controller:
render :locals => { :flag => true }
A controller instance variable? That's the normal way to get information to the template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With