From 3a8f7a8e3a20778573e782514e535e9a2ddcad49 Mon Sep 17 00:00:00 2001 From: Mark Reid Date: Tue, 16 Dec 2008 17:52:00 +1100 Subject: [PATCH 1/4] Added post categories based on directories containing _posts --- README.textile | 36 +++++++++++++++++++++++++++++++++--- lib/jekyll.rb | 1 + lib/jekyll/filters.rb | 5 ++--- lib/jekyll/post.rb | 11 +++++++---- lib/jekyll/site.rb | 30 +++++++++++++++++++++--------- test/test_post.rb | 2 +- test/test_site.rb | 4 ++-- 7 files changed, 67 insertions(+), 22 deletions(-) diff --git a/README.textile b/README.textile index 75064b93..5bfdc4df 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 @@ -158,6 +166,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 @@ -177,6 +188,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 @@ -289,6 +303,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: + +
+{% for post in site.categories.foo %}
+	
  • {{ post.date | date_to_string }} - {{ post.title }}
  • +{% 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 e23382e1..aa67073e 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/filters.rb b/lib/jekyll/filters.rb index 58191ec7..087a0c98 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -15,7 +15,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" =>