Index: app/helpers/application_helper.rb
===================================================================
--- app/helpers/application_helper.rb (revision 272)
+++ app/helpers/application_helper.rb (working copy)
@@ -94,4 +94,14 @@
hash = "#{aggregator.to_s}_#{Digest::SHA1.hexdigest(url)}".to_sym
controller.cache[hash] ||= aggregator.new(url)
end
+
+ def time_in_words(from_time, to_time)
+ if(from_time>to_time)
+ delta="ago"
+ else
+ delta="later"
+ end
+
+ to_time.strftime('%B %d, %Y at %H:%M %p')+" ("+distance_of_time_in_words(from_time,to_time)+" #{delta})"
+ end
end
Index: app/helpers/admin/base_helper.rb
===================================================================
--- app/helpers/admin/base_helper.rb (revision 272)
+++ app/helpers/admin/base_helper.rb (working copy)
@@ -77,6 +77,8 @@
text_filter_options << [ 'None', 'none' ]
text_filter_options << [ 'Textile', 'textile' ] if defined?(RedCloth)
text_filter_options << [ 'Markdown', 'markdown' ] if defined?(BlueCloth)
+ text_filter_options << [ 'SmartyPants', 'smartypants' ] if defined?(RubyPants)
+ text_filter_options << [ 'Markdown with SmartyPants', 'markdown smartypants' ] if defined?(RubyPants) and defined?(BlueCloth)
text_filter_options
end
Index: app/models/category.rb
===================================================================
--- app/models/category.rb (revision 272)
+++ app/models/category.rb (working copy)
@@ -1,5 +1,5 @@
class Category < ActiveRecord::Base
- acts_as_list
+# acts_as_list
has_and_belongs_to_many :articles, :order => "created_at DESC"
end
Index: app/models/comment.rb
===================================================================
--- app/models/comment.rb (revision 272)
+++ app/models/comment.rb (working copy)
@@ -2,6 +2,7 @@
class Comment < ActiveRecord::Base
belongs_to :article
+ acts_as_tree :order => "id"
validates_presence_of :author, :body
validates_against_spamdb :body, :url, :ip
@@ -25,7 +26,8 @@
end
def transform_body
- self.body_html = HtmlEngine.transform(body, config["text_filter"], [:filter_html]) # Escape HTML in comments
+ text_filter = config["comment_text_filter"]||config["text_filter"]
+ self.body_html = HtmlEngine.transform(body, text_filter, [:filter_html]) # Escape HTML in comments
end
end
Index: app/models/configuration.rb
===================================================================
--- app/models/configuration.rb (revision 272)
+++ app/models/configuration.rb (working copy)
@@ -6,6 +6,7 @@
setting :sp_article_auto_close, :int, "Auto-close ability to comment/trackback articles after X days"
setting :sp_url_limit, :int, "Limit for URLs in comments and trackbacks"
setting :text_filter, :string, "Default HTML transformation style"
+ setting :comment_text_filter, :string, "Comment HTML transformation style"
end
def config
Index: app/controllers/admin/content_controller.rb
===================================================================
--- app/controllers/admin/content_controller.rb (revision 272)
+++ app/controllers/admin/content_controller.rb (working copy)
@@ -13,7 +13,7 @@
def show
@article = Article.find(@params['id'])
- @categories = Category.find(:all)
+ @categories = Category.find(:all, :order => 'name')
end
def new
Index: app/controllers/admin/categories_controller.rb
===================================================================
--- app/controllers/admin/categories_controller.rb (revision 272)
+++ app/controllers/admin/categories_controller.rb (working copy)
@@ -6,7 +6,7 @@
end
def list
- @categories = Category.find_all
+ @categories = Category.find(:all, :order => 'name')
end
def show
Index: app/controllers/articles_controller.rb
===================================================================
--- app/controllers/articles_controller.rb (revision 272)
+++ app/controllers/articles_controller.rb (working copy)
@@ -18,14 +18,14 @@
@comment = Comment.new
@page_title = @article.title
- fill_from_cookies(@comment)
+ populate_comment(@comment)
end
def permalink
@article = Article.find_by_permalink(@params["year"], @params["month"], @params["day"], @params["title"])
@comment = Comment.new
- fill_from_cookies(@comment)
+ populate_comment(@comment)
if @article.nil?
error("Post not found..")
@@ -78,20 +78,43 @@
@comment.article = @article
@comment.ip = request.remote_ip
- if @request.post? and @comment.save
- @comment.body = ""
-
+ if @article.allow_comments and @request.post? and @comment.save
cookies['author'] = { :value => @comment.author, :expires => 2.weeks.from_now }
cookies['url'] = { :value => @comment.url, :expires => 2.weeks.from_now }
+ cookies['email'] = { :value => @comment.email, :expires => 2.weeks.from_now }
@headers["Content-Type"] = "text/html; charset=utf-8"
- render_partial("comment", @comment)
+ if(@comment.parent_id)
+ render_partial("comment", @comment.parent)
+ else
+ render_partial_collection("commentset", @article.comments.reject { |c| c.parent_id })
+ end
else
render_partial("comment_error", @comment)
end
end
+ def commentbox
+ @article = Article.find(@params["id"])
+ @comment = Comment.new
+ @comment.article_id=@params['id']
+ @comment.parent_id = @params['parent_id']
+
+ populate_comment(@comment)
+ render_partial("commentbox", @comment)
+ end
+
+ def commenttitle
+ @article = Article.find(@params["id"])
+ @comment = Comment.new
+ @comment.article_id=@params['id']
+ @comment.parent_id = @params['parent_id']
+
+ populate_comment(@comment)
+ render_text(@comment.title)
+ end
+
# Receive trackbacks linked to articles
def trackback
@result = true
@@ -138,10 +161,23 @@
def fill_from_cookies(comment)
comment.author ||= cookies['author']
comment.url ||= cookies['url']
+ comment.email ||= cookies['email']
end
def rescue_action_in_public(exception)
error(exception.message)
end
+ def populate_comment(comment)
+ if(comment.parent_id)
+ comment.parent=Comment.find(comment.parent_id)
+ comment.title = comment.parent.title if comment.parent
+ end
+
+ if(not comment.title)
+ comment.title=@article.title
+ end
+
+ fill_from_cookies(comment)
+ end
end
Index: app/apis/movable_type_service.rb
===================================================================
--- app/apis/movable_type_service.rb (revision 272)
+++ app/apis/movable_type_service.rb (working copy)
@@ -119,6 +119,8 @@
def supportedTextFilters()
filters = []
filters << MovableTypeStructs::TextFilter.new(:key => 'markdown', :label => 'Markdown') if defined?(BlueCloth)
+ filters << MovableTypeStructs::TextFilter.new(:key => 'smartypants', :label => 'SmartyPants') if defined?(RubyPants)
+ filters << MovableTypeStructs::TextFilter.new(:key => 'markdown smartypants', :label => 'Markdown with SmartyPants') if defined?(RubyPants) and defined?(BlueCloth)
filters << MovableTypeStructs::TextFilter.new(:key => 'textile', :label => 'Textile') if defined?(RedCloth)
filters
end
@@ -145,4 +147,4 @@
def pub_date(time)
time.strftime "%a, %e %b %Y %H:%M:%S %Z"
end
-end
\ No newline at end of file
+end
Index: app/views/xml/commentrss.rxml
===================================================================
--- app/views/xml/commentrss.rxml (revision 272)
+++ app/views/xml/commentrss.rxml (working copy)
@@ -9,7 +9,7 @@
for comment in @comments
xml.item do
- xml.title "\"#{comment.article.title}\" by #{comment.author}"
+ xml.title "\"#{comment.article.title}\": #{comment.title} by #{comment.author}"
xml.description comment.body_html
xml.pubDate pub_date(comment.created_at)
xml.guid comment_link(comment)
Index: app/views/articles/read.rhtml
===================================================================
--- app/views/articles/read.rhtml (revision 272)
+++ app/views/articles/read.rhtml (working copy)
@@ -1,16 +1,20 @@
<% content_for("script") do %>
-function item_added() {
- var li = $('commentList').getElementsByTagName('LI');
- new Effect.Appear(li[li.length-1]);
+var old_commentclick='';
+
+function item_added(c_id) {
Element.hide('comment_loading');
- Element.show('commentform');
- $('commentform').elements[2].value = '';
- $('commentform').elements[2].focus();
$('form-submit-button').disabled = false;
+ $('comment_body').value='';
+
+ var li = $('commentsub-'+c_id).getElementsByTagName('LI');
+ var newcommentid=li[li.length-1];
+ //$(newcommentid).style.display='none';
+ new Effect.Appear(newcommentid);
}
-function item_loading() {
+function item_loading(a_id) {
$('form-submit-button').disabled = true;
Element.show('comment_loading');
+ reply_to(a_id,'');
}
window.onload = function() {
@@ -18,6 +22,32 @@
Element.show('guest_url');
}
}
+function reply_to(a_id,c_id) {
+ commentbox=document.getElementById('commentbox');
+ commentblank=document.getElementById('commentbox-'+c_id);
+ oldcommentclick=document.getElementById('commentclick-'+old_commentclick);
+ newcommentclick=document.getElementById('commentclick-'+c_id);
+ oldcommentclick.style.display="block";
+ newcommentclick.style.display="none";
+
+ old_commentclick=c_id;
+
+ commentbox.parentNode.removeChild(commentbox);
+ commentblank.appendChild(commentbox);
+
+ document.getElementById('comment_parent_id').value=c_id;
+ commentform=document.getElementById('commentform');
+ commentform.onsubmit=function(){new Ajax.Updater('comment-'+c_id, '/articles/comment/'+a_id, {onLoading:function(request){item_loading(a_id)}, onComplete:function(request){item_added(c_id)}, parameters:Form.serialize(this), asynchronous:true}); return false;};
+
+ new Effect.Appear('commentbox');
+
+ new Ajax.Updater('comment_title', '/articles/commenttitle/'+a_id+'?parent_id='+c_id,
+ {asynchronous:true,
+ insertion:function(container,text){container.value=text;}
+ });
+
+ return false;
+}
<% end %>
<%= render_partial "article", @article %>
@@ -27,8 +57,8 @@
Leave a response
-
+<% if comment.children.size>0 %>
+
+<% end %>
+
\ No newline at end of file
Index: app/views/articles/_article.rhtml
===================================================================
--- app/views/articles/_article.rhtml (revision 272)
+++ app/views/articles/_article.rhtml (working copy)
@@ -7,7 +7,7 @@
trackback:ping="<%= server_url_for :controller=>"articles", :action=>"trackback", :id=>article.id %>"
dc:title="<%=h article.title %>"
dc:identifier="<%= server_url_for :controller=>"articles", :action=>"read", :id=>article.id %>"
- dc:description="<%=h strip_html(article.body_html[0..255]) %>"
+ dc:description="<%=h strip_html(article.body_html[0..255]).gsub(/--/,'-') %>"
dc:creator="<%= h article.author %>"
dc:date="<%= article.updated_at.xmlschema %>" />
@@ -15,5 +15,5 @@
<%= article_link article.title, article %>
- Posted by <%=h article.author %> <%= distance_of_time_in_words_to_now article.created_at %> ago
+ Posted by <%=h article.author %> on <%= time_in_words Time.now,article.created_at %>
<%= article.body_html %>
Index: app/views/admin/content/_form.rhtml
===================================================================
--- app/views/admin/content/_form.rhtml (revision 272)
+++ app/views/admin/content/_form.rhtml (working copy)
@@ -1,15 +1,15 @@
<%= error_messages_for 'article' %>
-Title: <%= text_field 'article', 'title' %>
+Title: <%= text_field 'article', 'title' %>
-Created at: <%= datetime_select 'article', 'created_at' %>
+Created at: <%= datetime_select 'article', 'created_at' %>
-Body: <%= text_area 'article', 'body' %>
+Body: <%= text_area 'article', 'body' %>
-Allow comments: <%= check_box 'article', 'allow_comments' %>
-Allow pings: <%= check_box 'article', 'allow_pings' %>
-Textfilter: <%= select 'article', 'text_filter', text_filter_options %>
+Allow comments: <%= check_box 'article', 'allow_comments' %>
+Allow pings: <%= check_box 'article', 'allow_pings' %>
+Textfilter: <%= select 'article', 'text_filter', text_filter_options %>
Index: app/views/admin/general/index.rhtml
===================================================================
--- app/views/admin/general/index.rhtml (revision 272)
+++ app/views/admin/general/index.rhtml (working copy)
@@ -13,10 +13,10 @@
General settings
<% for field in @fields -%>
<%= field.desc %>
- <% if field.name == :text_filter %>
-
- <%= options_for_select( text_filter_options, config["text_filter"] ) -%>
-
+ <% if field.name.to_s =~ /text_filter/ %>
+
+ <%= options_for_select( text_filter_options, config[field.name.to_s] ) -%>
+
<% else %>
<%= settings_field field %>
<% end %>
Index: config/environment.rb
===================================================================
--- config/environment.rb (revision 272)
+++ config/environment.rb (working copy)
@@ -77,4 +77,6 @@
require_dependency 'spam_protection'
require_dependency 'xmlrpc_fix'
-ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(:database_manager => CGI::Session::ActiveRecordStore)
\ No newline at end of file
+require 'rubypants' rescue nil
+
+ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.update(:database_manager => CGI::Session::ActiveRecordStore)
Index: db/schema.mysql.sql
===================================================================
--- db/schema.mysql.sql (revision 272)
+++ db/schema.mysql.sql (working copy)
@@ -47,6 +47,7 @@
CREATE TABLE `comments` (
`id` int(11) NOT NULL auto_increment,
`article_id` int(11) default NULL,
+ `parent_id` int(11) default NULL,
`author` varchar(255) default NULL,
`email` varchar(255) default NULL,
`url` varchar(255) default NULL,
Index: db/schema.psql.sql
===================================================================
--- db/schema.psql.sql (revision 272)
+++ db/schema.psql.sql (working copy)
@@ -50,6 +50,7 @@
CREATE TABLE comments (
id SERIAL PRIMARY KEY NOT NULL,
article_id int NOT NULL REFERENCES articles,
+ parent_id int default NULL,
title varchar(255) default NULL,
author varchar(255) default NULL,
email varchar(255) default NULL,
Index: db/schema.sqlite.sql
===================================================================
--- db/schema.sqlite.sql (revision 272)
+++ db/schema.sqlite.sql (working copy)
@@ -42,6 +42,7 @@
CREATE TABLE 'comments' (
'id' INTEGER PRIMARY KEY NOT NULL,
'article_id' INTEGER DEFAULT NULL,
+ 'parent_id' INTEGER DEFAULT NULL,
'author' VARCHAR(255) DEFAULT NULL,
'email' VARCHAR(255) DEFAULT NULL,
'url' VARCHAR(255) DEFAULT NULL,
Index: lib/html_engine.rb
===================================================================
--- lib/html_engine.rb (revision 272)
+++ lib/html_engine.rb (working copy)
@@ -2,14 +2,23 @@
def self.transform(txt, text_filter = 'textile', restrictions = [])
return "" if txt.to_s.empty?
-
- case text_filter
- when "markdown": BlueCloth.new(txt, restrictions).to_html
+
+ text_filter='filterhtml '+text_filter if restrictions.include?(:filter_html)
+
+ text_filter.split(/ /).each do |filter|
+ case filter
+ when "markdown":
+ txt = BlueCloth.new(txt, restrictions).to_html
when "textile":
- txt = self.encode_html(txt) if restrictions.include?(:filter_html)
RedCloth.new(txt, restrictions).to_html(:textile)
- else txt
+ when "smartypants":
+ txt = RubyPants.new(txt).to_html
+ when "filterhtml":
+ txt = self.encode_html(txt)
+ end
end
+
+ return txt
end
# Taken from BlueCloth since RedCloth's filter_html is broken
@@ -19,4 +28,4 @@
str
end
-end
\ No newline at end of file
+end
Index: public/stylesheets/azure.css
===================================================================
--- public/stylesheets/azure.css (revision 272)
+++ public/stylesheets/azure.css (working copy)
@@ -167,12 +167,31 @@
/*+-------------------------------------------+
| COMMENTS |
+-------------------------------------------+*/
- .comment-list li {
+ .comment {
background: #d3e0ea;
padding: 5px;
margin-bottom: 8px;
color: #555;
}
+
+ .commentheader {
+ font-weight: bold;
+ }
+
+ .comment-list, .comment-sublist {
+ list-style-type: none;
+ margin: 0em;
+ padding: 0;
+ }
+
+ .comment-sublist {
+ margin-left: 2em;
+ }
+
+ .commentclick {
+ font-size: 0.8em;
+ font-style: italic;
+ }
/*+-------------------------------------------+
| SIDEBAR |