middleman / middleman-blog

Blog Engine Extension for Middleman
https://middlemanapp.com
MIT License
325 stars 179 forks source link

Custom Collections feature fails if a blog article lacks the associated property #192

Closed dhemery closed 10 years ago

dhemery commented 10 years ago

I can't figure out how to make custom collections work.

Here is the relevant section of my config.rb:

blog.custom_collections = {
  topic: {
    link: 'topic/:topic/index.html',
    template: 'topics.html'
  }
}

Any idea what I'm doing wrong?

Here is the gist, including config.rb, stack trace, and version info about OS, ruby, and gems: https://gist.github.com/dhemery/8326598

Failure

middleman fails to build.

I've included a sample stack trace in the gist.

As far as I can tell, the problem is that the property value sent to safe_parameterize is nil.

Additional details

I do have a topics.haml file in my source directory.

Not all of my posts have a topic property in their front matter.

What I have tried

I have tried each of these, with no effect:

  1. Changing the link line in config.rb to: link: 'topic/{topic}/index.html'.
  2. Renaming my template file to topics.html.haml.
lolmaus commented 10 years ago

I think you should put the error message into issue title.

dhemery commented 10 years ago

Done.

dhemery commented 10 years ago

Okay, I've narrowed down the problem. It appears that the custom collections feature requires that every blog article include the associated metadata property. If every article has the property, the feature works. If any article lacks the property, the feature throws, as described in the gist.

I consider this a defect. I suspect that not everyone will consider it a defect.

tdreyno commented 10 years ago

Thanks @dhemery, this is a very new feature, so it's definitely got some rough edges. We'll provide better errors, and in this case, probably just ignore articles without the property.

bhollis commented 10 years ago

Yeah, this is something we definitely want to fix. I'll see about reproducing the bug and then fix it up.

bhollis commented 10 years ago

I'm sorry, I just haven't had much time to work on middleman-blog recently. The one thing that takes bugs like this from being a lot of work for me to being a quick and easy fix is a minimal middleman project that reproduces the problem. @dhemery, would you be able to provide such a thing?

dhemery commented 10 years ago

Alas, my motivation is lower now.

My goal at the time was to have both tags and categories on my blog posts, and to allow for posts to omit tags. I've since decided that trying to distinguish tags from categories was not worth the mental effort, and I now use only tags.

So I currently don't have a need for the feature. And I am not eager to fiddle further with website/blog code right now.

Middleman and the blog plugin made my work as easy and pleasant as it could be. But I've had enough of that for a while.

Refactored commented 10 years ago

I also want categories and tags. Using what @dhemery posted I was able to at least get a "topics" page to work using the following (in config.rb):

blog.custom_collections = {
    topic: {
      link: 'topics/{topic}.html',
      template: 'topic.html'
    }
  }

However I'm trying to now provide a categories list. I started by cloning the "tags" block from layout.erb and edited it as such:

<h2>Topics</h2>
<ol>
    <% blog.topics.each do |topic, articles| %>
      <li><%= link_to topic, tag_path(topic) %> (<%= articles.size %>)</a></li>
    <% end %>
</ol>

But when I load the site I get the following error:

NoMethodError at /
undefined method `topics' for #<Middleman::Blog::BlogData:0x007f84592a6590>

I'm certain I'm just missing something in my code but don't know what.

bhollis commented 10 years ago

There is no blog.topics method. There is no helper like tags to get all the unique values. But you can do it yourself:

<% topics = blog.articles.group_by {|a| a.metadata[:page]['topic'] }%>
<h2>Topics</h2>
<ol>
    <% topics.each do |topic, articles| %>
      <li><%= link_to topic, tag_path(topic) %> (<%= articles.size %>)</a></li>
    <% end %>
</ol>

I have some ideas on how to make this sort of stuff easier, but I don't really have time to do anything with them.

bhollis commented 10 years ago

Fixed on master.