Merge pull request #195 from substantial/refactor_archive_widget

Refactor archive widget
This commit is contained in:
Philip Arndt 2012-02-22 23:43:01 -08:00
commit f82d2c96e4
5 changed files with 148 additions and 55 deletions

View file

@ -1,14 +1,6 @@
module Refinery module Refinery
module Blog module Blog
module PostsHelper module PostsHelper
def blog_archive_widget
posts = Refinery::Blog::Post.select('published_at').all_previous
return nil if posts.blank?
render :partial => "/refinery/blog/widgets/blog_archive", :locals => { :posts => posts }
end
alias_method :blog_archive_list, :blog_archive_widget
def next_or_previous?(post) def next_or_previous?(post)
post.next.present? or post.prev.present? post.next.present? or post.prev.present?
end end
@ -28,22 +20,51 @@ module Refinery
end end
end end
def archive_link(post) def blog_archive_widget(dates=blog_archive_dates)
if post.published_at >= Time.now.end_of_year.advance(:years => -3) ArchiveWidget.new(dates, self).display
post_date = post.published_at.strftime('%m/%Y') end
year = post_date.split('/')[1]
month = post_date.split('/')[0]
count = Blog::Post.by_archive(Time.parse(post_date)).size
text = t("date.month_names")[month.to_i] + " #{year} (#{count})"
link_to(text, refinery.blog_archive_posts_path(:year => year, :month => month)) def blog_archive_dates(cutoff=Time.now.beginning_of_month)
else Refinery::Blog::Post.published_dates_older_than(cutoff)
post_date = post.published_at.strftime('01/%Y') end
year = post_date.split('/')[1]
count = Refinery::Blog::Post.by_year(Time.parse(post_date)).size
text = "#{year} (#{count})"
link_to(text, refinery.blog_archive_posts_path(:year => year)) class ArchiveWidget
delegate :t, :link_to, :refinery, :render, :to => :view_context
attr_reader :view_context
def initialize(dates, view_context, cutoff=3.years.ago.end_of_year)
@recent_dates, @old_dates = dates.sort_by {|date| -date.to_i }.
partition {|date| date > cutoff }
@view_context = view_context
end
def recent_links
@recent_dates.group_by {|date| [date.year, date.month] }.
map {|(year, month), dates| recent_link(year, month, dates.count) }
end
def recent_link(year, month, count)
link_to "#{t("date.month_names")[month]} #{year} (#{count})",
refinery.blog_archive_posts_path(:year => year, :month => month)
end
def old_links
@old_dates.group_by {|date| date.year }.
map {|year, dates| old_link(year, dates.size) }
end
def old_link(year, count)
link_to "#{year} (#{count})", refinery.blog_archive_posts_path(:year => year)
end
def links
recent_links + old_links
end
def display
return "" if links.empty?
render "refinery/blog/widgets/blog_archive", :links => links
end end
end end
end end

View file

@ -63,16 +63,16 @@ module Refinery
end end
class << self class << self
def by_archive(archive_date) def by_archive(date)
where(['published_at between ? and ?', archive_date.beginning_of_month, archive_date.end_of_month]) where(:published_at => date.beginning_of_month..date.end_of_month)
end end
def by_year(archive_year) def by_year(date)
where(['published_at between ? and ?', archive_year.beginning_of_year, archive_year.end_of_year]) where(:published_at => date.beginning_of_year..date.end_of_year)
end end
def all_previous def published_dates_older_than(date)
where(['published_at <= ?', Time.now.beginning_of_month]) where("published_at <= ?", date).map(&:published_at)
end end
def live def live

View file

@ -2,9 +2,9 @@
<h2><%= t('archives', :scope => 'refinery.blog.shared') %></h2> <h2><%= t('archives', :scope => 'refinery.blog.shared') %></h2>
<nav> <nav>
<ul> <ul>
<% posts.each do |post| %> <% links.each do |link| %>
<li><%= archive_link(post) %></li> <li><%= link %></li>
<% end %> <% end %>
</ul> </ul>
</nav> </nav>
</section> </section>

View file

@ -0,0 +1,71 @@
require 'spec_helper'
module Refinery
module Blog
describe PostsHelper do
describe "#blog_archive_widget" do
let(:html) { helper.blog_archive_widget(dates) }
let(:links) { Capybara.string(html).find("#blog_archive_widget ul") }
context "with no archive dates" do
let(:dates) { [] }
it "does not display anything" do
html.should be_blank
end
end
context "with archive dates" do
let(:recent_post) { 2.months.ago }
let(:old_post) { 4.years.ago }
let(:dates) do
[old_post, recent_post].map do |date|
[date, date.beginning_of_month, date.end_of_month]
end.flatten
end
it "has a link for the month of dates not older than one year" do
month = Date::MONTHNAMES[recent_post.month]
year = recent_post.year
links.should have_link("#{month} #{year} (3)")
end
it "has a link for the year of dates older than one year" do
year = old_post.year
links.should have_link("#{year} (3)")
end
it "sorts recent links before old links" do
links.find("li:first").should have_content(recent_post.year.to_s)
links.find("li:last").should have_content(old_post.year.to_s)
end
end
context "with multiple recent dates" do
let(:dates) { [3.months.ago, 2.months.ago] }
it "sorts by the more recent date" do
first, second = dates.map {|p| Date::MONTHNAMES[p.month] }
links.find("li:first").should have_content(second)
links.find("li:last").should have_content(first)
end
end
context "with multiple old dates" do
let(:dates) { [5.years.ago, 4.years.ago] }
it "sorts by the more recent date" do
first, second = dates.map {|p| p.year.to_s }
links.find("li:first").should have_content(second)
links.find("li:last").should have_content(first)
end
end
end
end
end
end

