Adding a TOC to Typo
Posted in typo, hacks, rails 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:
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 %>
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>
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" %>
- 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.
- 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.
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?
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.
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
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.
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:
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:
Let me know if this helps.
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?
Dan,
The two things you need to make it jump:
John,
I used your code:
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.
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?
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:
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.
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.
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?
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
I’m not sure why it would be doing that. Email me at
johncwang at gmail dot com
and I’ll take a look.
Ok, I’ve sent you an email with all the pertinent info.
thanks,
Dan
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.
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.
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.
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 ashttp://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
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).