diff -x hobix.rb -x CVS -x webapp.rb -uNr hobix/lib/hobix/comments.rb hobix.ljb/lib/hobix/comments.rb
--- hobix/lib/hobix/comments.rb	Tue Jul 26 08:57:22 2005
+++ hobix.ljb/lib/hobix/comments.rb	Sat Jul 30 23:12:34 2005
@@ -37,22 +37,29 @@
 }
 
 append_def :entry_erb, %{
-    <% if entry and not defined? entries %><+ entry_comment +><% end %> 
+    <% if entry and not defined? entries %>
+      <+ entry_comment +>
+      <+ entry_comment_form +>
+    <% end %> 
 }
 
 def entry_comment_erb; %{
   <% entry_id = entry.id %>
+  <a name="comments"></a>
   <div id="comments">
   <% comments = weblog.storage.load_attached( entry_id, "comments" ) rescue [] %>
-  <% comments.each do |entry| %>
+  <% comments.each do |comment| %>
   <div class="entry">
       <div class="entryAttrib">
-          <div class="entryAuthor"><h3><%= entry.author %></h3></div>
-          <div class="entryTime">said on <%= entry.created.strftime( "<nobr>%d %b %Y</nobr> at <nobr>%I:%M %p</nobr>" ) %></div>
+          <div class="entryAuthor"><h3><%= comment.author %></h3></div>
+          <div class="entryTime">said on <%= comment.created.strftime( "<nobr>%d %b %Y</nobr> at <nobr>%I:%M %p</nobr>" ) %></div>
       </div>
-      <div class="entryContentOuter"><div class="entryContent"><%= entry.content.to_html %></div></div>
+      <div class="entryContentOuter"><div class="entryContent"><%= comment.content.to_html %></div></div>
   </div>
   <% end %>
+} end
+
+def entry_comment_form_erb; %{
   <div class="entry">
   <form id="userComment" method="post" action="/control/comment/<%= entry_id %>">
     <div class="entryAttrib">
@@ -76,5 +83,17 @@
   </div>
 } end
 end
+end
+
+class Comment < BaseContent
+  _! "Comment Information"
+  _ :author,    :req => true, :edit_as => :text, :search => :prefix
+  _ :created,   :edit_as => :datetime
+  _ :url,       :edit_as => :text
+  _ :email,     :edit_as => :text
+  _ :content,   :edit_as => :textarea, :search => :fulltext, :text_processor => true
+  _ :ipaddress, :edit_as => :text
+
+  yaml_type "tag:hobix.com,2005:comment"
 end
 end
diff -x hobix.rb -x CVS -x webapp.rb -uNr hobix/lib/hobix/facets/comments.rb hobix.ljb/lib/hobix/facets/comments.rb
--- hobix/lib/hobix/facets/comments.rb	Sun Jul 24 02:10:34 2005
+++ hobix.ljb/lib/hobix/facets/comments.rb	Sat Jul 30 11:05:22 2005
@@ -29,7 +29,7 @@
 class Comments < BaseFacet
     def self.form_field( name ); "hobix_comment:#{ name }" end
     def self.comment_fields; ['author', 'content']; end
-    def self.comment_class; Hobix::Entry end
+    def self.comment_class; Hobix::Comment end
 
     def initialize( weblog, defaults = {} )
         @weblog = weblog
@@ -51,12 +51,11 @@
                         c.method( "#{ cf }=" ).call( app._POST[getf] )
                     end
                     c.created = Time.now
+                    c.ipaddress = app.remote_addr
                 end
-                comments = @weblog.storage.load_attached( entry_id, 'comments' ) rescue []
-                comments << comment
 
-                # Save the attachment, upgen
-                @weblog.storage.save_attached( entry_id, "comments", comments )
+                # Save the comment, upgen
+                @weblog.append_to_attachment( entry_id, 'comments', comment )
                 @weblog.regenerate :update
 
                 # Redirect
