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

-
    - <%= render_collection_of_partials "comment", @article.comments.sort_by {|c| c.id} %> +
      + <%= render_collection_of_partials "commentset", @article.comments.sort_by {|c| c.id}.reject { |c| c.parent_id } %>
    <% end -%> @@ -46,37 +76,6 @@ <% end -%> <% if @article.allow_comments > 0 -%> - <%= form_remote_tag :url => {:action => "comment", :id => @article.id}, - :update => "commentList", :position=> "bottom", - :loading => "item_loading()", - :complete => "item_added()", - :html => {:id=>"commentform",:class=>"commentform"} %> - - -
    - - - - - - - - - - - - - - - - - -

    <%= text_field "comment", "author", :size => 20 %> (leave url »)

    - <%= text_area "comment", "body" %> -
    -    - -
    -
    - <%= end_form_tag %> -<% end -%> +
    <%= render_partial "commentbox" %>
    + +<% end -%> \ No newline at end of file Index: app/views/articles/_comment.rhtml =================================================================== --- app/views/articles/_comment.rhtml (revision 272) +++ app/views/articles/_comment.rhtml (working copy) @@ -1,5 +1,23 @@ -
  1. > +
    - <%= (comment.url.blank?) ? comment.author : link_to(comment.author, comment.url) %> said <%= distance_of_time_in_words @article.created_at, comment.created_at %> later:
    +
    + <% if comment.title %>

    <%=h comment.title %>

    <% end %> + + <% if comment.url.blank? %> + <%=h comment.author %> + <% else %> + <%= link_to(comment.author, comment.url) %> + <% end %> + said on <%=h time_in_words(@article.created_at, comment.created_at) %>: +
    <%= comment.body_html %> -
  2. + (Reply to this comment) +
    +
    +
+<% if comment.children.size>0 %> +
    + <%= render_collection_of_partials "commentset", comment.children.sort_by {|c| c.id} %> +
+<% 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' %> -<%= text_field 'article', 'title' %>
+<%= text_field 'article', 'title' %>
-<%= datetime_select 'article', 'created_at' %>
+<%= datetime_select 'article', 'created_at' %>
-<%= text_area 'article', 'body' %>
+<%= text_area 'article', 'body' %>
-<%= check_box 'article', 'allow_comments' %>
-<%= check_box 'article', 'allow_pings' %>
-<%= select 'article', 'text_filter', text_filter_options %>
+<%= check_box 'article', 'allow_comments' %>
+<%= check_box 'article', 'allow_pings' %>
+<%= 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 %> - + <% if field.name.to_s =~ /text_filter/ %> +
<% 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 |