Links on the left hand side - are components necessary?


#1

Hello,

Maybe this is super-trivial…
I need to have a list of links on the left hand side of my application,
for every single page.

So, I’ve created a layout called “main” (main.rhtml) under
view/layouts, and included >layout “main”< in pretty all of my
controllers.

main.rhtml has, amongst all the other HTML stuff:

<%= render_component :controller=> ‘dli/extras’, :action=>
‘show_lookup_links’%>

This is the component to display the links:

class Dli::ExtrasController < ApplicationController
uses_component_template_root
Link=Struct.new(:name,:controller,:action)

def show_lookup_links
@links=[]
@links << Link.new(“Channels”, “/lookup/channel”, “index”)
@links << Link.new(“Password durations”,
“/lookup/password_duration”, “index”)
render :layout=>false
end

end

Now: the list of links will need to change according to the user’s
permission. So, there is quite a lot of logic involved here.

What are my options, if I don’t want to use components?

The only solution I can think of is to add a method to the general
application controller (application.rb). However, how do call such an
action from main.rhtml? It looks like I need to be able to specify
controller and action, which brings me back to components…

Can somebody please enlighten me? I feel that I am heading the wrong
way, and…

Thanks,

Merc.


#2

Components are going out of favour anyway so you’re best off with
partials:

<%= render :partial => ‘foo/bar’ %>

then in app/views/foo/_bar.rhtml you include your code. You can add the
logic into a before_filter method that creates an instance variable that
the partial can access.

You could also create a helper method in
app/helpers/application_helper.rb:

def my_helper(options = {})

make code

end

Then you can just call it in your templates:
<%= my_helper :option1 => ‘foo’, :option2 => ‘bar’ %>

The first method is probably best though. If you’re generating a list
of links, i would create a before_filter in application_controller that
loads the links into a collection then pass this to the partial:

  • application_controller.rb
    before_filter :load_menu

def load_menu

load links into @links

end

  • main.rhtml
    <%= render :partial => 'link', :collection => @links %>
  • _link.rhtml
  • <%= link %>
  • Check out
    http://api.rubyonrails.org/classes/ActionController/Base.html#M000206
    for more information about partials.

    Hope that helps,

    Steve

    Tony M. wrote:

    Hello,

    Maybe this is super-trivial…
    I need to have a list of links on the left hand side of my application,
    for every single page.

    So, I’ve created a layout called “main” (main.rhtml) under
    view/layouts, and included >layout “main”< in pretty all of my
    controllers.

    main.rhtml has, amongst all the other HTML stuff:

    <%= render_component :controller=> ‘dli/extras’, :action=>
    ‘show_lookup_links’%>

    This is the component to display the links:

    class Dli::ExtrasController < ApplicationController
    uses_component_template_root
    Link=Struct.new(:name,:controller,:action)

    def show_lookup_links
    @links=[]
    @links << Link.new(“Channels”, “/lookup/channel”, “index”)
    @links << Link.new(“Password durations”,
    “/lookup/password_duration”, “index”)
    render :layout=>false
    end

    end

    Now: the list of links will need to change according to the user’s
    permission. So, there is quite a lot of logic involved here.

    What are my options, if I don’t want to use components?

    The only solution I can think of is to add a method to the general
    application controller (application.rb). However, how do call such an
    action from main.rhtml? It looks like I need to be able to specify
    controller and action, which brings me back to components…

    Can somebody please enlighten me? I feel that I am heading the wrong
    way, and…

    Thanks,

    Merc.


    #3

    On 6/7/06, Tony M. removed_email_address@domain.invalid wrote:

    def show_lookup_links
    @links=[]
    @links << Link.new(“Channels”, “/lookup/channel”, “index”)
    @links << Link.new(“Password durations”,
    “/lookup/password_duration”, “index”)
    render :layout=>false
    end

    This looks like trouble. You’re going to be better off if you use
    link_to() and let Rails build the paths that it needs. When I see
    “/lookup/channel” hardcoded it sets off warning bells.

    Can somebody please enlighten me? I feel that I am heading the wrong
    way, and…

    One thing that you could do to get away from using a component would
    be to put the common pieces of your nav as partials in
    /app/view/shared. Your layout(s) could then use this shared nav RHTML
    code as needed.

    – James


    #4

    On Wednesday, June 07, 2006, at 7:48 PM, Stephen B. wrote:

    app/helpers/application_helper.rb:
    loads the links into a collection then pass this to the partial:
    <%= render :partial => ‘link’, :collection => @links %>

    view/layouts, and included >layout “main”< in pretty all of my
    uses_component_template_root
    end


    Rails mailing list
    removed_email_address@domain.invalid
    http://lists.rubyonrails.org/mailman/listinfo/rails

    This is basically how I have done it. A partial to display the links.
    In my case, I am using the user_engine/login_engine combo, so all I have
    to do is run a query against the permissions table to get a list of
    actions that are allowed. It’s not perfect as it is because there are
    several actions that you really wouldn’t want users to call directly
    (i.e., an ‘edit’ action needs an id to work).

    Another approach would be to pre-generate a list of menu items and then
    use ‘link_if_authorized’ instead of ‘link_to’. This will make them show
    up only if the user has permission to access them (it’s included in the
    user_engine).

    _Kevin


    #5

    What’s wrong with just putting

    <%=link_to_unless_current “Home”, :controller=>“main”, :action=>“index”
    %>

    in your main.rhtml file

    If they’re always the same across all pages, why make the extra work?
    If you need them to be dynamically generated, then use render :partial
    as stated in an earlier post.


    #6

    Hi,

    def show_lookup_links
    @links=[]
    @links << Link.new(“Channels”, “/lookup/channel”, “index”)
    @links << Link.new(“Password durations”,
    “/lookup/password_duration”, “index”)
    render :layout=>false
    end

    This looks like trouble. You’re going to be better off if you use
    link_to() and let Rails build the paths that it needs. When I see
    “/lookup/channel” hardcoded it sets off warning bells.

    Oh no, it’s not. /lookup/channel is actually a contoller’s name which
    lives in a separate directory (I put a whole bunched of controllers
    under “lookup/…” and called them Lookup::ChannelController, for
    example).

    Merc.


    #7

    Hello,

    Brian H. wrote:

    What’s wrong with just putting

    <%=link_to_unless_current “Home”, :controller=>“main”, :action=>“index”
    %>

    in your main.rhtml file

    If they’re always the same across all pages, why make the extra work?

    From my post:

    “Now: the list of links will need to change according to the user’s
    permission. So, there is quite a lot of logic involved here.”

    If you need them to be dynamically generated, then use render :partial
    as stated in an earlier post.

    Yep - that’s exactly what I’m doing.

    Merc.