cloudhead / toto

the 10 second blog-engine for hackers
MIT License
1.49k stars 245 forks source link

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

Closed benjamincharity closed 12 years ago

benjamincharity commented 13 years ago

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 13 years ago

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 %>
benjamincharity commented 13 years ago

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

lyslim commented 13 years ago

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 13 years ago

@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 13 years ago

@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`.

benjamincharity commented 12 years ago

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!)

sscarduzio commented 12 years ago

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