noodall-articles 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +33 -0
- data/Rakefile +39 -0
- data/app/assets/javascripts/noodall-articles/categories.js +7 -0
- data/app/controllers/admin/categories_controller.rb +7 -0
- data/app/helpers/articles_helper.rb +126 -0
- data/app/models/article.rb +58 -0
- data/app/models/article_list.rb +49 -0
- data/app/models/latest_articles.rb +28 -0
- data/app/views/admin/components/_latest_articles.html.erb +21 -0
- data/app/views/admin/nodes/_article.html.erb +55 -0
- data/app/views/admin/nodes/_article_list.html.erb +45 -0
- data/app/views/application/_article_sidebar.html.erb +74 -0
- data/app/views/components/_latest_articles.html.erb +18 -0
- data/app/views/nodes/article.html.erb +31 -0
- data/app/views/nodes/article_list.html.erb +41 -0
- data/app/views/nodes/article_list.rss.builder +19 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +5 -0
- data/lib/generators/noodall/articles/views/USAGE +5 -0
- data/lib/generators/noodall/articles/views/views_generator.rb +7 -0
- data/lib/noodall/articles/archive.rb +56 -0
- data/lib/noodall/articles/categories.rb +39 -0
- data/lib/noodall/articles/custom_link_renderer.rb +25 -0
- data/lib/noodall/articles/engine.rb +9 -0
- data/lib/noodall/articles/version.rb +5 -0
- data/lib/noodall-articles.rb +1 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/noodall-articles_tasks.rake +4 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +9 -0
- data/test/dummy/app/assets/stylesheets/application.css +7 -0
- data/test/dummy/app/controllers/application_controller.rb +26 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/content_page.rb +5 -0
- data/test/dummy/app/models/user.rb +31 -0
- data/test/dummy/app/views/admin/nodes/_content_page.html.erb +45 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/nodes/content_page.html.erb +6 -0
- data/test/dummy/config/application.rb +51 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +30 -0
- data/test/dummy/config/environments/production.rb +60 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/noodall.rb +1 -0
- data/test/dummy/config/initializers/noodall_dragonfly.rb +8 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/mongo.yml +6 -0
- data/test/dummy/config/routes.rb +9 -0
- data/test/dummy/config/sitemap.yml +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +9 -0
- data/test/noodall-articles_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- 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,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)"> </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>
|