Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

template lookup should search controller inheritance chain

#948

(Josh, I briefly mentioned this to you via email.)

Here's the gist of the feature:

Say you have:

DocumentsController < ApplicationController ArticlesController < DocumentsController

and a view file at:

app/views/documents/list.html.erb

If you request articles/list, and app/views/articles/list.html.erb doesn't exist, rails should render app/views/documents/list.html.erb for you.

Here's my plugin that implements this behavior:

http://github.com/kch/inheritabl...

I'm opening this case to consider making this behavior default in rails.

If you would please experiment with the plugin and let me know if the core is interested, I'd be happy to convert the plugin into a patch.

Reported by Caio Chassot · September 1st, 2008 @ 07:23 AM

State: resolved
Milestone: 3.1
Assigned to: Yehuda Katz (wycats) Yehuda Katz (wycats)
Importance: Low

Activity

  1. Ahmed Adam
    Ahmed Adam

    +1 I tried this on 2.1 and it works as expected. It's a very useful feature for people using inherited controllers.

    September 4th, 2008 @ 05:53 AM

  2. josh
    josh
    • Milestone cleared.
    • State changed from new to open

    You can you use git-format-patch to make me a diff file, please.

    I'm also curious how this applies to partial rendering. I ran into this problem a few times.

    
    # admin/posts/index.html.erb
    render :partial => "post"
    
    # posts/_post.html.erb
    Hello
    

    September 7th, 2008 @ 03:59 PM

  3. Caio Chassot
    Caio Chassot

    The plugin handles partials as well.

    I'll work on a patch now.

    September 8th, 2008 @ 03:13 AM

  4. Caio Chassot
    Caio Chassot

    Running into some issues with actionmailer tests. Which reminds me, should I implement inheritable templates for actionmailer too?

    In the name of consistency, it seems to make sense, but on the other hand, I feel like it'll never be used. So, for now, I'm skipping it, but if there's interest, post here.

    September 8th, 2008 @ 04:11 AM

  5. Caio Chassot
    Caio Chassot
    • Tag changed from actionpack, edge, enhancement to actionpack, edge, enhancement, patch

    Here's a patch.

    Only handling actionpack, no actionmailer.

    Passes all tests, no new tests added.

    I think such a feature would deserve at least a test for the controller action and partial template lookup. Would appreciate some pointers on where it's best to add them.

    September 8th, 2008 @ 04:20 AM

  6. josh
    josh

    I shouldn't have to touch ActionView, since it only affects the controller's default template. Maybe it's missing a hook?

    September 8th, 2008 @ 03:23 PM

  7. josh
    josh

    I'm starting to think this would be better off as a plugin. However, it is sucky that you have to override the pick partial stuff. We should fix this so your plugin can hook in easier.

    http://github.com/kch/inheritabl...

    September 8th, 2008 @ 03:46 PM

  8. Caio Chassot
    Caio Chassot

    Template finding is quite spaghettied into the various rails components. Controllers find action templates one way, then views find partials another, and actionmailer works differently too.

    Maybe this is something that could be abstracted to a template finder module?

    As for the hooks, we used to have them. If you check out the tags in my plugin repository, you can see that for previous versions of rails I had to overwrite less internal stuff. Was never an ideal situation though.

    September 8th, 2008 @ 06:24 PM

  9. Caio Chassot
    Caio Chassot

    On having to patch actionview, if you just patch actionview the way I did, and have it ask the controller for the template, then the plugin wouldn't need to orverride _pick_partial_template.

    You don't need to call find_inherited_template, you could simply call default_template_name, and the plugin could override it to use find_inherited_template, as it does now.

    However, all this feels pretty flaky. I'd prefer to have the whole thing committed to the core. Seems to make sense that templates would be inherited.

    I'll try to work on a more robust patch.

    September 8th, 2008 @ 06:26 PM

  10. josh
    josh
    • Milestone set to 2.x

    :) I totally agree. If you could refactor some of that finder code i'd be more convinced to let it into core. I'm just a bit worried about adding the logic to default_template_name (where it should be) and to pick_template (where it shouldn't). I could see myself auditing pick_template sometime in the future and wondering why this code is there.

    September 8th, 2008 @ 11:25 PM

  11. josh
    josh
    • State changed from open to wontfix

    Temporary closing the ticket. Can you please email me (directly) when you come up with a kick ass solution. Thanks for looking into this.

    September 8th, 2008 @ 11:26 PM

  12. artemave
    artemave

    Yet another attempt to get this feature through. The attached patch based on current 2-3-stable.

    October 29th, 2009 @ 11:30 PM

  13. josh
    josh
    • State changed from wontfix to open
    • Milestone cleared.
    • Assigned user changed from josh to Yehuda Katz (wycats)

    If this feature is to go in Rails, it certainly needs to be implemented on master too. Reassigning to Yehuda to review this idea. Once we can get it working in 3.0, it seems fine to "backport" it. Even though it was actually done on 2.3 first ;)

    October 31st, 2009 @ 02:29 AM

  14. artemave
    artemave

    Oh no, not 3.0... I am desperately lost in that code ;)

    October 31st, 2009 @ 11:02 AM

  15. artemave
    artemave

    Guys, quick doublecheck. Am I supposed to make 3.0 version at this point or the whole idea has to be first reviewed by Yehuda Katz?

    November 6th, 2009 @ 07:04 PM

  16. Rizwan Reza
    Rizwan Reza

    I just talked to Yehuda and he's asking for a patch on master. He says this should be implemented in the Resolver, which currently doesn't have any way to specify fallbacks. (The "context" slot needs to take an array)

    I am sure this will help you, artemave. Please do ask anything here about this. Thanks!

    January 22nd, 2010 @ 06:05 AM

  17. artemave
    artemave

    Rizwan, I'm finishing up the patch at the moment. However the change affects AbstractController::Rendering rather than Resolver. I'll look closely though into this alternative and possibly come up with two different patches.

    Thanks for your response, it is good to know there is after all life on Mars.

    January 22nd, 2010 @ 09:01 AM

  18. Rizwan Reza
    Rizwan Reza

    You might wanna buckle yourself up to write this up since Yehuda is all set to release Rails 3 beta soon. Good Luck!

    January 22nd, 2010 @ 10:56 AM

  19. artemave
  20. Rizwan Reza
    Rizwan Reza

    The patch applies cleanly. But artemave, you might want to do it in Resolver as Yehuda had said. Anyways, will pass it on to Yehuda and let's see what he says.

    January 24th, 2010 @ 06:01 AM

  21. Rizwan Reza
    Rizwan Reza

    Yehuda still wants it to be written in Resolver. Can you do that?

    January 24th, 2010 @ 08:11 PM

  22. artemave
    artemave

    I am struggling to figure out how. Resolver has got no awareness of controller at the moment. Unless we start passing it to view_paths elements. Does that sound like a plan? Or is there something I am missing here?

    January 24th, 2010 @ 08:35 PM

  23. Rizwan Reza
    Rizwan Reza

    This is Yehuda had in mind:

    There's a slot for "context" right now, which is the controller directory to look under. I think that would have to take an Array of contexts. The problem with doing it in render is that it'll only work in some cases but not in others. People will be wondering why a layout name from a parent controller doesn't come in.

    He also wonders whether it might good to leave this until Rails 3.1.

    artemave, I hope this helps. Thanks!

    January 24th, 2010 @ 09:50 PM

  24. artemave
    artemave

    Rizwan,

    I've been waiting for 3 months for any response. If it wasn't for that, this feature would have been done long time ago. So I think it would be fair for you guys to wait few days for me to finish.

    January 25th, 2010 @ 09:29 AM

  25. Rizwan Reza
    Rizwan Reza

    Sorry you had to wait that long. Get your patch ready, I will ask Yehuda to
    apply it. Thanks!

    January 25th, 2010 @ 09:31 AM

  26. artemave
    artemave

    When you talk about 'array of contexts' do you mean the array in FileSystemResolverWithFallback?

    P.S.
    Good point about layouts not being inherited (in my patch). Frankly, I didn't know that layouts get picked up much the same way as regular templates.

    January 25th, 2010 @ 09:33 AM

  27. Caio Chassot
    Caio Chassot

    A quick note on layout inheritance:

    Given controller A with layout "a", controller B < A, with an explicit call to layout false, B must not fallback layout "a", it must use no layout.

    Just the kind of common bug that tends to crop up.

    And thanks for taking this over from me.

    January 25th, 2010 @ 09:43 AM

  28. artemave
    artemave

    No worries. This feature is a bit cursed though. Started here: http://dev.rubyonrails.org/ticket/5027 . Then failed to make it here: http://dev.rubyonrails.org/ticket/7076 . And got shot in this ticket. So, in the end, I just couldn't resist fighting the doom.

    P.S.
    Nice test case, thanks.

    January 25th, 2010 @ 10:06 AM

  29. artemave
    artemave

    Speaking of layout inheritance. If implemented, it may change current behavior of existing applications. Some controllers may start falling back to parent layout instead of application layout (current behavior). Please let me know if this is a problem.

    January 26th, 2010 @ 11:38 AM

  30. artemave
    artemave

    Here is the version WITHOUT layout inheritance.
    Few notes:

    • Template inheritance ended up in PathSet rather than Resolver. Since instance of Resolver is an element in view_paths, it can only "apply itself" to parent controller. But if parent controller has different elements in its view_paths this will be incorrect.

    • MissingTemplate changed in order to comply with template inheritance. There were also some unused/out of place stuff there. As if it's been copypasted from 2.x code. I believe I cleaned up a bit.

    • PathSet::find_template method seemed to not have been used anywhere. Hence, removed.

    Version WITH layout inheritance may be produced quickly once the desired behavior is clarified (see my previous comment)

    http://github.com/artemave/rails/tree/view_inheritance_resolver_3-0

    January 27th, 2010 @ 04:16 PM

  31. Rizwan Reza
    Rizwan Reza

    Good job! Looks pretty nice so far. I will show this to Yehuda whenever (or wherever) I find him! :)

    January 27th, 2010 @ 04:25 PM

  32. artemave
    artemave
    in_regards_to 'rails 3.0 beta release' do
      with :all_the_respect { artemave.says('Thanks for ignoring me').to($rails_team) }
    end
    

    February 5th, 2010 @ 09:18 PM

  33. artemave
    artemave

    Few changes:

    • moved calculating parent controllers to AbstractController::Base
    • rebased against latest master

    http://github.com/artemave/rails/tree/view_inheritance_resolver_3-0

    February 9th, 2010 @ 04:50 PM

  34. artemave
    artemave

    Can someone please reassign this ticket to someone who actually has time to deal with it? Seriously.

    February 25th, 2010 @ 08:33 PM

  35. Caio Chassot
    Caio Chassot

    Maybe if carl types merge and yehuda types push, they can get it done this year. :P

    March 3rd, 2010 @ 02:16 AM

  36. Yehuda Katz (wycats)
    Yehuda Katz (wycats)

    Hey guys,

    Not sure if you've been paying attention to master, but we've been making some changes to ActionController and ActionView, specifically around the Resolver. Currently, there are too many paths that result in template lookup, making patches like this far more complex than they should be.

    We've been working on refactoring this part of the code with the express intention of making it trivial to implement this feature (without needing as much code as is in this patch). Part of that work involved reducing global state with the intention of removing AV's direct dependency on AC for much of what it does. Again, you can follow that progress on master.

    In short, I haven't pulled this patch because it exposed a problem with our current architecture that Carl and I wanted to fix the right way.

    As I've said before, this feature is desired. We're actively working on it (again, see master), and we're going to get it in properly.

    March 5th, 2010 @ 04:01 PM

  37. artemave
    artemave

    Thanks for status update. It certainly cleared up the picture.

    I am therefor waiting til you guys finish up fighting global state. And there we'll see what is next.

    March 6th, 2010 @ 10:30 AM

  38. Neil Smith
    Neil Smith

    Please can anyone advise of the status of this issue? Did the relevant refactoring take place? It would be great to use this feature (or something very similar) in Rails 3.

    May 19th, 2010 @ 12:15 AM

  39. Jeremy Kemper
  40. artemave
  41. gnufied
    gnufied

    +1 from Me. But it should be opt-in.

    September 27th, 2010 @ 07:10 PM

  42. artemave
    artemave

    Good point, I believe this fixes it github.com/artemave/rails/commit/f9b87450b2d5bde0177502c5b5bba2761e3b96a4

    October 1st, 2010 @ 06:58 PM

  43. Jeremy Kemper
  44. Santiago Pastorino
  45. artemave
    artemave

    Rebased against current master. Again. https://github.com/artemave/rails/tree/view_inheritance

    Can someone from rails team respond/review, please?

    December 19th, 2010 @ 04:01 PM

  46. José Valim
    José Valim
    • Milestone set to 3.1
    • State changed from open to resolved
    • Importance changed from to Low

    December 27th, 2010 @ 07:06 PM

  47. TuteC
    TuteC

    I can't make it work on Rails 3.0.5, neither adding 'config.template_inheritance = true' to my application.rb file. Is it published on Rails 3.0, or will it be in 3.1?

    April 2nd, 2011 @ 09:29 PM

  48. José Valim
    José Valim

    As the milestone says, 3.1.

    April 2nd, 2011 @ 09:32 PM