typo iconrails icon

Adding a TOC to Typo

Posted in , , Mon, 26 Jun 2006 21:37:00 GMT

I've been using MediaWiki for a while and wanted its ability to auto-generate Table of contents for pages with multiple articles such as the homepage and the category pages. Typo is a Ruby on Rails app so you'll need to be somewhat familiar with it to make enhancments. I have this running on Typo 4.1.1, 4.0.0 r1188 and 2.6.0.

I came up with the following but it's still in the early stages:

  1. Add name attribute to article links: We want to add the HTML name attribute to the article links so we can anchor to them. To do this, edit the app/helpers/application_helper.rb file and modify the appropriate method shown below with the changes in highlighted.

    For Typo 4.1.1:

    def link_to_permalink(item, title, anchor=nil, name=nil)
      anchor = "##{anchor}" if anchor
      name   = " name=\"#{name}\"" if name
      "<a href=\"#{item.permalink_url}#{anchor}\"#{name}>#{title}</a>"
    end

    For Typo 4.0.0:

    def item_link(title, item, anchor=nil)
      if item.is_a?(Article) && anchor != 'comments'
      && anchor != 'trackbacks'
        link_to title, item.location(anchor), :name => item.id
      else
        link_to title, item.location(anchor)
      end
    end

    For Typo 2.6.0:

    def article_link(title, article, anchor=nil)
      link_to title, article_url(article,true,anchor),
        :name => article.id
    end

    For Typo 4.1.1, you will also need to edit the app/views/articles/index.rhtml file and make the following modification:

    <%= link_to_permalink article,article.title,nil,article.id %>
  2. Add TOC template: I decided to create a separate template to handle the TOC. I used the following file name:

    app/views/articles/_articles_toc.rhtml

    which consists of the following (I didn't use link_to because the uri is only the article.id):

    <div id="articles_toc"><p>Table of Contents</p>
      <ul>
      <% for article in @articles -%>
        <li>
          <a href="#<%= article.id %>">
            <%= article.title %>
          </a>
        </li>
      <% end -%>
      </ul>
    </div>
  3. Call the TOC template: To call the TOC template from index.rhtml, add the following at the top of app/views/articles/index.rhtml

    <%= render_partial "articles_toc" %>
  4. Style with CSS: You'll probably want to style the TOC using CSS. Since the TOC feature is a hack it may be easier to put it in a supplementary CSS file so it won't get overwritten when you switch themes.
  5. TODO - Admin Console: To make this a full-fledged enhancement, there should be a toggle in the admin console to turn the TOC on and off. Right now this also shows the list for the index and category pages even when there's just one article on the page. It may be worthwhile to configure a mininum number of articles before the TOC is displayed.

I'll run this on this blog for now since I like having a quick way to see the list of articles on the page.

UPDATE 1: I added the number of comments to the existing TOC here. You can get the number of comments by using article.comments.length.

UPDATE 2: I also looked at turning this into a sidebar plugin by using the bundled 2.6.0 plugins as examples. It seems that the sidebars are components and have their own context so they may not be able to access @articles in the action context. I'll either have to query articles a second time, which I'm loathe to do, or write it in JS and then do a JS sidebar rendering. It would be nice if the sidebar shared or could access the primary context.

UPDATE 2.1: After looking at layouts/default.rhtml I think it may be possible to pass @articles to the sidebar by adding it to:

<%= render_component(:controller=>'sidebars/sidebar'

default.rhtml gets @content_for_layout, not @articles, so some testing is needed.

UPDATE 3: I was running the Lucid theme here before but I had problems with anchors in that articles and sidebar content above the selected anchor wouldn't render when an anchor was selected. I've switched back to Azure for now.

del.icio.us:Adding a TOC to Typo digg:Adding a TOC to Typo reddit:Adding a TOC to Typo spurl:Adding a TOC to Typo wists:Adding a TOC to Typo simpy:Adding a TOC to Typo newsvine:Adding a TOC to Typo blinklist:Adding a TOC to Typo furl:Adding a TOC to Typo fark:Adding a TOC to Typo blogmarks:Adding a TOC to Typo Y!:Adding a TOC to Typo smarking:Adding a TOC to Typo magnolia:Adding a TOC to Typo segnalo:Adding a TOC to Typo

20 comments

Comments

  1. Ajay said about 23 hours later:

    This might work best as a sidebar, though it would be better if you could turn the TOC sidebar off when an individual post is being viewed and I don’t know if that’s possible using the sidebar API. Why’d you go back to the default Azure theme?

  2. John Wang said 1 day later:

    Making it a sidebar is a good idea. I’m going to look at turning it a standard plugin soon and all the 2.6.0 plugins (examples) are sidebars. The other nice thing is that it won’t need any additional CSS. I switched back to Azure because I didn’t have time to create a nice TOC CSS header for Lucid but I also discovered that an issue where articles and sidebar content above the anchor wouldn’t get rendered with Lucid – strange.

    I think it should be easy to turn it off when an individual post is being viewed but I need to look into it some more. Hopefully it can be done in just the templates as opposed to controllers or other files.

  3. Dan said 14 days later:

    I attempted to integrate your TOC into my blog and followed every step but when I bring up my blog it has the following above the articles:

    ../themes/azure/views../../themes/azure/views.

    Its not rendering properly, any ideas?

    -Dan

  4. John Wang said 15 days later:

    Dan,

    That seems a bit strange. I’m not sure why it would be looking for a file in themes/azure. Are you sure you’re putting the file in the right directory? The _articles_toc.rhtml file should be in the same directory that contains index.rhtml and _article.rhtml. For me the files are in app/views/articles (nothing to do with any theme). In the below, the first two files should already exist, just add the third.

    app/views/articles/index.rhtml
    app/views/articles/_article.rhtml
    app/views/articles/_articles_toc.rhtml

    In the index.rhtml file you should see the following at the top which displays each article by including the _article.rhtml file per article:

    &lt;% for article in @articles -%&gt;
     &lt;div class="post"&gt;
      &lt;%= render_partial "article", article %&gt;

    If you can view articles on your blog homepage then it means index.rhtml can find _article.rhtml. Adding the following to the top of index.rhtml should work exactly the same way, i.e. it should find and include the template that happens to be in the same views directory:

    &lt;%= render_partial "articles_toc" %&gt;

    Let me know if this helps.

  5. Dan said 15 days later:

    Well, I was able to get it to do the render partial stuff….but then the hyperlinks in the TOC would not jump down to the articles. I copied your _articles_toc.rhtml exactly and it wouldn’t work. I wonder if you have any other modifications in _article.rhtml that might be needed.

    Can you post the contents of your modified _articles.rhtml file?

  6. John Wang said 15 days later:

    Dan,

    The two things you need to make it jump:

    1. The HTML name attribute set in the article title link. Did you edit the article_link method in the application_helper.rb file as shown in step 1?
    2. The second thing you need is to make sure the TOC links are going to the anchors. Are the link href’s in the TOC being set to href=”#<article_id>” where <article_id> is a number?
  7. Dan said 15 days later:

    John,

    I used your code:

    &lt;div id="articles_toc"&gt;&lt;p&gt;Table of Contents&lt;/p&gt;
      &lt;ul&gt;
      &lt;% for article in @articles -%&gt;
        &lt;li&gt;
          &lt;a href="#&lt;%= article.id %&gt;"&gt;
            &lt;%= article.title %&gt;
          &lt;/a&gt;
        &lt;/li&gt;
      &lt;% end -%&gt;
      &lt;/ul&gt;
    &lt;/div&gt;

    And I saved it as _articles_toc.rhtml. Is there anything missing in the code that is currently in use on this blog?

    Edited by Dev411: fix formatting.

  8. Dan said 15 days later:

    Well, I guess the code doesn’t want to show up in my previous comment…Anyways, I did notice that in your comment you have it as article_id, is it supposed to be article_id or article.id in the href code in _articles_toc.html?

  9. John Wang said 15 days later:

    In the rhtml it’s supposed to be <%= article.id %>, I just used article_id to indicate it’s supposed to be a literal number.

    Do you have an install where this is running that I can look at as a user to see what’s being rendered? Also, can you post the relevant files on a server somewhere for me to take a look?

    In the _articles_toc.rhtml file, try something simlple like the following to see if you’re getting the articles and the TOC file is being rendered:

    &lt;% for article in @articles -%&gt;
      &lt;%= article.title %&gt;
    &lt;% end -%&gt;
  10. Dan said 15 days later:

    Unfortunately by tinkering with the application code on my blog it created an application error and I can’t access the admin side of my typo site anymore, it basically just blew up. So I now have a support ticket in with my hosting company. I luckily have a backup of my site before the code changes. I’m crossing my fingers and hoping it comes back up.

  11. Dan Cote said 20 days later:

    Are you using version 2.6.0 of Typo or the most recent version which is 3.99? I’m working off of 2.6.0 which might be why your code is not working in my version of typo.

  12. John Wang said 21 days later:

    I have this running on 2.6.0. Do you have this running on server I can look at as an end user? The changes are very simple and I’m curious to see what is and isn’t showing up in the HTML, namely:

    1) Is the name attribute being added to the article titles

    2) Is the _articles_toc.rhtml header being shown, i.e. is it just not getting _articles_toc.rhtml or is @articles not being retrieved

    I assume you’ve restarted the server after making the change to the application_helper.rb file?

  13. Dan Cote said 24 days later:

    John,

    Check out http://mlsanswers.tampabayrealtor.com. The site has been reset to a fresh install of typo and then I’ve implemented your code. If you can give me your email address I’ll give you access to the server to take a look at the code. I’d rather not put the username/password on this comment posting.

    -Dan

  14. John Wang said 25 days later:

    I’m not sure why it would be doing that. Email me at

    johncwang at gmail dot com

    and I’ll take a look.

  15. Dan Cote said 27 days later:

    Ok, I’ve sent you an email with all the pertinent info.

    thanks,

    Dan

  16. John Wang said 28 days later:

    A general note: Dan’s issue has been resolved. There was a name mismatch between the toc template and the file index.rhtml file was trying to include.

  17. Ansgar Berhorn said 3 months later:

    The approach is working fine. Thanks for the useful idea.

    If a theme comes with own view-controllers like scribbish, changes for 3. and 4. have to be placed in the theme:

    themes/THEME_NAME/views/articles/

    Overall I think this changes are better of in the theme than in the more generic view controllers of the application.

  18. John Wang said 3 months later:

    Ansgar: You’re right. These changes would be better off in the theme. I haven’t gotten around to it partly due to time and party due to the fact that a lot of things keep changing in Typo with every release. I’d certainly look into it once I think things have stabilized with Typo.

  19. Anton said 4 months later:

    I think there’s some magic from routes.rb that I’m missing out on.

    I get the list from _articles_toc.rhtml rendered OK, but the link doesn’t lead to the article. It comes out as http://hostname.com/#number and that doens’t do anything.

    I’m still experimenting and by the time you read this I may have figured it out, but you can see this in action with the dual aidebar theme – which is based on scribblish – at http://antonaylward.com

  20. John Wang said 11 months later:

    Anton has already solved his issue but I figure I’ll respond just for the sake of completeness. The TOC isn’t designed to link to the article permalink page, it’s designed to take you to the article on the same page. This way a user can quickly jump to the article and see if it’s interesting without having to load another page with the associated HTTP connection delay.

    To link to the individual article permalink page instead, just look in _article.rhtml for the code that creates the permalink (which changes depending on the Typo version).

(leave url/email »)

   Comment Markup Help Preview comment