View file

@ -49,11 +49,11 @@ module Refinery
describe "authors" do describe "authors" do
it "are authored" do it "are authored" do
subject.class.instance_methods.map(&:to_sym).should include(:author) described_class.instance_methods.map(&:to_sym).should include(:author)
end end
end end
describe "by_archive scope" do describe "by_archive" do
before do before do
@post1 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 11)) @post1 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 11))
@post2 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 12)) @post2 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 12))
@ -65,25 +65,26 @@ module Refinery
it "returns all posts from specified month" do it "returns all posts from specified month" do
#check for this month #check for this month
date = "03/2011" date = "03/2011"
subject.class.by_archive(Time.parse(date)).count.should be == 2 described_class.by_archive(Time.parse(date)).count.should be == 2
subject.class.by_archive(Time.parse(date)).should == [@post2, @post1] described_class.by_archive(Time.parse(date)).should == [@post2, @post1]
end end
end end
describe "all_previous scope" do describe ".published_dates_older_than" do
before do before do
@post1 = FactoryGirl.create(:blog_post, :published_at => Time.now - 2.months) @post1 = FactoryGirl.create(:blog_post, :published_at => Time.now - 2.months)
@post2 = FactoryGirl.create(:blog_post, :published_at => Time.now - 1.month) @post2 = FactoryGirl.create(:blog_post, :published_at => Time.now - 1.month)
FactoryGirl.create(:blog_post, :published_at => Time.now) FactoryGirl.create(:blog_post, :published_at => Time.now)
end end
it "returns all posts from previous months" do it "returns all published dates older than the argument" do
subject.class.all_previous.count.should be == 2 expected = [@post2.published_at, @post1.published_at]
subject.class.all_previous.should == [@post2, @post1]
described_class.published_dates_older_than(1.day.ago).should eq(expected)
end end
end end
describe "live scope" do describe "live" do
before do before do
@post1 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -2)) @post1 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -2))
@post2 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -1)) @post2 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -1))
@ -92,12 +93,12 @@ module Refinery
end end
it "returns all posts which aren't in draft and pub date isn't in future" do it "returns all posts which aren't in draft and pub date isn't in future" do
subject.class.live.count.should be == 2 described_class.live.count.should be == 2
subject.class.live.should == [@post2, @post1] described_class.live.should == [@post2, @post1]
end end
end end
describe "uncategorized scope" do describe "uncategorized" do
before do before do
@uncategorized_post = FactoryGirl.create(:blog_post) @uncategorized_post = FactoryGirl.create(:blog_post)
@categorized_post = FactoryGirl.create(:blog_post) @categorized_post = FactoryGirl.create(:blog_post)
@ -106,22 +107,22 @@ module Refinery
end end
it "returns uncategorized posts if they exist" do it "returns uncategorized posts if they exist" do
subject.class.uncategorized.should include @uncategorized_post described_class.uncategorized.should include @uncategorized_post
subject.class.uncategorized.should_not include @categorized_post described_class.uncategorized.should_not include @categorized_post
end end
end end
describe "#live?" do describe "#live?" do
it "returns true if post is not in draft and it's published" do it "returns true if post is not in draft and it's published" do
FactoryGirl.create(:blog_post).live?.should be_true Factory.build(:blog_post).should be_live
end end
it "returns false if post is in draft" do it "returns false if post is in draft" do
FactoryGirl.create(:blog_post, :draft => true).live?.should be_false Factory.build(:blog_post, :draft => true).should_not be_live
end end
it "returns false if post pub date is in future" do it "returns false if post pub date is in future" do
FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => 1)).live?.should be_false Factory.build(:blog_post, :published_at => Time.now.advance(:minutes => 1)).should_not be_live
end end
end end
@ -132,7 +133,7 @@ module Refinery
end end
it "returns next article when called on current article" do it "returns next article when called on current article" do
subject.class.last.next.should == @post described_class.last.next.should == @post
end end
end end
@ -143,7 +144,7 @@ module Refinery
end end
it "returns previous article when called on current article" do it "returns previous article when called on current article" do
subject.class.first.prev.should == @post described_class.first.prev.should == @post
end end
end end
@ -171,7 +172,7 @@ module Refinery
end end
it "should be true" do it "should be true" do
subject.class.comments_allowed?.should be_true described_class.comments_allowed?.should be_true
end end
end end
@ -181,7 +182,7 @@ module Refinery
end end
it "should be false" do it "should be false" do
subject.class.comments_allowed?.should be_false described_class.comments_allowed?.should be_false
end end
end end
end end
@ -199,7 +200,7 @@ module Refinery
end end
it "should be true" do it "should be true" do
subject.class.teasers_enabled?.should be_true described_class.teasers_enabled?.should be_true
end end
end end
@ -209,7 +210,7 @@ module Refinery
end end
it "should be false" do it "should be false" do
subject.class.teasers_enabled?.should be_false described_class.teasers_enabled?.should be_false
end end
end end
end end
@ -246,4 +247,4 @@ module Refinery
end end
end end
end end