middleman/middleman — pull request #1307 by tdreyno (2014-06-28 22:15:41+00:00)
Title: Collections

This is a WIP feature/PR for tracking the concept of "Collections" which is being extracted from Middleman Blog and brought into core. Some code may be shared, but it's more likely this will be a rewrite.

The API in this PR currently looks like this:

```
collect :articles,
where: proc { |resource|
uri_match resource.url, 'blog/{year}-{month}-{day}-{title}.html'
}

collect :tags,
where: proc { |resource|
resource.data.tags
},
group_by: proc { |resource|
if resource.data.tags.is_a? String
resource.data.tags.split(',').map(&:strip)
else
resource.data.tags
end
}
```

The first example allows the user to create a named collection and simply `filter` the sitemap. Collections are kept up-to-date with Sitemap changes. Eventually, we will move the collection-specific helpers from Blog over to build things like automatic paging and sorting into collections.

From a template, the first collection would be used like so:

```
<% collected.articles.each do |article| %>

<%= article.data.title %>
<%= article.data.date.strftime('%b %e') %>

<% end %>
```

The second example adds another key to create a collection of collections. In this case, it looks at articles it thinks are blog posts, pulls out the tags and makes an array for each unique match. From the template:

```
<% collected[:tags].each do |k, items| %>

<%= k %>
<% items.each do |article| %>
<%= article.data.title %>
<% end %>

<% end %>
```

Right now this is the only API. The next step will be to provide some sugar over directly using `Proc`s.

I'd love some feedback, not really on the code yet, but on the flexibility of the approach. I spoke with @pulletsforever the other day and realized the API had originally imagines wouldn't be nearly powerful enough for his needs. Starting from the bottom like this will let power users be very specific, but we can add nicer looking APIs on top later.

Thoughts? @bhollis @karlfreeman