How to pass a variable to a layout?

前端 未结 5 2087
时光说笑
时光说笑 2021-02-05 14:27

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 cod         


        
相关标签:
5条回答
  • 2021-02-05 15:03

    What about this http://snippets.dzone.com/posts/show/236 in order to conditionally select layouts?

    0 讨论(0)
  • 2021-02-05 15:09

    There is two another option to do, what actually the OP asked:

    #1

    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.

    #2

    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 }
    
    0 讨论(0)
  • 2021-02-05 15:15

    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.

    0 讨论(0)
  • 2021-02-05 15:16

    A controller instance variable? That's the normal way to get information to the template.

    0 讨论(0)
  • 2021-02-05 15:25

    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
    
    0 讨论(0)
提交回复
热议问题