beef-articles 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +7 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/app/controllers/admin/articles_controller.rb +89 -0
- data/app/controllers/admin/categories_controller.rb +83 -0
- data/app/controllers/admin/comments_controller.rb +30 -0
- data/app/controllers/articles_controller.rb +55 -0
- data/app/controllers/comments_controller.rb +50 -0
- data/app/helpers/articles_helper.rb +92 -0
- data/app/helpers/comments_helper.rb +7 -0
- data/app/models/article.rb +37 -0
- data/app/models/category.rb +17 -0
- data/app/models/comment.rb +16 -0
- data/app/views/admin/articles/index.html.erb +45 -0
- data/app/views/admin/articles/preview.js.rjs +1 -0
- data/app/views/admin/articles/show.html.erb +58 -0
- data/app/views/admin/categories/index.html.erb +31 -0
- data/app/views/admin/categories/show.html.erb +18 -0
- data/app/views/admin/comments/index.html.erb +33 -0
- data/app/views/articles/_article.html.erb +12 -0
- data/app/views/articles/index.html.erb +40 -0
- data/app/views/articles/index.rss.builder +18 -0
- data/app/views/articles/show.html.erb +55 -0
- data/app/views/comments/_comment.html.erb +4 -0
- data/app/views/comments/_form.html.erb +25 -0
- data/app/views/comments/new.html.erb +4 -0
- data/articles.gemspec +79 -0
- data/config/routes.rb +32 -0
- data/generators/articles_migration/articles_migration_generator.rb +11 -0
- data/generators/articles_migration/templates/migration.rb +45 -0
- data/lib/articles.rb +7 -0
- data/rails/init.rb +9 -0
- data/test/articles_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +110 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
class Article < ActiveRecord::Base
|
2
|
+
belongs_to :category
|
3
|
+
|
4
|
+
acts_as_content_node
|
5
|
+
acts_as_commentable
|
6
|
+
has_assets
|
7
|
+
acts_as_textiled :body
|
8
|
+
acts_as_taggable_on :tags
|
9
|
+
|
10
|
+
named_scope :categorised, lambda { |category|
|
11
|
+
return {} if category.nil?
|
12
|
+
category = Category.find(category) unless category.nil? or category.is_a? Category
|
13
|
+
{ :conditions => { :category_id => category.id } }
|
14
|
+
}
|
15
|
+
|
16
|
+
named_scope :in_time_delta, lambda { |year, month, day|
|
17
|
+
return {} if year.blank?
|
18
|
+
from = Time.mktime(year, month || 1, day || 1)
|
19
|
+
to = from + 1.year
|
20
|
+
to = from + 1.month unless month.blank?
|
21
|
+
to = from + 1.day unless day.blank?
|
22
|
+
to = to.tomorrow unless month.blank?
|
23
|
+
{ :conditions => ['published_at BETWEEN ? AND ?', from, to ] }
|
24
|
+
}
|
25
|
+
|
26
|
+
validates_presence_of :body, :description, :tag_list, :if => :publish
|
27
|
+
|
28
|
+
# Finds one article which was posted on a certain date and matches the supplied dashed-title
|
29
|
+
def self.find_by_permalink(year, month, day, permalink)
|
30
|
+
if result = in_time_delta(year, month, day).first( :conditions => ["permalink = ?", permalink] )
|
31
|
+
result
|
32
|
+
else
|
33
|
+
raise ActiveRecord::RecordNotFound, "Couldn't find article with permalink #{permalink} on #{year}.#{month}.#{day}}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Category < ActiveRecord::Base
|
2
|
+
|
3
|
+
has_many :articles
|
4
|
+
|
5
|
+
validates_presence_of :title
|
6
|
+
validates_uniqueness_of :title
|
7
|
+
|
8
|
+
named_scope :with, lambda { |many| {:joins => many.to_sym, :group => 'categories.id'} }
|
9
|
+
|
10
|
+
before_save :set_url
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def set_url
|
15
|
+
write_attribute :permalink, title.parameterize
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Comment < ActiveRecord::Base
|
2
|
+
belongs_to :commentable, :polymorphic => true
|
3
|
+
|
4
|
+
acts_as_textiled :body => [:hard_breaks, :filter_html, :filter_styles]
|
5
|
+
|
6
|
+
validates_presence_of :name, :comment
|
7
|
+
validates_acceptance_of :spam_filter, :accept => true, :on => :create, :allow_nil => false, :message => "believes message to be spam."
|
8
|
+
validates_format_of :email, :with => %r{.+@.+\..+}
|
9
|
+
|
10
|
+
attr_accessor :spam_filter
|
11
|
+
|
12
|
+
def website=(url)
|
13
|
+
write_attribute :website, url.gsub(/^http\:\/\//, '') unless url.blank?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<h1>Listing articles</h1>
|
2
|
+
|
3
|
+
<ul class="choices">
|
4
|
+
<li><%= link_to 'New article', new_admin_article_path %></li>
|
5
|
+
</ul>
|
6
|
+
|
7
|
+
<table>
|
8
|
+
<thead>
|
9
|
+
<tr>
|
10
|
+
<%= sortable_table_header :name => "Title", :sort => "title" %>
|
11
|
+
<th>Status</th>
|
12
|
+
<th>Author</th>
|
13
|
+
<%= sortable_table_header :name => "Updated", :sort => "updated_at" %>
|
14
|
+
<%= sortable_table_header :name => "Published At", :sort => "published_at" %>
|
15
|
+
<%= sortable_table_header :name => "Published To", :sort => "published_to" %>
|
16
|
+
<th colspan="3">Actions</th>
|
17
|
+
</tr>
|
18
|
+
</thead>
|
19
|
+
<tbody>
|
20
|
+
<% @articles.each do |article| %>
|
21
|
+
<tr id="article-<%= article.id %>">
|
22
|
+
<td><%=h article.title %></td>
|
23
|
+
<td><%= content_status(article) %></td>
|
24
|
+
<td><%= article.author %></td>
|
25
|
+
<td><%= article.updated_at.strftime('%d %b') %></td>
|
26
|
+
<td><%= article.published_at.strftime('%d %b') unless article.published_at.nil? %></td>
|
27
|
+
<td><%= article.published_to.strftime('%d %b') unless article.published_to.nil? %></td>
|
28
|
+
<td><%= link_to 'Show', article_permalink(article), :class => 'show' if article.published? %></td>
|
29
|
+
<td><%= link_to 'Edit', admin_article_path(article), :class => 'edit' %></td>
|
30
|
+
<td><%= link_to 'Destroy', admin_article_path(article), :confirm => 'Are you sure?', :method => :delete, :class => 'delete' %></td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
</tbody>
|
34
|
+
<tfoot>
|
35
|
+
<tr>
|
36
|
+
<%= sortable_table_header :name => "Title", :sort => "title" %>
|
37
|
+
<th>Status</th>
|
38
|
+
<th>Author</th>
|
39
|
+
<%= sortable_table_header :name => "Updated", :sort => "updated_at" %>
|
40
|
+
<%= sortable_table_header :name => "Published At", :sort => "published_at" %>
|
41
|
+
<%= sortable_table_header :name => "Published To", :sort => "published_to" %>
|
42
|
+
<th colspan="3">Actions</th>
|
43
|
+
</tr>
|
44
|
+
</tfoot>
|
45
|
+
</table>
|
@@ -0,0 +1 @@
|
|
1
|
+
page << "myLightWindow.activateWindow({href: '#{preview_articles_path}', title: 'This is only a preview'});"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<% content_for :header do %>
|
2
|
+
<%= javascript_include_tag 'lightwindow' %>
|
3
|
+
<%= stylesheet_link_tag 'lightwindow' %>
|
4
|
+
<% end -%>
|
5
|
+
|
6
|
+
<h1><%= @article.new_record? ? 'New' : 'Editing' %> article</h1>
|
7
|
+
|
8
|
+
<% form_for([:admin, @article], :html => {:id => 'has-assets-form'}) do |f| %>
|
9
|
+
<%= f.error_messages %>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
<%= f.label :title %><br/>
|
13
|
+
<%= f.text_field :title, :class => 'title' %>
|
14
|
+
</p>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
<%= f.label :body %><br />
|
18
|
+
<%= f.text_area :body, :class => 'editor' %>
|
19
|
+
</p>
|
20
|
+
<p>
|
21
|
+
<%= f.label :description %><br />
|
22
|
+
<%= f.text_area :description, :rows => 3 %>
|
23
|
+
</p>
|
24
|
+
<p>
|
25
|
+
<%= f.label :tag_list %><br />
|
26
|
+
<%= f.text_field :tag_list, :class => 'long' %>
|
27
|
+
</p>
|
28
|
+
<p>
|
29
|
+
<%= f.label :category %>
|
30
|
+
<%= f.collection_select :category_id, Category.all, :id, :title, :prompt => true %>
|
31
|
+
</p>
|
32
|
+
<p>
|
33
|
+
<%= f.label :allow_comments %><br />
|
34
|
+
<%= f.check_box :allow_comments %>
|
35
|
+
</p>
|
36
|
+
|
37
|
+
<%= publish_select(f) %>
|
38
|
+
|
39
|
+
<p class="submission">
|
40
|
+
<%= preview_link(@article) %>
|
41
|
+
<%= f.submit 'Publish', :name => 'article[publish]' %>
|
42
|
+
<%= f.submit 'Save as draft', :name => 'article[hide]' %>
|
43
|
+
or <%= link_to 'Cancel', admin_articles_path %>
|
44
|
+
</p>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
|
48
|
+
<% content_for :sub_content do %>
|
49
|
+
|
50
|
+
<%= asset_list(@article) %>
|
51
|
+
|
52
|
+
<h2>File Library</h2>
|
53
|
+
<%= asset_browser(true) %>
|
54
|
+
|
55
|
+
<h2>File Upload</h2>
|
56
|
+
<%= asset_upload_form %>
|
57
|
+
|
58
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<h1>Listing categories</h1>
|
2
|
+
|
3
|
+
<ul class="choices">
|
4
|
+
<li><%= link_to 'New category', new_admin_category_path %></li>
|
5
|
+
</ul>
|
6
|
+
|
7
|
+
<table>
|
8
|
+
<thead>
|
9
|
+
<tr>
|
10
|
+
<%= sortable_table_header :name => "Title", :sort => "title" %>
|
11
|
+
<%= sortable_table_header :name => "Description", :sort => "description" %>
|
12
|
+
<th colspan="2">Actions</th>
|
13
|
+
</tr>
|
14
|
+
</thead>
|
15
|
+
<tbody>
|
16
|
+
<% @categories.each do |category| %>
|
17
|
+
<tr id="category-<%= category.id %>">
|
18
|
+
<td><%= link_to category.title, admin_category_path(category) %></td>
|
19
|
+
<td><%=h category.description %></td>
|
20
|
+
<td><%= link_to 'Edit', admin_category_path(category), :class => 'edit' %></td>
|
21
|
+
<td><%= link_to 'Destroy', admin_category_path(category), :confirm => 'Are you sure?', :method => :delete, :class => 'delete' %></td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</tbody>
|
25
|
+
<tfoot>
|
26
|
+
<tr>
|
27
|
+
<%= sortable_table_header :name => "Title", :sort => "title" %>
|
28
|
+
<%= sortable_table_header :name => "Description", :sort => "description" %>
|
29
|
+
</tr>
|
30
|
+
</tfoot>
|
31
|
+
</table>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<h1><%= @category.new_record? ? 'New' : 'Editing' %> category</h1>
|
2
|
+
|
3
|
+
<% form_for([:admin, @category]) do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :title %><br />
|
8
|
+
<%= f.text_field :title %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.label :description %><br />
|
12
|
+
<%= f.text_area :description, :rows => 3 %>
|
13
|
+
</p>
|
14
|
+
<p class="submission">
|
15
|
+
<%= f.submit @category.new_record? ? 'Create' : 'Update', :disable_with => 'Submitting...' %> or <%= link_to 'Back', admin_categories_path %>
|
16
|
+
</p>
|
17
|
+
<% end %>
|
18
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<h1>Listing comments</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<% if @commentable.nil? -%>
|
7
|
+
<th>Article</th>
|
8
|
+
<% end -%>
|
9
|
+
<%= sortable_table_header :name => "Name", :sort => "name" %>
|
10
|
+
<%= sortable_table_header :name => "Comment", :sort => "comment" %>
|
11
|
+
<%= sortable_table_header :name => "Created", :sort => "created_at" %>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
<tbody>
|
15
|
+
<% @comments.each do |comment| %>
|
16
|
+
<tr id="comment-<%= comment.id %>">
|
17
|
+
<% if @commentable.nil? -%>
|
18
|
+
<td class="title"><%= link_to comment.commentable.title, [:admin, comment.commentable] %></td>
|
19
|
+
<% end -%>
|
20
|
+
<td><%= mail_to comment.email, comment.name %></td>
|
21
|
+
<td><%=h comment.comment %></td>
|
22
|
+
<td class="date"><%= comment.created_at.to_formatted_s(:short) %></td>
|
23
|
+
<td><%= link_to 'Destroy', admin_comment_path(comment), :confirm => 'Are you sure?', :method => :delete, :class => 'delete' %></td>
|
24
|
+
</tr>
|
25
|
+
<% end %>
|
26
|
+
</tbody>
|
27
|
+
<tfoot>
|
28
|
+
<tr>
|
29
|
+
<%= sortable_table_header :name => "Name", :sort => "name" %>
|
30
|
+
<%= sortable_table_header :name => "Comment", :sort => "comment" %>
|
31
|
+
</tr>
|
32
|
+
</tfoot>
|
33
|
+
</table>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!-- so:post -->
|
2
|
+
<dt>
|
3
|
+
<%= link_to h(article.title), article_permalink(article) %>
|
4
|
+
<%= link_to(image_tag(article.assets.images.first.public_filename(:medium)), article_permalink(article)) unless article.assets.images.first.nil? %>
|
5
|
+
</dt>
|
6
|
+
<dd>
|
7
|
+
<p class="post-meta">
|
8
|
+
<span class="date"><%= article.published_at.to_formatted_s(:short_dot) %></span> | posted by <%= link_to article.author, articles_authored_path(article.created_by) %>
|
9
|
+
</p>
|
10
|
+
<p><%=h article.description %></p>
|
11
|
+
</dd>
|
12
|
+
<!-- eo:post -->
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<% content_for 'header' do %>
|
2
|
+
<%= auto_discovery_link_tag :rss, {:tag => params[:tag], :page => nil, :format => 'rss'} unless params[:year] %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<h1>Articles</h1>
|
6
|
+
|
7
|
+
<%= link_to 'RSS', {:tag => params[:tag], :page => nil, :format => 'rss'} unless params[:year] %>
|
8
|
+
|
9
|
+
|
10
|
+
<!-- so:main-content -->
|
11
|
+
<div id="main-content">
|
12
|
+
|
13
|
+
<dl id="articles">
|
14
|
+
<%= render :partial => @articles %>
|
15
|
+
</dl>
|
16
|
+
|
17
|
+
<%= will_paginate %>
|
18
|
+
|
19
|
+
</div>
|
20
|
+
<!-- eo:main-content -->
|
21
|
+
|
22
|
+
<!-- so:supporting-content -->
|
23
|
+
<div id="supporting-content">
|
24
|
+
<%= article_categories %>
|
25
|
+
|
26
|
+
<h2>Archive</h2>
|
27
|
+
<%= archive %>
|
28
|
+
|
29
|
+
<h2>Latest Posts</h2>
|
30
|
+
<%= recent_articles %>
|
31
|
+
|
32
|
+
<h2>Tagcloud</h2>
|
33
|
+
<ul class="tag-cloud">
|
34
|
+
<% @tags.each do |tag| %>
|
35
|
+
<li><%= link_to tag.name, articles_tagged_path( tag.name ), :class => "css-class-#{tag.count}" %></li>
|
36
|
+
<% end %>
|
37
|
+
</ul>
|
38
|
+
|
39
|
+
</div>
|
40
|
+
<!-- eo:supporting-content -->
|
@@ -0,0 +1,18 @@
|
|
1
|
+
xml.instruct! :xml, :version=>"1.0"
|
2
|
+
xml.rss(:version=>"2.0") do
|
3
|
+
xml.channel do
|
4
|
+
xml.title("#{Settings.site_name} - #{page_title}")
|
5
|
+
xml.link(url_for {} )
|
6
|
+
xml.language('en-gb')
|
7
|
+
for article in @articles
|
8
|
+
xml.item do
|
9
|
+
xml.title(article.title)
|
10
|
+
xml.category(article.tag_list)
|
11
|
+
xml.description(article.description)
|
12
|
+
xml.pubDate(article.published_at.rfc822)
|
13
|
+
xml.link(article_permalink(article, :only_path => false))
|
14
|
+
xml.guid(article_permalink(article, :only_path => false))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<% content_for 'header' do %>
|
2
|
+
<%= auto_discovery_link_tag :rss, articles_path(:rss) %>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<div id="main-content">
|
6
|
+
<h1>News</h1>
|
7
|
+
<%= link_to 'RSS', articles_path(:rss), :class => 'rss' %>
|
8
|
+
<div class="post">
|
9
|
+
<h2><%=h @article.title %></h2>
|
10
|
+
<p class="post-meta">
|
11
|
+
on <span class="date"><%= @article.published_at.to_formatted_s(:short_dot) %></span> by <%= link_to @article.author, articles_authored_path(@article.created_by) %>
|
12
|
+
</p>
|
13
|
+
<%= @article.body %>
|
14
|
+
|
15
|
+
<% unless @article.assets.documents.empty? -%>
|
16
|
+
<ul>
|
17
|
+
<% for document in @article.assets.documents %>
|
18
|
+
<li><%= link_to document.filename %></li>
|
19
|
+
<% end %>
|
20
|
+
</ul>
|
21
|
+
<% end -%>
|
22
|
+
|
23
|
+
<a href="#" id="share-title" title="Share This Article">Share This</a>
|
24
|
+
<p class="share-links">
|
25
|
+
<%= mail_link @article %> <%= digg_link @article %> <%= delicious_link @article %> <%= facebook_link @article %> <%= stumble_link @article %> <%= twitter_link @article %> <%= reddit_link @article %> <%= technorati_link @article %>
|
26
|
+
</p>
|
27
|
+
</div><!-- eo:post -->
|
28
|
+
|
29
|
+
|
30
|
+
<% if @article.allow_comments? or !@article.comments.empty? -%>
|
31
|
+
<div id="comments">
|
32
|
+
<h2>Comments</h2>
|
33
|
+
|
34
|
+
<% if @article.comments.empty? -%>
|
35
|
+
<p class="no-comments">There are currently no comments.</p>
|
36
|
+
<% else -%>
|
37
|
+
<%= comments_list @article %>
|
38
|
+
<% end -%>
|
39
|
+
|
40
|
+
<% if @article.allow_comments? %>
|
41
|
+
<h2 id="respond">Leave a Comment</h2>
|
42
|
+
<%= render :partial => 'comments/form', :locals => { :commentable => @article } %>
|
43
|
+
<% end -%>
|
44
|
+
</div>
|
45
|
+
<% end -%>
|
46
|
+
|
47
|
+
</div><!-- eo:main-content -->
|
48
|
+
|
49
|
+
<div id="supporting-content">
|
50
|
+
<h3>Latest Posts</h3>
|
51
|
+
<%= recent_articles %>
|
52
|
+
|
53
|
+
<h3>Archive</h3>
|
54
|
+
<%= archive %>
|
55
|
+
</div><!-- eo: supporting-content -->
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<li id="comment-<%= comment.id %>">
|
2
|
+
<%= sanitize comment.comment, :tags => Settings.allowed_html_tags_for_UGC.to_s.split(' '), :attributes => Settings.allowed_html_attributes_for_UGC.to_s.split(' ') %>
|
3
|
+
<a href="<%= article_permalink(commentable, :anchor => "comment-#{comment.id}") %>" title="Permalink to this comment"><%= comment.created_at.to_formatted_s(:short_dot)%></a> | posted by <%= link_to_unless comment.website.blank?, comment.name, "http://#{comment.website}" %>
|
4
|
+
</li>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% form_for([commentable, (@comment || Comment.new)], :html => {:id=>"comment-form"} ) do |f| %>
|
2
|
+
<%= f.error_messages %>
|
3
|
+
<p>
|
4
|
+
<%= f.label :name, "Name" %><br/>
|
5
|
+
<%= f.text_field :name %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<%= f.label :email %><br/>
|
10
|
+
<%= f.text_field :email %>
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<p>
|
14
|
+
<%= f.label :website, 'Website' %><br/>
|
15
|
+
<%= f.text_field :website %>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
<%= f.label :comment, "Comment" %><br/>
|
20
|
+
<%= f.text_area :comment, :rows => 5 %>
|
21
|
+
</p>
|
22
|
+
|
23
|
+
<p class="buttons"><%= f.submit 'Submit', :id => 'submit' %></p>
|
24
|
+
|
25
|
+
<% end -%>
|