0
votes

I need some help with a very specific case.

I would like to override the layout behavior for a particular view. I did found the Rhodes documentation describing what to do. (a copy of the Rhodes documentation is pasted at bottom of this text)

I tried to use the second alternative ("call the layout method on the controller to overwrite the default layout name") but it did not worked. I assume I might have misunderstood how to code the controller or hopefully only have a syntax error... See more information about the application below.

Could anyone please tell me how I should do it ? What would be the right syntax ? Or should I use another method ?

Thanks in advance.

Louis Deschenes

Here are some informations about the application and what I did:

  • Simple application
  • Build is for iPhone
  • Application start in "Calculator" view
  • "Calculator" view call "Control" view that call "Help" view
  • App structure:

    app/
    ->  index.erb                        (Control view)  
    ->  layout.erb                       (Standard layout)  
    ->  calculatorlayout.erb             (Customize layout for Calculator view)  
    ->  calculator/  
    ----->    index.erb                  (Calculator view)  
    ----->    calculator_controller.erb  (Controller to be able to override layout)  
    ->  help/  
    ----->    index.erb                  (Help view)
    
  • I created Calculator_controller.erb containning

    require 'rho/rhocontroller'
    
    require 'helpers/browser_helper'
    
    class CalculatorController < Rho::RhoController
    
    include BrowserHelper
    
    layout :calculatorlayout (Thats what  Rhodes doc mentionned to do)
    
  • As I said this does not work. Please tell me the right way to do it.

  • Note: As a temporily mesure I did a copy of app/calculatorlayout.erb into app/calculator/layout.erb This does the rendering right when the app start in "Caculator" view, but if I navigate to "About" view and back to "Calculator" view the rendering of the calculator is done with the standard layout.

--------Rhodes Documentation--------------------------------------------

If you would like to override or customize layout behavior, you can call the render function with the following parameters:

render :action => 'index', :layout => 'mycustomlayout', :use_layout_on_ajax => false

The first argument is the action you would like to render. Next is the (optional) layout name, which assumes the application root as a base directory. In the above example, Rhodes would look for a file called “mycustomlayout.erb” in the application root directory (you also may use :layout => false to disable the use of a layout template). The use_layout_on_ajax argument tells Rhodes whether or not to use the layout on Ajax calls (default is false).

You can call the layout method on the controller to overwrite the default layout name:

layout :mycustomlayout

This will force the render call to use mycustomlayout.erb in place of the default layout file for all actions of this controller.


2

2 Answers

0
votes

In the controller, you need to specify an action method. The render method of an action is what handles the layout property. You cannot simply designate a layout for an entire controller. Below is an example controller file. You would then need an index.erb view file to correspond to the index action method.

CalculatorController.rb

require 'rho/rhocontroller'
require 'helpers/browser_helper'

class CalculatorController < Rho::RhoController
    include BrowserHelper

    def index
        # perform any logic or fetch objects for the index.erb view

        render :action => :index, :layout => 'calculatorLayout'
    end

end
0
votes

Unfortunately Rhodes has godawful documentation so its mechanics can be difficult to decipher. But I must mention that unfortunately Geoffrey is entirely wrong in this point:

You cannot simply designate a layout for an entire controller

Actually, you can simply designate a layout for a controller. There are tons of ways, but specifically you can do as the docs supposedly mention, just not in the way 'ideschenes' tried. If you inspect the source code in render.rb you would notice that RhoController defines a setter method for this exact purpose, which is a basic Ruby mechanic.

def self.layout(name)
  @layout = name
end

Therefore you can either use self.layout = :layout_name or @layout = :layout_name inside the controller to define a default layout. I don't know the complexities of how it may be overridden, but this technique will allow you to set a default layout for any controller. I tested it myself.

There is also a method in RhoController which retrieves the layout name, and you can of course override this inside your own controller if you want to customize the behavior for choosing a layout.

def self.get_layout_name
  @layout.nil? ? 'layout' : @layout
end