Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

- lib/hobix/out/atom.rb: Improved Atom support.

- lib/hobix.rb: More Ri.
  • Loading branch information...
commit a3939e52cea75178082689732284a463ad241206 1 parent c6a1501
_why authored
View
37 InstalledFiles
@@ -868,3 +868,40 @@
/usr/local/lib/ruby/site_ruby/1.9//hobix.rb
/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9//hobix.rb
+/usr/local/lib/ruby/site_ruby/1.9/CVS/Entries
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/CVS/Entries
+/usr/local/lib/ruby/site_ruby/1.9/hobix/entry.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.entry.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/entry.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.entry.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/out/atom.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/out/.atom.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/out/atom.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/out/.atom.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9//hobix.rb
+/usr/local/lib/ruby/site_ruby/1.9//.hobix.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/CVS/Root
+/usr/local/lib/ruby/site_ruby/1.9/CVS/Repository
+/usr/local/lib/ruby/site_ruby/1.9/CVS/Entries
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.base.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/out/atom.rb
+/usr/local/lib/ruby/site_ruby/1.9//.hobix.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9//hobix.rb
+/usr/local/lib/ruby/site_ruby/1.9//.hobix.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9//hobix.rb
+/usr/local/lib/ruby/site_ruby/1.9//.hobix.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/weblog.rb
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9//.hobix.rb.swp
+/usr/local/lib/ruby/site_ruby/1.9/hobix/.weblog.rb.swp
View
3  doc/CHANGELOG
@@ -3,7 +3,8 @@
date: 2004-05-23
changes:
- install.rb: install Ri documentation automatically.
- - lib/hobix.rb: new, great Ri documentation.
+ - ? [lib/hobix.rb, lib/hobix/weblog.rb, lib/hobix/entry.rb]
+ : new, great Ri documentation.
- lib/hobix/commandline.rb: moved commandline options into a class.
- lib/hobix/out/atom.rb: atom 0.3 support.
View
2  install.rb
@@ -679,7 +679,7 @@ def install_dir_bin( rel )
def install_dir_lib( rel )
install_files targfiles, config('rb-dir') + '/' + rel, 0644
- return unless rel == 'hobix'
+ return unless rel.empty?
begin
require 'rdoc/rdoc'
ri_site = true
View
2  lib/hobix.rb
@@ -213,7 +213,7 @@
#
module Hobix
## Version used to compare installations
- VERSION = '0.1e'
+ VERSION = '0.1f'
## CVS information
CVS_ID = "$Id$"
CVS_REV = "$Revision$"[11..-3]
View
39 lib/hobix/base.rb
@@ -16,9 +16,16 @@
#++
module Hobix
+# The BasePlugin class is *bingo* the underlying class for
+# all Hobix plugins. The +Class::inherited+ hook is used
+# by this class to keep track of all classes that inherit
+# from it.
class BasePlugin
@@plugins = {}
@@required_from = nil
+ # Initializes all the plugins, returning
+ # an Array of plugin objects. (Used by the
+ # +Hobix::Weblog+ class.)
def BasePlugin.start( req, weblog )
opts = nil
unless req.respond_to? :to_str
@@ -49,9 +56,33 @@ def BasePlugin.inherited( sub )
end
end
+# The BaseStorage class outlines the fundamental API for
+# all storage plugins. Storage plugins are responsible
+# for abstracting away entry queries and managing the loading
+# of Entry objects. The goal being: cache as much as you can,
+# be efficient and tidy.
+#
+# == Query Methods
+#
+# find:: Each of the query methods below uses the +find+ method
+# to perform its search. This method accepts a Hash of
+# parameters. Please note that calling +find+ without
+# parameters will return all entries which qualify for
+# placement on the front page.
+#
+# all:: Returns all entries. Searches find( :all => true )
+# lastn:: Returns the last _n_ entries which qualify for the
+# front page.
+# inpath:: Returns entries within a path which qualify for the
+# front page.
+# after:: Returns entries created after a given date.
+# before:: Returns entries created before a given date.
+# within:: Returns entries created between a start and
+# end date.
+#
class BaseStorage < BasePlugin
def all
- find
+ find( :all => true )
end
def lastn( n = 10 )
find( :lastn => n )
@@ -70,9 +101,15 @@ def within( after, before )
end
end
+# The BaseOutput plugin is the underlying class for all output
+# plugins. These plugins are associated to templates. Based on
+# a template's suffix, the proper output plugin is loaded and
+# used to generate page output.
class BaseOutput < BasePlugin
end
+# The BasePublish plguin is the underlying class for all publishing
+# plugins, which are notified of updates to pages.
class BasePublish < BasePlugin
end
View
38 lib/hobix/entry.rb
@@ -18,9 +18,36 @@
require 'yaml'
module Hobix
+# The Entry class stores complete data for an entry on the site. All
+# entry extensions should behave like this class as well.
+#
+# == Properties
+#
+# At the very least, entry data should support the following
+# accessors.
+#
+# id:: The id (or shortName) for this entry. Includes
+# the basic entry path.
+# link:: The full URL to this entry from the weblog.
+# title:: The heading for this entry.
+# tagline:: The subheading for this entry.
+# author:: The author's abbreviated name.
+# contributors:: An Array of contributors' abbreviated names.
+# modified:: A modification time.
+# created:: The time the Entry was initially created.
+# summary:: A brief description of this entry. Can be used
+# for an abbreviated text of a long article.
+# content:: The full text of the entry.
+#
+# The following read-only properties are also available:
+#
+# day_id:: The day ID can act as a path where other
+# entry, posted on the same day, are stored.
+# month_id:: A path for the month's entries.
+# year_id:: A path for the year's entries.
class Entry
attr_accessor :id, :link, :title, :tagline, :summary, :author,
- :contributors, :modified, :issued, :created,
+ :contributors, :modified, :created,
:content
def day_id; created.strftime( "/%Y/%m/%d/" ); end
@@ -65,7 +92,10 @@ def Entry::load( file )
YAML::load( File::open( file ) )
end
+ # Accessor which returns the text processor used for untyped
+ # strings in Entry fields. (defaults to +RedCloth+.)
def Entry::text_processor; RedCloth; end
+ # Returns an Array of fields to which the text processor applies.
def Entry::text_processor_fields; ['content', 'tagline', 'summary']; end
end
@@ -89,7 +119,13 @@ def str.to_html
YAML::add_domain_type( 'hobix.com,2004', 'entry', &entry_proc )
module Hobix
+# The EntryEnum class is mixed into an Array of entries just before
+# passing on to a template. This Enumerator-like module provides some
+# common iteration of entries.
module EntryEnum
+ # Calls the block with two arguments: (1) a Time object with
+ # the earliest date of an issued post for that day; (2) an
+ # Array of entries posted that day, in chronological order.
def each_day
last_day, day = nil, []
each do |e|
View
43 lib/hobix/linklist.rb
@@ -18,12 +18,41 @@
require 'redcloth'
require 'yaml'
+# The LinkList class is an entry type for storing links. It's
+# also a good example of how to subclass the Entry class so you
+# can store your own kinds of entries.
+#
+# == Properties
+#
+# The LinkList responds to many of the same properties listed
+# in the +Hobix::Entry+ class. The primary difference is that,
+# instead of having a +content+ property, there is a +links+
+# property.
+#
+# links:: Internally, this class stores a +YAML::Omap+, an
+# Array of pairs. The links are kept in the order
+# shown in the YAML file. They consist of a link
+# title, paired with a URL.
+#
+# == Sample LinkList
+#
+# --- %YAML:1.0 !hobix.com,2004/linklist
+# title: Hobix Links
+# author: why
+# created: 2004-05-30 18:53:00 -06:00
+# links:
+# - Hobix: http://hobix.com/
+# - Learn Hobix: http://hobix.com/learn/
+# - Textile Reference: http://hobix.com/textile/
+#
module Hobix
class LinkList < Entry
attr_accessor :id, :link, :title, :tagline, :summary, :author,
:contributors, :modified, :issued, :created, :links
- def to_yaml_properties
+ # Definition map for outputting YAML. Used by +to_yaml+,
+ # see +ToYamlExtras+ module.
+ def to_yaml_property_map
[
['@title', :opt],
['@author', :req],
@@ -32,15 +61,11 @@ def to_yaml_properties
['@tagline', :opt],
['@summary', :opt],
['@links', :req]
- ].
- reject do |prop, req|
- req == :opt and not instance_variable_get( prop )
- end.
- collect do |prop, req|
- prop
- end
+ ]
end
+ # Converts the link list into a RedCloth string for display
+ # in templates.
def content
RedCloth.new(
@links.collect do |title, url|
@@ -49,6 +74,8 @@ def content
)
end
+ # LinkLists currently output as YAML type family
+ # !hobix.com,2004/linklist.
def to_yaml_type
"!hobix.com,2004/linklist"
end
View
78 lib/hobix/out/atom.rb
@@ -20,6 +20,14 @@
module Hobix
module Out
+module XmlQuick
+ def x( title, txt, attrs = nil )
+ e = REXML::Element.new title
+ e.text = txt if txt
+ attrs.each { |a,b| e.attributes[a] = b } if attrs
+ self << e
+ end
+end
class Atom < Hobix::BaseOutput
def initialize( weblog )
@path = weblog.skel_path
@@ -48,41 +56,25 @@ def load( file_name, vars )
rssdoc.elements['/feed/copyright'].text = vars[:weblog].copyright || "None"
vars[:entries].each do |e|
ele = REXML::Element.new 'entry'
- ele_title = REXML::Element.new 'title'
- ele_title.text = e.title
- ele << ele_title
- ele_link = REXML::Element.new 'link'
- ele_link.attributes['rel'] = 'alternate'
- ele_link.attributes['type'] = 'text/html'
- ele_link.attributes['href'] = e.link
- ele << ele_link
- ele_guid = REXML::Element.new 'id'
- ele_guid.text = "tag:#{ uri.host },#{ Time.now.year }:blog#{ uri.path }entry/#{ e.id }"
- ele << ele_guid
- ele_time = REXML::Element.new 'issued'
- ele_time.text = e.created.strftime( "%Y-%m-%dT%H:%M:%SZ" )
- ele << ele_time
- ele_time = REXML::Element.new 'modified'
- ele_time.text = e.modified.strftime( "%Y-%m-%dT%H:%M:%SZ" )
- ele << ele_time
- if e.summary
- ele_summ = REXML::Element.new 'summary'
- ele_summ.attributes['type'] = 'text/html'
- ele_summ.attributes['mode'] = 'escaped'
- ele_summ.text = e.summary.to_html.gsub( /img src="\//, "img src=\"#{ vars[:weblog].link }" )
- ele << ele_summ
- end
+ ele.extend XmlQuick
+ ele.x( 'title', e.title )
+ ele.x( 'link', nil, {'rel' => 'alternate', 'type' => 'text/html', 'href' => e.link } )
+ ele.x( 'id', "tag:#{ uri.host },#{ Time.now.year }:blog#{ uri.path }entry/#{ e.id }" )
+ ele.x( 'issued', e.created.strftime( "%Y-%m-%dT%H:%M:%SZ" ) )
+ ele.x( 'modified', e.modified.strftime( "%Y-%m-%dT%H:%M:%SZ" ) )
+ ele.x( 'summary',
+ e.summary.to_html.gsub( /img src="\//, "img src=\"#{ vars[:weblog].link }" ),
+ {'type' => 'text/html', 'mode' => 'escaped'} ) if e.summary
author = vars[:weblog].authors[e.author]
ele_auth = REXML::Element.new 'author'
- ele_name = REXML::Element.new 'name'
- ele_name.text = author['name']
- ele_auth << ele_name
+ ele_auth.extend XmlQuick
+ ele_auth.x( 'name', author['name'] )
+ ele_auth.x( 'url', author['url'] ) if author['url']
+ ele_auth.x( 'email', author['email'] ) if author['email']
ele << ele_auth
- ele_desc = REXML::Element.new 'content'
- ele_desc.attributes['type'] = 'text/html'
- ele_desc.attributes['mode'] = 'escaped'
- ele_desc.text = e.content.to_html.gsub( /img src="\//, "img src=\"#{ vars[:weblog].link }" )
- ele << ele_desc
+ ele.x( 'content',
+ e.content.to_html.gsub( /img src="\//, "img src=\"#{ vars[:weblog].link }" ),
+ {'type' => 'text/html', 'mode' => 'escaped'} )
rssdoc.elements['/feed'].add ele
end
rssdoc.to_s
@@ -90,25 +82,3 @@ def load( file_name, vars )
end
end
end
-# <entry>
-# <title><$MTEntryTitle remove_html="1" encode_xml="1"$></title>
-# <link rel="alternate" type="text/html" href="<$MTEntryPermalink encode_xml="1"$>" />
-# <modified><$MTEntryModifiedDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></modified>
-# <issued><$MTEntryDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></issued>
-# <id>tag:<$MTBlogHost exclude_port="1" encode_xml="1"$>,<$MTEntryDate format="%Y">:<$MTBlogRelativeURL encode_xml="1"$>/<$MTBlogID$>.<$MTEntryID$></id>
-# <created><$MTEntryDate utc="1" format="%Y-%m-%dT%H:%M:%SZ"$></created>
-# <summary type="text/plain"><$MTEntryExcerpt remove_html="1" encode_xml="1"$></summary>
-# <author>
-# <name><$MTEntryAuthor encode_xml="1"$></name>
-# <MTIfNonEmpty tag="MTEntryAuthorURL"><url><$MTEntryAuthorURL encode_xml="1"$></url></MTIfNonEmpty>
-# <MTIfNonEmpty tag="MTEntryAuthorEmail"><email><$MTEntryAuthorEmail encode_xml="1"$></email></MTIfNonEmpty>
-# </author>
-# <MTIfNonEmpty tag="MTEntryCategory"><dc:subject><$MTEntryCategory encode_xml="1"$></dc:subject></MTIfNonEmpty>
-# <content type="text/html" mode="escaped" xml:lang="en" xml:base="<$MTBlogURL encode_xml="1"$>">
-# <$MTEntryBody encode_xml="1"$>
-# <$MTEntryMore encode_xml="1"$>
-# </content>
-# </entry>
-# </MTEntries>
-# </feed>
-
View
82 lib/hobix/weblog.rb
@@ -151,7 +151,7 @@ def add_ext( ext ) #:nodoc:
#
# = Examples
#
-# == Viewing Configuration
+# == Example 1: Viewing Configuration
#
# Since configuration is stored in YAML, you can generate the hobix.yaml
# configuration file by simply running +to_yaml+ on a weblog.
@@ -161,6 +161,60 @@ def add_ext( ext ) #:nodoc:
# puts weblog.to_yaml
# #=> --- # prints YAML configuration
#
+# == Example 2: Adding a Template Prefix
+#
+# On Hobix.com, only news entries are shown on the front page. The
+# site also has `about' and `learn' entry paths for storing the faqs
+# and tutorials. Although I didn't want to display the complete
+# text of these items, I did want a sidebar to contain links to them.
+#
+# So I added a `sidebar' prefix, which loads from these entry paths.
+# I have a sidebar.html.erb, which is included using Apache SSIs.
+# The advantage to this approach is that when an update occurs in
+# either of these paths, the sidebar will be updated in the next
+# regeneration. Rather than having to regenerate every page in the
+# site to see the change reflected.
+#
+# I added a `lib/hobix.com.rb' to the site's `lib' directory. And
+# in hobix.yaml, I included a line requiring this file. The file
+# simply contains the new skel method.
+#
+# module Hobix
+# class Weblog
+# def skel_sidebar
+# ## Load `about' and `learn' entries
+# abouts = storage.find( :all => true, :inpath => 'about' ).reverse
+# learns = storage.find( :all => true, :inpath => 'learn' ).reverse
+#
+# ## Create page data
+# page = Page.new( '/sidebar' )
+# page.updated = storage.last_modified( abouts + learns )
+# yield :page => page,
+# :about_entries => abouts, :learn_entries => learns
+# end
+# end
+# end
+#
+# There is a lot going on here. I'll try to explain the most vital parts and
+# leave the rest up to you.
+#
+# First, storage queries don't return full Entry objects. You can read more
+# about this in the +Hobix::BaseStorage+ class docs. The storage query returns
+# Arrays which contain each entry's id (a String) and the entry's modification time
+# (a Time object).
+#
+# See, the regeneration system will do the business of loading the full entries.
+# The skel method's job is just to report which entries *qualify* for a
+# template. The regeneration system will then look at those entries and figure out
+# if an update is needed.
+#
+# We create a Page object, which dictates that the output will be saved to
+# /sidebar.ext. A modification time is discovered by passing a combined list
+# to +Hobix::BaseStorage#last_modified+.
+#
+# We then yield to the regeneration system. Note that any hash key which
+# ends with `entries' will have its contents loaded as full Entry objects, should
+# the prefix qualify for regeneration.
#
class Weblog
attr_accessor :title, :link, :authors, :contributors, :tagline,
@@ -198,8 +252,8 @@ def Weblog::load( file )
weblog
end
- # Used by regenerate to construct the vars hash by calling
- # the appropriate +skel+ method for each page.
+ # Used by +regenerate+ to construct the vars hash by calling
+ # the appropriate skel method for each page.
def build_pages( page_name )
puts "[Building #{ page_name } pages]"
vars = {}
@@ -381,8 +435,11 @@ def skel_yearly
end
end
+ # Handler for templates with `entry' prefix. These templates will
+ # receive one entry for each entry in the weblog. The handler requests
+ # entry pages to be output as `/shortName.ext'.
def skel_entry
- all_entries = [storage.all]
+ all_entries = [storage.find]
all_entries += sections_ignored.collect { |ign| storage.find( :all => true, :inpath => ign ) }
all_entries.each do |entry_set|
entry_set.extend Hobix::Enumerable
@@ -397,6 +454,9 @@ def skel_entry
end
end
+ # Returns a hash of special sorting cases. Key is the entry path,
+ # value is the sorting method. Storage plugins must honor these
+ # default sorts.
def sections_sorts
@sections.inject( {} ) do |sorts, set|
k, v = set
@@ -405,12 +465,18 @@ def sections_sorts
end
end
+ # Returns an Array of entry paths ignored by general querying.
+ # Storage plugins must withhold these entries from queries, unless
+ # the :all => true setting is passed to the query.
def sections_ignored
@sections.collect do |k, v|
k if v['ignore']
end.compact
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.
def method_missing( methId, *args )
if storage.respond_to? methId
storage.method( methId ).call( *args ).collect do |e|
@@ -419,10 +485,8 @@ def method_missing( methId, *args )
end
end
- def to_yaml_type
- "!hobix.com,2004/weblog"
- end
-
+ # Prints publication information the screen. Override this if
+ # you want to suppress output or change the display.
def p_publish( obj )
puts "## Page: #{ obj.link }, updated #{ obj.updated }"
end
@@ -445,6 +509,8 @@ def to_yaml_property_map
]
end
+ # Returns the YAML type information, which expands to
+ # tag:hobix.com,2004:weblog.
def to_yaml_type
"!hobix.com,2004/weblog"
end
Please sign in to comment.
Something went wrong with that request. Please try again.