diff -x hobix.rb -x CVS -x webapp.rb -uNr hobix/lib/hobix/facets/trackbacks.rb hobix.ljb/lib/hobix/facets/trackbacks.rb
--- hobix/lib/hobix/facets/trackbacks.rb	Thu Jan  1 01:00:00 1970
+++ hobix.ljb/lib/hobix/facets/trackbacks.rb	Sat Jul 30 22:31:29 2005
@@ -0,0 +1,80 @@
+#
+# = hobix/facets/trackbacks.rb
+#
+# Hobix command-line weblog system, support for trackbacks.
+#
+# Copyright (c) 2003-2004 why the lucky stiff
+#
+# Written & maintained by why the lucky stiff <why@ruby-lang.org>
+#
+# This program is free software, released under a BSD license.
+# See COPYING for details.
+#
+#--
+# $Id$
+#++
+
+require 'hobix/entry'
+
+module Hobix
+module Facets
+
+# The Trackbacks plugin adds support for the TrackBack specification
+# (http://www.sixapart.com/pronet/docs/trackback_spec).
+#
+# Add this require to your hobix.yaml:
+#
+#   requires:
+#   - hobix/trackbacks
+#
+class Trackbacks < BaseFacet
+    def self.trackback_fields; ['url','title', 'excerpt', 'blog_name']; end
+    def self.trackback_class; Hobix::Trackback; end
+
+    def initialize( weblog, defaults = {} )
+        @weblog = weblog
+    end
+    def get app
+        if app.respond_to? :action_uri
+            action, entry_id = app.action_uri.split( '/', 2 )
+            case action
+            when "trackback"
+                # Validate
+                on_entry = @weblog.storage.load_entry( entry_id ) rescue nil
+                return send_trackback_response( app, false, 'No such entry' ) if on_entry.nil?
+
+                # Create a trackback comment
+                trackback = Trackbacks.trackback_class.new do |t|
+                    Trackbacks.trackback_fields.each do |tf|
+                      t.method( "#{tf}=" ).call( app._POST[tf].to_s )
+                    end
+                    return send_trackback_response( app, false, 'Missing URL field' ) if (t.url || '').empty?
+                    t.created = Time.now
+                    t.ipaddress = app.remote_addr
+                end
+
+                # Save the trackback, upgen
+                @weblog.append_to_attachment( entry_id, 'trackbacks', trackback )
+                @weblog.regenerate :update
+
+                # Send response
+                send_trackback_response( app, true )
+                return true
+            end
+        end
+    end
+
+    def send_trackback_response(app, ok = true, message = nil)
+      app.content_type = 'text/xml'
+      app.puts %{<?xml version="1.0" encoding="UTF-8"?>
+        <response>
+          <error>%d</error>
+          %s
+        </response>
+      } % [ok ? 0 : 1, message ? %{<message>#{message}</message>} : '']
+      true
+    end
+end
+
+end
+end
diff -x hobix.rb -x CVS -x webapp.rb -uNr hobix/lib/hobix/trackbacks.rb hobix.ljb/lib/hobix/trackbacks.rb
--- hobix/lib/hobix/trackbacks.rb	Thu Jan  1 01:00:00 1970
+++ hobix.ljb/lib/hobix/trackbacks.rb	Sat Jul 30 23:33:14 2005
@@ -0,0 +1,90 @@
+#
+# = hobix/trackbacks.rb
+#
+# Hobix command-line weblog system, API for trackbacks.
+#
+# Copyright (c) 2003-2004 why the lucky stiff
+#
+# Written & maintained by why the lucky stiff <why@ruby-lang.org>
+#
+# This program is free software, released under a BSD license.
+# See COPYING for details.
+#
+#--
+# $Id$
+#++
+
+require 'hobix/facets/trackbacks'
+require 'time'
+require 'rexml/document'
+
+module Hobix
+module Out
+class Quick
+  prepend_def :entry_title_erb, %{
+    <+ entry_trackback_rdf +>
+  }
+
+  def entry_trackback_rdf_erb; %{
+    <!--
+    <%= trackback_rdf_for( weblog, entry ) %>
+    -->
+  } end
+
+  append_def :entry_erb, %{
+    <% if entry and not defined? entries %><+ entry_trackback +><% end %>
+  }
+
+  def entry_trackback_erb; %{
+    <a name="trackbacks"></a>
+    <div id="trackbacks">
+    <% entry_id = entry.id %>
+    <% trackbacks = weblog.storage.load_attached( entry_id, "trackbacks") rescue [] %>
+    <% trackbacks.each do |trackback| %>
+    <div class="entry">
+        <div class="entryAttrib">
+            <div class="entryAuthor"><h3><%= trackback.blog_name %></h3></div>
+            <div class="entryTime">tracked back on <%= trackback.created.strftime("<nobr>%d %b %Y</nobr> at <nobr>%I:%M %p</nobr>" ) %></div>
+        </div>
+        <div class="entryContentOuter"><div class="entryContent">
+            <h3><a href="<%= trackback.url %>"><%= trackback.title %></a></h3>
+            <%= trackback.excerpt %>
+        </div></div>
+    </div>
+    <% end %>
+    </div>
+  } end
+
+  private
+  def trackback_rdf_for( weblog, entry )
+    trackback_link = '%s/control/trackback/%s' % [weblog.link, entry.id]
+    doc = REXML::Document.new
+    rdf = doc.add_element( "rdf:RDF" )
+    rdf.add_namespace( "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#" )
+    rdf.add_namespace( "trackback", "http://madskills.com/public/xml/rss/module/trackback/" )
+    rdf.add_namespace( "dc", "http://purl.org/dc/elements/1.1/" )
+    desc = rdf.add_element( "rdf:Description" )
+    desc.add_attribute( "rdf:about", "")
+    desc.add_attribute( "trackback:ping", trackback_link )
+    desc.add_attribute( "dc:title", entry.title )
+    desc.add_attribute( "dc:identifier", entry.link )
+    desc.add_attribute( "dc:description", entry.summary )
+    desc.add_attribute( "dc:creator", entry.author )
+    desc.add_attribute( "dc:date", entry.created.xmlschema )
+    doc.to_s
+  end
+end
+end
+
+class Trackback < BaseContent
+  _! "Trackback Information"
+  _ :blog_name, :edit_as => :text, :req => true
+  _ :url, :edit_as => :text, :req => true
+  _ :title, :edit_as => :text, :req => true
+  _ :excerpt , :edit_as => :text, :req => true
+  _ :created, :edit_as => :datetime
+  _ :ipaddress, :edit_as => :text
+
+  yaml_type "tag:hobix.com,2005:trackback"
+end
+end
diff -x hobix.rb -x CVS -x webapp.rb -uNr hobix/lib/hobix/weblog.rb hobix.ljb/lib/hobix/weblog.rb
--- hobix/lib/hobix/weblog.rb	Sat Jul 23 19:19:55 2005
+++ hobix.ljb/lib/hobix/weblog.rb	Tue Jul 26 08:31:38 2005
@@ -792,6 +792,15 @@
         entry
     end
 
+    # Appends the given items to an entry attachment with the given type, and
+    # then saves the modified attachment. If an attachment of the given type
+    # does not exist, it will be created.
+    def append_to_attachment( entry_id, attachment_type, *items )
+      attachment = storage.load_attached( entry_id, attachment_type ) rescue []
+      attachment += items
+      storage.save_attached( entry_id, attachment_type, attachment )
+    end
+
     # For convenience, storage queries can be made through the Weblog
     # class.  Queries will return the full Entry data, though, so it's
     # best to use this only when you're scripting and need data quick.
