diff --git a/README.textile b/README.textile
index 2352dd88..5c5f7530 100644
--- a/README.textile
+++ b/README.textile
@@ -31,9 +31,10 @@ various data about my site. A reverse chronological list of all my blog posts
can be found in site.posts. Each post, in turn, contains various
fields such as title and date.
-Jekyll gets the list of blog posts by parsing the files in the
-"_posts":http://github.com/mojombo/tpw/tree/master/_posts directory. Each
-post's filename contains the publishing date and slug (what shows up in the
+Jekyll gets the list of blog posts by parsing the files in any
+"_posts":http://github.com/mojombo/tpw/tree/master/_posts directory found in
+subdirectories below the root.
+Each post's filename contains the publishing date and slug (what shows up in the
URL) that the final HTML file should have. Open up the file corresponding to a
blog post:
"2008-11-17-blogging-like-a-hacker.textile":http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile.
@@ -52,6 +53,13 @@ filename is used to construct the URL in the generated site. The example post,
for instance, ends up at
http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html.
+Categories for posts are derived from the directory structure the posts were
+found within.
+A post that appears in the directory foo/bar/_posts is placed in the categories
+'foo' and 'bar'.
+By selecting posts from particular categories in your Liquid templates, you will
+be able to host multiple blogs within a site.
+
Files that do not reside in directories prefixed with an underscore are
mirrored into a corresponding directory structure in the generated site. If a
file does not have a YAML preface, it is not run through the Liquid
@@ -165,6 +173,9 @@ h3. Site
high quality but slow to compute results, run the jekyll command with the
--lsi (latent semantic indexing) option.
+ site.categories.CATEGORY
+ The list of all posts in category CATEGORY.
+
h3. Post
post.title
@@ -184,6 +195,9 @@ h3. Post
post.content
The content of the Post.
+ post.categories
+ The list of categories to which this post belongs.
+
h2. YAML Front Matter
Any files that contain a YAML front matter block will be processed by Jekyll
@@ -296,6 +310,22 @@ highlighting stylesheet. For an example stylesheet you can look at
are the same styles as used by GitHub and you are free to use them for your
own site.
+h2. Categories
+
+Posts are placed into categories based on the directory structure they are found
+within (see above for an example). The categories can be accessed from within
+a Liquid template as follows:
+
+
+{% endfor %}
+
+
+This would list all the posts in the category 'foo' by date and title.
+
+The posts within each category are sorted in reverse chronological order.
+
h2. Contribute
If you'd like to hack on Jekyll, grab the source from GitHub. To get
diff --git a/lib/jekyll.rb b/lib/jekyll.rb
index 7233a18c..9e6b610e 100644
--- a/lib/jekyll.rb
+++ b/lib/jekyll.rb
@@ -6,6 +6,7 @@ require 'rubygems'
# core
require 'fileutils'
require 'time'
+require 'yaml'
# stdlib
diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb
index 2ab4c7ec..7d1be0ab 100644
--- a/lib/jekyll/convertible.rb
+++ b/lib/jekyll/convertible.rb
@@ -13,7 +13,7 @@ module Jekyll
def read_yaml(base, name)
self.content = File.read(File.join(base, name))
- if self.content =~ /^(---.*\n.*?)\n---.*\n/m
+ if self.content =~ /^(---\s*\n.*?)\n---\s*\n/m
self.content = self.content[($1.size + 5)..-1]
self.data = YAML.load($1)
@@ -52,7 +52,7 @@ module Jekyll
# recursively render layouts
layout = layouts[self.data["layout"]]
while layout
- payload = payload.merge({"content" => self.output, "page" => self.data})
+ payload = payload.merge({"content" => self.output, "page" => payload['page']})
self.output = Liquid::Template.parse(layout.content).render(payload, [Jekyll::Filters])
layout = layouts[layout.data["layout"]]
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index 58191ec7..6051626a 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -4,6 +4,10 @@ module Jekyll
def date_to_string(date)
date.strftime("%d %b %Y")
end
+
+ def date_to_long_string(date)
+ date.strftime("%d %B %Y")
+ end
def date_to_xmlschema(date)
date.xmlschema
@@ -15,7 +19,6 @@ module Jekyll
def number_of_words(input)
input.split.length
- end
- end
-
+ end
+ end
end
\ No newline at end of file
diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb
index caca9354..fabbaf85 100644
--- a/lib/jekyll/post.rb
+++ b/lib/jekyll/post.rb
@@ -3,7 +3,7 @@ module Jekyll
class Post
include Comparable
include Convertible
-
+
class << self
attr_accessor :lsi
end
@@ -18,17 +18,19 @@ module Jekyll
name =~ MATCHER
end
- attr_accessor :date, :slug, :ext
+ attr_accessor :date, :slug, :ext, :categories
attr_accessor :data, :content, :output
# Initialize this Post instance.
# +base+ is the String path to the dir containing the post file
# +name+ is the String filename of the post file
+ # +categories+ is an Array of Strings for the categories for this post
#
# Returns
def initialize(base, name)
@base = base
@name = name
+ @categories = base.split('/').reject { |p| ['.', '_posts'].include? p }
self.process(name)
self.read_yaml(base, name)
@@ -61,9 +63,10 @@ module Jekyll
#
# Returns
def dir
+ path = @categories ? '/' + @categories.join('/') : ''
permalink ?
permalink.to_s.split("/")[0..-2].join("/") :
- date.strftime("/%Y/%m/%d/")
+ "#{path}" + date.strftime("/%Y/%m/%d/")
end
# The full path and filename of the post.
@@ -90,7 +93,7 @@ module Jekyll
def id
self.dir + self.slug
end
-
+
# Calculate related posts.
#
# Returns []
diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb
index 219d5d4a..b808bc59 100644
--- a/lib/jekyll/site.rb
+++ b/lib/jekyll/site.rb
@@ -24,9 +24,8 @@ module Jekyll
# Returns nothing
def process
self.read_layouts
- self.read_posts
- self.write_posts
self.transform_pages
+ self.write_posts
end
# Read all the files in /_layouts into memory for
@@ -46,12 +45,11 @@ module Jekyll
# ignore missing layout dir
end
- # Read all the files in /posts and create a new Post
+ # Read all the files in /_posts and create a new Post
# object with each one.
#
# Returns nothing
- def read_posts
- base = File.join(self.source, "_posts")
+ def read_posts(base)
entries = Dir.entries(base)
entries = entries.reject { |e| File.directory?(e) }
@@ -76,7 +74,7 @@ module Jekyll
# Copy all regular files from to / ignoring
# any files/directories that are hidden (start with ".") or contain
- # site content (start with "_")
+ # site content (start with "_") unless they are "_posts" directories
# The +dir+ String is a relative path used to call this method
# recursively as it descends through directories
#
@@ -84,10 +82,14 @@ module Jekyll
def transform_pages(dir = '')
base = File.join(self.source, dir)
entries = Dir.entries(base)
- entries = entries.reject { |e| ['.', '_'].include?(e[0..0]) }
+ entries = entries.reject { |e|
+ (e != '_posts') and ['.', '_'].include?(e[0..0])
+ }
entries.each do |f|
- if File.directory?(File.join(base, f))
+ if f == '_posts'
+ read_posts(File.join(base, f))
+ elsif File.directory?(File.join(base, f))
next if self.dest.sub(/\/$/, '') == File.join(base, f)
transform_pages(File.join(dir, f))
else
@@ -111,7 +113,17 @@ module Jekyll
#
# Returns {"site" => {"time" =>