noodall-articles 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +33 -0
  3. data/Rakefile +39 -0
  4. data/app/assets/javascripts/noodall-articles/categories.js +7 -0
  5. data/app/controllers/admin/categories_controller.rb +7 -0
  6. data/app/helpers/articles_helper.rb +126 -0
  7. data/app/models/article.rb +58 -0
  8. data/app/models/article_list.rb +49 -0
  9. data/app/models/latest_articles.rb +28 -0
  10. data/app/views/admin/components/_latest_articles.html.erb +21 -0
  11. data/app/views/admin/nodes/_article.html.erb +55 -0
  12. data/app/views/admin/nodes/_article_list.html.erb +45 -0
  13. data/app/views/application/_article_sidebar.html.erb +74 -0
  14. data/app/views/components/_latest_articles.html.erb +18 -0
  15. data/app/views/nodes/article.html.erb +31 -0
  16. data/app/views/nodes/article_list.html.erb +41 -0
  17. data/app/views/nodes/article_list.rss.builder +19 -0
  18. data/config/cucumber.yml +8 -0
  19. data/config/routes.rb +5 -0
  20. data/lib/generators/noodall/articles/views/USAGE +5 -0
  21. data/lib/generators/noodall/articles/views/views_generator.rb +7 -0
  22. data/lib/noodall/articles/archive.rb +56 -0
  23. data/lib/noodall/articles/categories.rb +39 -0
  24. data/lib/noodall/articles/custom_link_renderer.rb +25 -0
  25. data/lib/noodall/articles/engine.rb +9 -0
  26. data/lib/noodall/articles/version.rb +5 -0
  27. data/lib/noodall-articles.rb +1 -0
  28. data/lib/tasks/cucumber.rake +65 -0
  29. data/lib/tasks/noodall-articles_tasks.rake +4 -0
  30. data/test/dummy/Rakefile +7 -0
  31. data/test/dummy/app/assets/javascripts/application.js +9 -0
  32. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  33. data/test/dummy/app/controllers/application_controller.rb +26 -0
  34. data/test/dummy/app/helpers/application_helper.rb +2 -0
  35. data/test/dummy/app/models/content_page.rb +5 -0
  36. data/test/dummy/app/models/user.rb +31 -0
  37. data/test/dummy/app/views/admin/nodes/_content_page.html.erb +45 -0
  38. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  39. data/test/dummy/app/views/nodes/content_page.html.erb +6 -0
  40. data/test/dummy/config/application.rb +51 -0
  41. data/test/dummy/config/boot.rb +10 -0
  42. data/test/dummy/config/environment.rb +5 -0
  43. data/test/dummy/config/environments/development.rb +30 -0
  44. data/test/dummy/config/environments/production.rb +60 -0
  45. data/test/dummy/config/environments/test.rb +39 -0
  46. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  47. data/test/dummy/config/initializers/inflections.rb +10 -0
  48. data/test/dummy/config/initializers/mime_types.rb +5 -0
  49. data/test/dummy/config/initializers/noodall.rb +1 -0
  50. data/test/dummy/config/initializers/noodall_dragonfly.rb +8 -0
  51. data/test/dummy/config/initializers/secret_token.rb +7 -0
  52. data/test/dummy/config/initializers/session_store.rb +8 -0
  53. data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
  54. data/test/dummy/config/locales/en.yml +5 -0
  55. data/test/dummy/config/mongo.yml +6 -0
  56. data/test/dummy/config/routes.rb +9 -0
  57. data/test/dummy/config/sitemap.yml +6 -0
  58. data/test/dummy/config.ru +4 -0
  59. data/test/dummy/public/404.html +26 -0
  60. data/test/dummy/public/422.html +26 -0
  61. data/test/dummy/public/500.html +26 -0
  62. data/test/dummy/public/favicon.ico +0 -0
  63. data/test/dummy/script/rails +6 -0
  64. data/test/integration/navigation_test.rb +9 -0
  65. data/test/noodall-articles_test.rb +7 -0
  66. data/test/test_helper.rb +10 -0
  67. metadata +165 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Steve England
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,33 @@
1
+ # Noodall Articles
2
+
3
+ Noodall Articles adds simple blog functionality to Noodall.
4
+
5
+ ## Install
6
+
7
+ Add to your `Gemfile`
8
+
9
+ gem 'noodall-articles', :git => 'git@github.com:noodall/noodall-articles.git'
10
+
11
+ Run `bundle install`
12
+
13
+ bundle install
14
+
15
+ ## Configuration
16
+
17
+ Noodall Articles adds an `Article` and `ArticleList` Node to Noodall.
18
+
19
+ `ArticleList` is the classic blog listing page. `Article` is an individual blog post.
20
+
21
+ In `config/initializers/noodall.rb`
22
+
23
+ Add the `ArticleList` as a root template
24
+
25
+ Noodall::Node.root_templates ArticleList, ContentPage
26
+
27
+ Noodall Articles also adds a `LatestArticles` component which you can to your slots if required.
28
+
29
+ Noodall::Node.slot :large, LatestArticles
30
+ Noodall::Node.slot :small, LatestArticles
31
+
32
+ You can now create an `ArticleList` as your blog listing page and `Article` Nodes beneath it.
33
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'NoodallArticles'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rake/testtask'
30
+
31
+ Rake::TestTask.new(:test) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/**/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+
39
+ task :default => :test
@@ -0,0 +1,7 @@
1
+ function categoriesAutocomplete() {
2
+ formFieldAutocomplete('/admin/categories.json', "input.categories-completer");
3
+ };
4
+
5
+ $(function() {
6
+ categoriesAutocomplete();
7
+ });
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ class CategoriesController < ApplicationController
3
+ def index
4
+ render :json => Article.all_categories
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,126 @@
1
+ require 'noodall/articles/custom_link_renderer'
2
+
3
+ module ArticlesHelper
4
+ def paginated_articles(pagination_options = {}, &block)
5
+ options = { :per_page => 10, :page => params[:page] }
6
+
7
+ # Add search filters
8
+ options.merge!(build_query_from_params)
9
+
10
+ if params[:year]
11
+ if params[:month]
12
+ time = Time.zone.local(params[:year].to_i, params[:month].to_i, 1)
13
+ options[:published_at] = { :$gt => time.beginning_of_month, :$lt => time.end_of_month }
14
+ else
15
+ time = Time.zone.local(params[:year].to_i, 1, 1)
16
+ options[:published_at] = { :$gt => time.beginning_of_year, :$lt => time.end_of_year }
17
+ end
18
+ end
19
+ articles = @node.articles.paginate(options)
20
+
21
+ # Set default will_paginate options
22
+ paginated_section_options = {
23
+ :renderer => Noodall::Articles::CustomLinkRenderer,
24
+ :next_label => "Next",
25
+ :previous_label => "Previous",
26
+ :first_label => "First",
27
+ :last_label => "Last"
28
+ }
29
+
30
+ # Override any options passed in
31
+ paginated_section_options.merge!(pagination_options)
32
+ paginated_section(articles, paginated_section_options) { yield(articles) }.html_safe unless articles.empty?
33
+ end
34
+
35
+ def articles_rss_feed(node)
36
+ node.articles.all(build_query_from_params)
37
+ end
38
+
39
+ def articles_rss_feed_link(text, options = {})
40
+ link_to(text, articles_rss_feed_url, options)
41
+ end
42
+
43
+ def articles_rss_feed_url
44
+ querystring = build_querystring
45
+ querystring[:format] = :rss
46
+ node_path(@node.list, querystring)
47
+ end
48
+
49
+ def articles_rss_feed_auto_discovery
50
+ auto_discovery_link_tag(:rss, articles_rss_feed_url, :title => "Articles RSS Feed")
51
+ end
52
+
53
+ def link_to_next_article(label = 'Next')
54
+ if next_article = @node.articles.where(:position.gt => @node.position).first
55
+ link_to label, node_path(next_article), class: 'next_page'
56
+ else
57
+ content_tag :span, label, class: 'next_page disabled'
58
+ end
59
+ end
60
+
61
+ def link_to_previous_article(label = 'Previous')
62
+ if previous_article = @node.articles.where(:position.lt => @node.position).order('position DESC').first
63
+ link_to label, node_path(previous_article), class: 'previous_page'
64
+ else
65
+ content_tag :span, label, class: 'previous_page disabled'
66
+ end
67
+ end
68
+
69
+ def link_for_filter_text(text, node, current_filter)
70
+ querystring = build_querystring(current_filter)
71
+ content_tag(:li) do
72
+ link_to(text, node_path(node.list, querystring))
73
+ end
74
+ end
75
+
76
+ def link_for_year_filter(node, year)
77
+ querystring = build_querystring(:year => year.year)
78
+ link_to("#{year.year} <span>(#{year.total})</span>".html_safe, node_path(node.list, querystring))
79
+ end
80
+
81
+ def link_for_month_filter(node, year, month, count)
82
+ querystring = build_querystring(:year => year.year, :month => month + 1)
83
+ content_tag(:li,
84
+ link_to("#{t(:'date.month_names')[month+1]} <span>(#{count})</span>".html_safe, node_path(node.list, querystring))
85
+ ) unless count.zero?
86
+ end
87
+
88
+ def selected_filter(filter)
89
+ params[filter.downcase] || filter
90
+ end
91
+
92
+ def article_region(node)
93
+ node.regions.blank? ? "All Regions" : node.regions
94
+ end
95
+
96
+ def authors
97
+ User.where(tags: 'authors')
98
+ end
99
+
100
+ def author
101
+ User.first(permalink: params[:author]) if valid_filter?(params[:author])
102
+ end
103
+
104
+ protected
105
+
106
+ def build_query_from_params
107
+ query = {}
108
+ query[:categories] = params[:category] if valid_filter?(params[:category])
109
+ query[:creator_id] = author._id unless author.nil?
110
+ query
111
+ end
112
+
113
+ def build_querystring(current_filter = {})
114
+ querystring = {
115
+ category: params[:category],
116
+ author: params[:author],
117
+ year: params[:year],
118
+ month: params[:month]
119
+ }
120
+ querystring.merge!(current_filter)
121
+ end
122
+
123
+ def valid_filter?(filter)
124
+ !filter.blank? && filter != "All"
125
+ end
126
+ end
@@ -0,0 +1,58 @@
1
+ require 'noodall/articles/categories'
2
+
3
+ class Article < Noodall::Node
4
+ extend Noodall::Articles::Categories
5
+
6
+ delegate :list, :articles, :all_categories, :recent_articles, :archive, :to => :parent
7
+
8
+ key :categories, Array, :index => true
9
+
10
+ key :asset_id, ObjectId
11
+ belongs_to :asset
12
+
13
+ def category_list=(string)
14
+ self.categories = string.to_s.split(',').map{ |t| t.strip.titlecase }.reject(&:blank?).compact.uniq
15
+ end
16
+
17
+ def category_list
18
+ categories.join(',')
19
+ end
20
+
21
+ def related_articles
22
+ @related_articles ||= begin
23
+ siblings
24
+ .published
25
+ .order('published_date DESC')
26
+ .where(:tags => /(#{tags.join('|')})/i)
27
+ .limit(3)
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ # A slug for creating the permalink with date
34
+ def slug
35
+ (published_at || current_time).strftime('%Y/%m/%d/') + super
36
+ end
37
+
38
+ private
39
+
40
+ # Always put a new article at the top of a list
41
+ def set_position
42
+ write_attribute :position, 0 if self.position.blank?
43
+ end
44
+
45
+ # Parses body to find first image asset
46
+ def set_asset
47
+
48
+ # get all image assets
49
+ asset_ids = body.to_s.scan(%r|<img.*id="asset-([^"]*)".*/>|i)
50
+ if asset_ids.empty?
51
+ self.asset = nil
52
+ else
53
+ # remove prefix and file extension
54
+ self.asset = Asset.find_by_id(asset_ids.first.first.to_s)
55
+ end
56
+ end
57
+ before_save :set_asset
58
+ end
@@ -0,0 +1,49 @@
1
+ require 'noodall/articles/archive'
2
+ require 'noodall/articles/categories'
3
+
4
+ class ArticleList < Noodall::Node
5
+ include Noodall::Articles::Archive
6
+ include Noodall::Articles::Categories
7
+
8
+ sub_templates Article
9
+
10
+ def articles
11
+ children.published
12
+ end
13
+
14
+ def recent_articles(options = {})
15
+ options = remove_invalid_filters(options)
16
+ options[:order] = ['published_at DESC','created_at DESC']
17
+ children.published.limit(3).all(options)
18
+ end
19
+
20
+ def list
21
+ self
22
+ end
23
+
24
+ def all_categories
25
+ super(children.published.criteria.to_hash)
26
+ end
27
+
28
+ def archive(options = {})
29
+ options = remove_invalid_filters(options)
30
+
31
+ criteria = Plucky::CriteriaHash.new(
32
+ :path => self._id,
33
+ :_type => 'Article',
34
+ :published_at => { :$lte => Time.zone.now },
35
+ :published_to => { :$gte => Time.zone.now }
36
+ ).to_hash.merge(options)
37
+
38
+ result = self.collection.map_reduce(archive_map('published_at'), archive_reduce, {:query => criteria, :finalize => archive_finalize, :out => "tmp_articles"})
39
+ years = result.find.to_a.map{ |hash| Year.new(hash['_id'],hash['value']) }.sort{ |a,b| b.year <=> a.year }
40
+
41
+ years
42
+ end
43
+
44
+ private
45
+
46
+ def remove_invalid_filters(query)
47
+ query.reject {|key, value| value == "All" || value.blank? }
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ class LatestArticles < Noodall::Component
2
+
3
+ key :title, String, :default => "Latest Articles"
4
+
5
+ # Keys for filtering articles
6
+ key :category, String
7
+ key :article_list_id, ObjectId
8
+ belongs_to :article_list
9
+
10
+ # Returns a filtered list of latest articles
11
+ def articles
12
+ return [] if article_list.nil?
13
+ query = {
14
+ categories: category,
15
+ order: ['published_at DESC','created_at DESC']
16
+ }
17
+
18
+ # Remove any filters that are set to "All"
19
+ query.reject! {|key, value| value == "All" || value.blank? }
20
+
21
+ article_list.children.published.limit(3).all(query)
22
+ end
23
+
24
+ def categories
25
+ Article.all_categories
26
+ end
27
+
28
+ end
@@ -0,0 +1,21 @@
1
+ <%= fields_for :node do |n| %>
2
+ <%= n.fields_for slot_name, component do |f| %>
3
+ <%= f.hidden_field :_type %>
4
+
5
+ <p>
6
+ <%= f.label :title %><br/>
7
+ <span class="input-wrap"><%= f.text_field :title %></span>
8
+ </p>
9
+
10
+ <p>
11
+ <%= f.label :article_list_id %><br/>
12
+ <span class="input-wrap"><%= f.collection_select :article_list_id, ArticleList.published.all, :id, :name, :prompt => 'Choose an Article List' %></span>
13
+ </p>
14
+
15
+ <p>
16
+ <%= f.label :category %><br/>
17
+ <span class="input-wrap"><%= f.select :category, component.categories, :include_blank => true %></span>
18
+ </p>
19
+
20
+ <% end %>
21
+ <% end %>
@@ -0,0 +1,55 @@
1
+ <p>
2
+ <span class="tooltip" title="Enter a comma separated list of categories (e.g: one, two, three)">&nbsp;</span>
3
+ <%= f.label :category_list, 'Categories' %><br/>
4
+ <span class="input-wrap">
5
+ <%= f.text_field :category_list, :class => "categories-completer" %><br/>
6
+ </span>
7
+ </p>
8
+
9
+ <%= javascript_include_tag('noodall-articles/categories') %>
10
+
11
+ <%= render :partial => 'noodall/admin/nodes/body', :locals => { :f => f } %>
12
+ <% content_for :component_table do %>
13
+ <!--
14
+ modify this table to look like your template and link slots to correct anchors
15
+ <table class="component-table">
16
+ <tr>
17
+ <td rowspan="2" class="content"></td>
18
+ <td colspan="2" rowspan="4" class="content"></td>
19
+ <td><a href="#small_component_form_0" class="slot_link">4</a></td>
20
+ </tr>
21
+ <tr>
22
+ <td><a href="#small_component_form_1" class="slot_link">5</a></td>
23
+ </tr>
24
+ <tr>
25
+ <td></td>
26
+ <td><a href="#small_component_form_2" class="slot_link">6</a></td>
27
+ </tr>
28
+ <tr>
29
+ <td></td>
30
+ <td><a href="#small_component_form_3" class="slot_link">7</a></td>
31
+ </tr>
32
+ <tr>
33
+ <td></td>
34
+ <td colspan="2"><a href="#wide_component_form_0" class="slot_link">1</a></td>
35
+ <td></td>
36
+ </tr>
37
+ <tr>
38
+ <td></td>
39
+ <td colspan="2"><a href="#wide_component_form_1" class="slot_link">2</a></td>
40
+ <td></td>
41
+ </tr>
42
+ <tr>
43
+ <td></td>
44
+ <td colspan="2"><a href="#wide_component_form_2" class="slot_link">3</a></td>
45
+ <td></td>
46
+ </tr>
47
+ <tr>
48
+ <td></td>
49
+ <td></td>
50
+ <td></td>
51
+ <td></td>
52
+ </tr>
53
+ </table>
54
+ -->
55
+ <% end -%>
@@ -0,0 +1,45 @@
1
+ <%= render :partial => 'noodall/admin/nodes/body', :locals => { :f => f } %>
2
+ <% content_for :component_table do %>
3
+ <!--
4
+ modify this table to look like your template and link slots to correct anchors
5
+ <table class="component-table">
6
+ <tr>
7
+ <td rowspan="2" class="content"></td>
8
+ <td colspan="2" rowspan="4" class="content"></td>
9
+ <td><a href="#small_component_form_0" class="slot_link">4</a></td>
10
+ </tr>
11
+ <tr>
12
+ <td><a href="#small_component_form_1" class="slot_link">5</a></td>
13
+ </tr>
14
+ <tr>
15
+ <td></td>
16
+ <td><a href="#small_component_form_2" class="slot_link">6</a></td>
17
+ </tr>
18
+ <tr>
19
+ <td></td>
20
+ <td><a href="#small_component_form_3" class="slot_link">7</a></td>
21
+ </tr>
22
+ <tr>
23
+ <td></td>
24
+ <td colspan="2"><a href="#wide_component_form_0" class="slot_link">1</a></td>
25
+ <td></td>
26
+ </tr>
27
+ <tr>
28
+ <td></td>
29
+ <td colspan="2"><a href="#wide_component_form_1" class="slot_link">2</a></td>
30
+ <td></td>
31
+ </tr>
32
+ <tr>
33
+ <td></td>
34
+ <td colspan="2"><a href="#wide_component_form_2" class="slot_link">3</a></td>
35
+ <td></td>
36
+ </tr>
37
+ <tr>
38
+ <td></td>
39
+ <td></td>
40
+ <td></td>
41
+ <td></td>
42
+ </tr>
43
+ </table>
44
+ -->
45
+ <% end -%>
@@ -0,0 +1,74 @@
1
+ <!-- FILTER NEWS -->
2
+ <div class="component filter">
3
+ <h3 class="sup-title">Find News...</h3>
4
+ <% if @node.all_categories.any? %>
5
+ <div class="filter-wrap category-list">
6
+ <h4>Category</h4>
7
+ <ul id="categories-list">
8
+ <% for category in @node.all_categories %>
9
+ <%= link_for_filter_text(category, @node, category: category) %>
10
+ <% end %>
11
+ </ul>
12
+ </div>
13
+ <% end %>
14
+ </div>
15
+
16
+ <% if authors.any? %>
17
+ <div class="component authors">
18
+ <h3 class="sup-title">Authors</h3>
19
+ <ul id="authors-list">
20
+ <% authors.each do |author| %>
21
+ <%= link_for_filter_text(author.full_name, @node.list, { :author => author.permalink }) %>
22
+ <% end %>
23
+ </ul>
24
+ </div>
25
+ <% end %>
26
+
27
+ <!-- RELATED ARTICLES -->
28
+ <% if @node.is_a?(Article) %>
29
+ <% unless @node.related_articles.empty? %>
30
+ <div class="component related-articles">
31
+ <h3 class="sup-title">Related Articles</h3>
32
+ <ul id="related-articles">
33
+ <% @node.related_articles.each do |article| %>
34
+ <li class="<%= cycle("first", "second", "third") %>">
35
+ <%= link_to article.title, node_path(article), :class => "latest-link" %>
36
+ <time datetime="<%= article.published_at %>" pubdate><%= l article.published_at, :format => :short %></time>
37
+ </li>
38
+ <% end %>
39
+ </ul>
40
+ </div>
41
+ <% end %>
42
+ <% end %>
43
+
44
+ <!-- RECENT ARTICLES -->
45
+ <div class="component latest-articles">
46
+ <h3 class="sup-title">Recent Articles</h3>
47
+ <ul id="latest-article-list">
48
+ <% @node.recent_articles(categories: params[:category], creator_id: ( author.id if author )).each do |article| %>
49
+ <li class="<%= cycle("first", "second", "third") %>">
50
+ <%= link_to article.title, node_path(article), :class => "latest-link" %>
51
+ <time datetime="<%= article.published_at %>" pubdate><%= l article.published_at, :format => :short %></time>
52
+ </li>
53
+ <% end %>
54
+ </ul>
55
+ </div>
56
+
57
+ <!-- ARCHIVE -->
58
+ <div class="component archive">
59
+ <h3 class="sup-title">Archive</h3>
60
+ <ul id="archive-list">
61
+ <% @node.archive(categories: params[:category], creator_id: ( author.id if author )).each do |year| %>
62
+ <li>
63
+ <%= link_for_year_filter(@node, year) %>
64
+ <% if (params[:year] || Time.now.year).to_i == year.year %>
65
+ <ul>
66
+ <% year.months.each_with_index do |count, month| %>
67
+ <%= link_for_month_filter(@node, year, month, count) %>
68
+ <% end -%>
69
+ </ul>
70
+ <% end -%>
71
+ </li>
72
+ <% end -%>
73
+ </ul>
74
+ </div>
@@ -0,0 +1,18 @@
1
+ <% unless component.article_list.nil? %>
2
+
3
+ <div id="<%= slot_code %>" class="component latest-articles <%= 'double' if expand %> <%= additional_classes %>">
4
+ <h3 class="sup-title"><%=h component.title %></h3>
5
+ <ul id="latest-articles">
6
+ <% for article in component.articles %>
7
+ <li class="<%= cycle("first", "second", "third") %>">
8
+ <a href="<%= node_path(article) %>" title="<%= article.title %>">
9
+ <span class="article-title"><%= article.title %></span>
10
+ </a>
11
+ <time datetime="<%= article.published_at %>" pubdate><%= l article.published_at, :format => :short %></time>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <%= link_to 'All Articles', "/news", :class => 'more' %>
16
+ </div>
17
+
18
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <div class="main-content">
2
+ <div class="section-title">
3
+ <p><%= @node.list.title %></p>
4
+ <%= articles_rss_feed_link "RSS", :title => "RSS Feed", :class => "rss" %>
5
+ </div>
6
+ <h1><%= @node.title %></h1>
7
+ <div class="article-body">
8
+ <%= @node.body.html_safe %>
9
+ </div>
10
+ <div class="meta">
11
+ <span class="date"><%= l @node.published_at, :format => :short %></span>
12
+ <% if @node.creator %>
13
+
14
+ <span class="author"><%= link_to(@node.creator.full_name, node_path(@node.list, { :author => @node.creator.permalink })) %></li>
15
+ <% end %>
16
+ <span class="cats">
17
+ <% unless @node.categories.empty? %>
18
+ <% for category in @node.categories %>
19
+ <%= link_to category, node_path(@node, :category => category) %>,
20
+ <% end %>
21
+ <% end %>
22
+ </span>
23
+ </div>
24
+ <div class="pagination">
25
+ <%= link_to_previous_article %>
26
+ <%= link_to_next_article %>
27
+ </div>
28
+ </div>
29
+ <div class="supporting-content">
30
+ <%= render :partial => 'article_sidebar' %>
31
+ </div>
@@ -0,0 +1,41 @@
1
+ <% content_for :head do %>
2
+ <%= articles_rss_feed_auto_discovery %>
3
+ <% end %>
4
+
5
+ <div class="main-content">
6
+ <div class="section-title">
7
+ <p><%= @node.title %></p>
8
+ <%= articles_rss_feed_link "RSS", :title => "RSS Feed", :class => "rss" %>
9
+ </div>
10
+ <%= paginated_articles do |articles| %>
11
+ <ul id="articles">
12
+ <% for article in articles %>
13
+ <li class="<%= 'has-image' unless article.asset.nil? %>" >
14
+ <% unless article.asset.nil? %>
15
+ <div class="article-image"><%= image_tag( article.asset.url('80x80#', article.asset.web_image_extension), :alt => article.asset.description.to_s ) %></div>
16
+ <% end %>
17
+ <div class="article-content">
18
+ <h2><%= link_to article.title, node_path(article) %></h2>
19
+ <p><%= truncate(article.description, :length => 140) %></p>
20
+ <p class="meta">
21
+ <span class="date"><%= l article.published_at, :format => :short %></span>
22
+ <% if article.creator %>
23
+ <span class="author"><%= link_to(article.creator.full_name, node_path(@node.list, { :author => article.creator.permalink })) %></li>
24
+ <% end %>
25
+ <span class="cats">
26
+ <% unless article.categories.empty? %>
27
+ <% for category in article.categories %>
28
+ <%= link_to category, node_path(@node.list, :category => category) %>,
29
+ <% end %>
30
+ <% end %>
31
+ </span>
32
+ </p>
33
+ </div>
34
+ </li>
35
+ <% end %>
36
+ </ul>
37
+ <% end -%>
38
+ </div>
39
+ <div class="supporting-content">
40
+ <%= render :partial => 'article_sidebar' %>
41
+ </div>