Adding Tabs to Your Rails App Just Got a Whole Lot Easier with Tabulous 2

The tabulous gem has continued to grow in popularity ever since I released it in 2011. Since so many people have found it useful, I decided to give it some love. Tabulous 2 is a complete rewrite, featuring a simpler syntax and new behavior.

Tabulous is designed to be perfect for quick prototyping, robust enough for production use, and flexible enough to grow with your app. I hope that many people find it useful enough to make it a permanent part of their Ruby on Rails toolbox.

Check out the sweet new syntax:

Tabulous.setup do
 
  tabs do
    pictures_tab do
      text          { 'Pictures' }
      link_path     { pictures_path }
      visible_when  { true }
      enabled_when  { true }
      active_when   { in_action('any').of_controller('pictures') }
    end
 
    music_tab do
      text          { 'Music' }
      link_path     { songs_path }
      visible_when  { true }
      enabled_when  { current_user.has_music? }
      active_when   { in_action('any').of_controller('songs') }
    end
 
    profile_tab do
      text          { 'My Profile' }
      link_path     { account_path(current_user) }
      visible_when  { true }
      enabled_when  { true }
      active_when   { in_actions('show', 'edit', 'update').of_controller('accounts') }
    end
  end
 
end

I abandoned the old syntax because:

  • Tabulous became popular enough that a syntax more in line with the typical conventions of Ruby and Rails programming would be more appropriate.
  • A fair amount of newbies were using tabulous. Experimental, boundary-pushing syntax is not appropriate for beginners as it may confuse their tastes in what constitutes good software design.
  • Developers had mixed feelings about the syntax. Some liked it, some hated it. No one loved it.

If you are using a version of tabulous older than 2.0.0, then you’ll have to manually update your code. Don’t worry, tabulous 1.3.2 works with Rails 4, so you don’t have to upgrade soon. But keep in mind that the old syntax will no longer be supported.

Check out the README on GitHub for the full story on tabulous 2.

Happy tabbing!

You can skip to the end and leave a response. Pinging is currently not allowed.

9 Responses to “Adding Tabs to Your Rails App Just Got a Whole Lot Easier with Tabulous 2”

  1. Jan Brdo says:

    Just wanted to note that using instance_eval like that is not always good. For example if I define a local variable text somewhere at the top of that file, there will be errors. I guess in this case it’s fine as it’s unlikely that anyone would do that, but it’s important to be aware of the problem. For example if you are designing a DSL that is meant to be used together with other code then it’s probably better to yield something into the block and use that instead of instance_eval-ing the block.

  2. techiferous says:

    @Jan

    Thanks for commenting! Local variables are not problematic with the use of instance_exec; instance_exec can see them and use them. Even if you created a local variable named “text”, you can still reference it inside the text block without a problem. The only thing problematic I can think of is that if you define a method, you can’t see that from within the block, which I guess is your point in mentioning “a DSL that is meant to be used together with other code”.

    I just want to point out to other readers that you should not define local variables or methods within the tabulous.rb file; that’s not how it’s meant to be used. If you need to define a method, create a helper; it will be visible from within tabulous.rb.

  3. Kelli says:

    Ooh, you didn’t tell me you’d finished this! Congrats on getting the rewrite out there. The new syntax looks nice. :)

  4. Jacob says:

    Howdy, love the rewrite, but I’m having a problem with the new DSL that I was able to accomplish with the old syntax.

    I have a main Tab, with Subtabs that are actual links to items, i.e.:
    cars_tab -> cars_path
    mustang_subtab -> car_path(mustang)
    corvette_subtab -> car_path(corvette)

    I’m pretty stumped on how to create these subtabs since they are being read through ‘method_missing’.

    Thanks for any help!
    -Jacob

  5. techiferous says:

    @Jacob

    Thanks for the question and trying out the new DSL! Sorry you’re having problems with it. Are you saying that the subtabs are created dynamically? I’m having trouble fully understanding your use case.

    If you could continue this discussion by opening a GitHub issue, that’d be great, since I get emailed whenever an issue is created and commented on:

    https://github.com/techiferous/tabulous/issues

  6. shyamkkhadka says:

    How can we make same tab available for two different controllers ?
    For example in your example

        music_tab do
          text          { 'Music' }
          link_path     { songs_path }
          visible_when  { true }
          enabled_when  { current_user.has_music? }
          active_when   { in_action('any').of_controller('songs') }
        end

    I want to have same tab (music_tab) for other controller as well say (‘movies’).

    So I want something like

        music_tab do
          text          { 'Music' }
          link_path     { songs_path }
          visible_when  { true }
          enabled_when  { current_user.has_music? }
          active_when   { in_action('any').of_controller('songs') | of_controller('movies' }
        end

    How can we achieve this ?

  7. techiferous says:

    Like this:

        music_tab do
          text          { 'Music' }
          link_path     { songs_path }
          visible_when  { true }
          enabled_when  { current_user.has_music? }
          active_when do
            in_action('any').of_controller('songs')
            in_action('any').of_controller('movies')
          end
        end

    More details here.

  8. Gerry P says:

    Is there any way to detect a tab load via javascript? That is, are there any events associated with tab show/hide?

  9. techiferous says:

    Gerry,

    A tab load is the same as navigating to a new URL, so you would detect it using JavaScript in the same way as you would clicking a link.

    Based on your question, though, I’m thinking you may be using the wrong tool for the job. Tabulous is not a JavaScript tabs solution like jQueryUI tabs or tabulous.js.

Leave a Reply