cloudhead/toto

Is there a way to pull in some archives on an article page?

Closed this issue · 7 comments

Basically wanting to pull in last seven articles into a sidebar.

I was trying something like:

%ol
  - unless archives.empty?
    - archives[0..6].each do |archive|
      %li
        %a{:href => "#{ archive.path }"}= archive.title

but apparently 'archives' isn't accessible outside the archives template? Anyone have a way around this (I'm still pretty new to Ruby and Toto, so my apologies if this is right in front of me!)

Thanks

ixti commented

In fact both Archives and Article are running in the Context. And Context has @articles property, so you can do something like this:

<% unless @artiles.empty? %>
<ol>
  <% @articles[0..6].each do |a| %>
  <li><a href="<%= a.url %>"><%= a.title %></a></li>
  <% end %>
</ol>
<% end %>

Hmm I tried:

%article.archives
  %h1 Archives
  %ol
    - unless @articles.empty?
      - articles[0..6].each do |a|
        %li
          %a{:href => "#{ a.url }"}= a.title

And it's returning a NoMethodError:

NoMethodError at /2011/03/08/the-art-of-code/
undefined method `articles' for #Toto::Site::Context:0x007ffebab46c78

I believe archives can only be used under route root or say index, guess this could only be changed if u hacking the gem... So here's my workaround:

<% if @path == '/'%>
<%archives.......%>
<%end%>

Let archives displays in sidebar only when it is on page index. Cheers.

ixti commented

@benjamincharity yes, that's true! there's no such method articles of Toto::Site::Context, but there's property @articles. You are checking property iin the condition unless @articles.empty?, but then tries access method further articles[0..6].

Correct variant for you should be:

%article.archives
  %h1 Archives
  %ol
    - unless @articles.empty?
      - @articles[0..6].each do |a|
        %li
          %a{:href => "#{ a.url }"}= a.title

Alternatively you can extend Toto in config.ru rackup file like this:

module Toto
  class Site
    class Context
      attr_reader :articles
    end
  end
end

In this case you'll be able to access @articles as articles :))

UPDATE I'm not familiar with HAML, but I believe that this line:

%a{:href => "#{ a.url }"}= a.title

Can be written as

%a{:href => a.url}= a.title
ixti commented

@lyslim you are partially right :)) Except few mistakes :))

Everything (except direct pages) are running in the Toto::Site::Context which stores whole array of all articles as @articles property. So you can access @articles property anywhere. For more details refer to the go method of Toto::Site: https://github.com/cloudhead/toto/blob/master/lib/toto.rb#L100

So as you can see, any request is being processed under Context class. So you can see it's contructor and find @articles property: https://github.com/cloudhead/toto/blob/master/lib/toto.rb#L154

On the other and, archives is really accessible on archives and index pages only, refer to go method to see why (this property is assigned only in few places`.

Ahh thank you all for your help! Still very new to all of this but I'm loving it!

@ixti, your fix worked well! (and kudos on the haml link syntax; much cleaner!)

Thanks everybody, but hey, his worked much better for me:

  • show just posts dated in the past (enable scheduled posts),

  • use .path instead of .url so it doesn't break my dev webserver :9292 special port,

  • fixed a typo in the paste of ixti,

  • Unordered list tag instead of Ordered list tag.

      <% unless @articles.empty? %>
          <ul>
            <% @articles[0..6].select {|a| a[:date] <= Date.today}.each do |a| %>
            <li><a href="<%= a.path %>"><%= a.title %></a></li>
            <% end %>
          </ul>
       <% end %>