Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 13 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
Commits on Sep 30, 2009
Mike West Porting Mat Flores' work from 0bd5b3a
Commits on Oct 04, 2009
@mikewest mikewest Liquid Extension: Adding 'markdownize' filter. c264952
@mikewest mikewest Adding page generation for individual tags. 34b5192
@mikewest mikewest Changing `tag_index` to `tag_detail`. I'll be adding a tag "index"
later, and don't want to come up with a new name.  :)
c89c926
@mikewest mikewest Typo in 'tag_details' function name 0ea2109
@mikewest mikewest Adding the rest of Mat Flores' archive support
Pulling from
http://github.com/matflores/jekyll/commit/6f580f802729d1b8ac54d12ce1d022a2d349311a
and updating to run under 0.5.4.

Apparently this is causing some problems with the Pager class.  Looking
into that now.
2cb98d1
@mikewest mikewest Merging branch 'archive' 6e509d7
Commits on Oct 05, 2009
@mikewest mikewest Adding `content_root` config option
I'd like to be able to pull in post content from a directory outside of
the site root.  I've added a `content_root` option in order to make that
possible.

Specifying an absolute path to a directory will parse files in that
directory exactly as though they were located in your site's `_posts`
directory, publishing them according to the same rules you've defined in
your site's `_config.yaml`.
c39af8a
@mikewest mikewest Adding tests for external content root
Simple tests to make sure things are at least mostly sane.  They are.
44b2513
Commits on Oct 06, 2009
@mikewest mikewest Fixing a bug in category parsing for external content root 5335724
Commits on Oct 18, 2009
@mikewest mikewest Adding `content_root` config option
I'd like to be able to pull in post content from a directory outside of
the site root.  I've added a `content_root` option in order to make that
possible.

Specifying an absolute path to a directory will parse files in that
directory exactly as though they were located in your site's `_posts`
directory, publishing them according to the same rules you've defined in
your site's `_config.yaml`.
745c19d
@mikewest mikewest Fixing one real bug, and two merge errors.
*   I need to process `content_root` _before_ calling `transform_pages`,
    as the data otherwise won't be available in `site.posts`.

*   Idiotic merge errors caused a comma to go missing, and an `end` to
    drop off the planet.
69a6d86
@mikewest mikewest Markdown should run smartypants as well. 0d11745
View
3 lib/jekyll.rb
@@ -26,6 +26,8 @@
require 'jekyll/tags/highlight'
require 'jekyll/tags/include'
require 'jekyll/albino'
+require 'jekyll/tag_detail'
+require 'jekyll/archive'
module Jekyll
# Default options. Overriden by values in _config.yml or command-line opts.
@@ -36,6 +38,7 @@ module Jekyll
'server_port' => 4000,
'source' => '.',
+ 'content_root' => File.join('.', '_posts'),
'destination' => File.join('.', '_site'),
'lsi' => false,
View
26 lib/jekyll/archive.rb
@@ -0,0 +1,26 @@
+module Jekyll
+
+ class Archive < Page
+ # Initialize a new Archive.
+ # +base+ is the String path to the <source>
+ # +dir+ is the String path between <source> and the file
+ #
+ # Returns <Archive>
+ def initialize(site, base, dir, type)
+ @site = site
+ @base = base
+ @dir = dir
+ @name = 'index.html'
+
+ self.process(@name)
+
+ self.read_yaml(File.join(base, '_layouts'), type + '.html')
+
+ year, month, day = dir.split('/')
+ self.data['year'] = year.to_i
+ month and self.data['month'] = month.to_i
+ day and self.data['day'] = day.to_i
+ end
+ end
+
+end
View
21 lib/jekyll/filters.rb
@@ -5,6 +5,20 @@ def textilize(input)
RedCloth.new(input).to_html
end
+ def markdownize(input)
+ if input
+ if defined? RDiscount
+ RDiscount.new(input, :smart).to_html
+ elsif defined? Maruku
+ Maruku.new(input, :smart).to_html
+ else
+ input
+ end
+ else
+ ''
+ end
+ end
+
def date_to_string(date)
date.strftime("%d %b %Y")
end
@@ -43,5 +57,12 @@ def array_to_sentence_string(array)
end
end
+ def to_month(input)
+ return Date::MONTHNAMES[input.to_i]
+ end
+
+ def to_month_abbr(input)
+ return Date::ABBR_MONTHNAMES[input.to_i]
+ end
end
end
View
9 lib/jekyll/post.rb
@@ -34,7 +34,14 @@ def categories
# Returns <Post>
def initialize(site, source, dir, name)
@site = site
- @base = File.join(source, dir, '_posts')
+ if File.directory?(dir)
+ @base = dir
+ if dir == site.content_root
+ dir = ''
+ end
+ else
+ @base = File.join(source, dir, '_posts')
+ end
@name = name
self.categories = dir.split('/').reject { |x| x.empty? }
View
93 lib/jekyll/site.rb
@@ -1,8 +1,9 @@
module Jekyll
class Site
- attr_accessor :config, :layouts, :posts, :categories, :exclude,
- :source, :dest, :lsi, :pygments, :permalink_style, :tags
+ attr_accessor :config, :layouts, :posts, :categories, :exclude, :content_root,
+ :source, :dest, :lsi, :pygments, :permalink_style,
+ :tags, :collated
# Initialize the site
# +config+ is a Hash containing site configurations details
@@ -12,6 +13,7 @@ def initialize(config)
self.config = config.clone
self.source = config['source']
+ self.content_root = config['content_root']
self.dest = config['destination']
self.lsi = config['lsi']
self.pygments = config['pygments']
@@ -27,6 +29,7 @@ def reset
self.posts = []
self.categories = Hash.new { |hash, key| hash[key] = [] }
self.tags = Hash.new { |hash, key| hash[key] = [] }
+ self.collated = {}
end
def setup
@@ -40,7 +43,7 @@ def setup
require 'rdiscount'
def markdown(content)
- RDiscount.new(content).to_html
+ RDiscount.new(content, :smart).to_html
end
rescue LoadError
@@ -51,7 +54,7 @@ def markdown(content)
require 'maruku'
def markdown(content)
- Maruku.new(content).to_html
+ Maruku.new(content, :smart).to_html
end
if self.config['maruku']['use_divs']
@@ -93,8 +96,13 @@ def textile(content)
def process
self.reset
self.read_layouts
+ if self.content_root
+ self.read_posts(self.content_root)
+ end
self.transform_pages
self.write_posts
+ self.write_tag_details
+ self.write_archives
end
# Read all the files in <source>/_layouts into memory for later use.
@@ -117,7 +125,11 @@ def read_layouts
#
# Returns nothing
def read_posts(dir)
- base = File.join(self.source, dir, '_posts')
+ if File.directory?(dir)
+ base = dir
+ else
+ base = File.join(self.source, dir, '_posts')
+ end
entries = []
Dir.chdir(base) { entries = filter_entries(Dir['**/*']) }
@@ -143,6 +155,20 @@ def read_posts(dir)
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a} }
self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a} }
+
+ self.posts.reverse.each do |post|
+ y, m, d = post.date.year, post.date.month, post.date.day
+ unless self.collated.key? y
+ self.collated[ y ] = {}
+ end
+ unless self.collated[y].key? m
+ self.collated[ y ][ m ] = {}
+ end
+ unless self.collated[ y ][ m ].key? d
+ self.collated[ y ][ m ][ d ] = []
+ end
+ self.collated[ y ][ m ][ d ] += [ post ]
+ end
rescue Errno::ENOENT => e
# ignore missing layout dir
end
@@ -156,6 +182,53 @@ def write_posts
end
end
+ # Write each tag page
+ #
+ # Returns nothing
+ def write_tag_detail(dir, tag)
+ index = TagIndex.new(self, self.source, dir, tag)
+ index.render(self.layouts, site_payload)
+ index.write(self.dest)
+ end
+
+ def write_tag_details
+ if self.layouts.key? 'tag_detail'
+ self.tags.keys.each do |tag|
+ self.write_tag_detail(File.join('tags', tag), tag)
+ end
+ end
+ end
+
+ # Write post archives to <dest>/<year>/, <dest>/<year>/<month>/,
+ # <dest>/<year>/<month>/<day>/
+ #
+ # Returns nothing
+ def write_archive( dir, type )
+ archive = Archive.new( self, self.source, dir, type )
+ archive.render( self.layouts, site_payload )
+ archive.write( self.dest )
+ end
+
+ def write_archives
+ self.collated.keys.each do |y|
+ if self.layouts.key? 'archive_yearly'
+ self.write_archive( y.to_s, 'archive_yearly' )
+ end
+
+ self.collated[ y ].keys.each do |m|
+ if self.layouts.key? 'archive_monthly'
+ self.write_archive( "%04d/%02d" % [ y.to_s, m.to_s ], 'archive_monthly' )
+ end
+
+ self.collated[ y ][ m ].keys.each do |d|
+ if self.layouts.key? 'archive_daily'
+ self.write_archive( "%04d/%02d/%02d" % [ y.to_s, m.to_s, d.to_s ], 'archive_daily' )
+ end
+ end
+ end
+ end
+ end
+
# Copy all regular files from <source> to <dest>/ ignoring
# any files/directories that are hidden or backup files (start
# with "." or "#" or end with "~") or contain site content (start with "_")
@@ -218,13 +291,15 @@ def post_attr_hash(post_attr)
#
# Returns {"site" => {"time" => <Time>,
# "posts" => [<Post>],
+ # "collated_posts" => [<Post>],
# "categories" => [<Post>]}
def site_payload
{"site" => self.config.merge({
- "time" => Time.now,
- "posts" => self.posts.sort { |a,b| b <=> a },
- "categories" => post_attr_hash('categories'),
- "tags" => post_attr_hash('tags')})}
+ "time" => Time.now,
+ "posts" => self.posts.sort { |a,b| b <=> a },
+ "collated_posts" => self.collated,
+ "categories" => post_attr_hash('categories'),
+ "tags" => post_attr_hash('tags')})}
end
# Filter out any files/directories that are hidden or backup files (start
View
20 lib/jekyll/tag_detail.rb
@@ -0,0 +1,20 @@
+module Jekyll
+
+ class TagIndex < Page
+ # Initialize a new TagIndex.
+ # +base+ is the String path to the <source>
+ # +dir+ is the String path between <source> and the file
+ #
+ # Returns <TagIndex>
+ def initialize(site, base, dir, tag)
+ @site = site
+ @base = base
+ @dir = dir
+ @name = 'index.html'
+ self.process(@name)
+ self.read_yaml(File.join(base, '_layouts'), 'tag_detail.html')
+ self.data['tag'] = tag
+ end
+ end
+
+end
View
7 test/external_content_root/2009-10-05-external-content-root.markdown
@@ -0,0 +1,7 @@
+---
+layout: default
+title: Published from an external content root.
+category: external
+---
+This should be published, even though it does not live in the normal `_posts`
+directory with all the other posts.
View
6 test/helper.rb
@@ -1,5 +1,5 @@
require 'rubygems'
-gem 'RedCloth', '= 4.2.1'
+gem 'RedCloth', '>= 4.2.1'
require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
@@ -21,6 +21,10 @@ def source_dir(*subdirs)
File.join(File.dirname(__FILE__), 'source', *subdirs)
end
+ def external_source_dir(*subdirs)
+ File.join(File.dirname(__FILE__), 'external_content_root', *subdirs)
+ end
+
def clear_dest
FileUtils.rm_rf(dest_dir)
end
View
10 test/source/_layouts/archive_daily.html
@@ -0,0 +1,10 @@
+---
+layout: default
+---
+
+<h1>{{ page.month | to_month }} {{ page.day }}, {{ page.year }}</h1>
+<ul>
+ {% for p in site.collated_posts[page.year][page.month][page.day] reversed %}
+ <li><a href='{{ p.url }}'>{{ p.title }}</a></li>
+ {% endfor %}
+</ul>
View
14 test/source/_layouts/archive_monthly.html
@@ -0,0 +1,14 @@
+---
+layout: default
+---
+
+<h1>{{ page.month | to_month }} {{ page.year }}</h1>
+<ul>
+ {% for d in (1..31) reversed %}
+ {% if site.collated_posts[page.year][page.month][d] %}
+ {% for p in site.collated_posts[page.year][page.month][d] reversed %}
+ <li><a href='{{ p.url }}'>{{ p.title }}</a></li>
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+</ul>
View
22 test/source/_layouts/archive_yearly.html
@@ -0,0 +1,22 @@
+---
+layout: default
+---
+
+<h1>{{ page.year }}</h1>
+<ul>
+{% for m in (1..12) reversed %}
+ {% if site.collated_posts[page.year][m] %}
+ <li>{{ m | to_month }}
+ <ul>
+ {% for d in (1..31) reversed %}
+ {% if site.collated_posts[page.year][m][d] %}
+ {% for p in site.collated_posts[page.year][m][d] reversed %}
+ <li><a href='{{ p.url }}'>{{ p.title }}</a></li>
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+ </ul>
+ </li>
+ {% endif %}
+{% endfor %}
+</ul>
View
10 test/source/_layouts/tag_detail.html
@@ -0,0 +1,10 @@
+---
+layout: default
+---
+
+<h1>Tag: {{ page.tag }} ({{ site.tags[page.tag] | size }} posts)</h1>
+<ul>
+ {% for p in site.categories[page.tag] reversed %}
+ <li><a href='{{ p.url }}'>{{ p.title }}</a></li>
+ {% endfor %}
+</ul>
View
27 test/test_generated_site.rb
@@ -36,5 +36,32 @@ class TestGeneratedSite < Test::Unit::TestCase
assert File.exists?(dest_dir('/about/index.html'))
assert File.exists?(dest_dir('/contacts.html'))
end
+
+ should "generate index pages for tags" do
+ ['code', 'food', 'pizza'].each {|tag|
+ filename = dest_dir("/tags/#{tag}/index.html")
+
+ assert File.exists?(filename)
+ assert File.read(filename).include?("<h1>Tag: #{tag} (1 posts)</h1>")
+ }
+ end
+ should "create yearly archive for 2008" do
+ filename = File.join(dest_dir, '2008', 'index.html')
+ assert File.exists?(filename)
+ assert File.read(filename).include?("<h1>2008</h1>")
+ end
+
+ should "create monthly archive for 2008/02" do
+ filename = File.join(dest_dir, '2008', '02', 'index.html')
+ assert File.exists?(filename)
+ assert File.read(filename).include?("<h1>February 2008</h1>")
+ end
+
+ should "create daily archive for 2008/02/02" do
+ filename = File.join(dest_dir, '2008', '02', '02', 'index.html')
+ assert File.exists?(filename)
+ assert File.read(filename).include?("<h1>February 2, 2008</h1>")
+ end
+
end
end
View
26 test/test_post.rb
@@ -5,6 +5,10 @@ def setup_post(file)
Post.new(@site, source_dir, '', file)
end
+ def setup_external_post(file)
+ Post.new(@site, source_dir, @content_root, file)
+ end
+
def do_render(post)
layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")}
post.render(layouts, {"site" => {"posts" => []}})
@@ -298,5 +302,27 @@ def do_render(post)
assert_equal ['foo'], post.categories
end
+ context "in an external content root" do
+ context "rendering" do
+ setup do
+ clear_dest
+ @content_root = File.join(File.expand_path(File.dirname(__FILE__)), "external_content_root")
+ stub(Jekyll).configuration do
+ Jekyll::DEFAULTS.merge({ 'content_root' => @content_root })
+ end
+ @site = Site.new(Jekyll.configuration)
+ end
+ should "render properly" do
+ post = setup_external_post("2009-10-05-external-content-root.markdown")
+ do_render(post)
+
+ assert_equal "<<< <p>This should be published, even though it does not live in the normal <code>_posts</code> directory with all the other posts.</p> >>>", post.output
+ end
+ should "have the correct categories" do
+ post = setup_external_post("2009-10-05-external-content-root.markdown")
+ assert_equal ['external'], post.categories
+ end
+ end
+ end
end
end
View
33 test/test_site.rb
@@ -28,7 +28,7 @@ class TestSite < Test::Unit::TestCase
should "read layouts" do
@site.read_layouts
- assert_equal ["default", "simple"].sort, @site.layouts.keys.sort
+ assert_equal ["default", "simple", "tag_detail", "archive_yearly", "archive_monthly", "archive_daily"].sort, @site.layouts.keys.sort
end
should "read posts" do
@@ -65,6 +65,37 @@ class TestSite < Test::Unit::TestCase
@site.exclude = excludes
assert_equal includes, @site.filter_entries(excludes + includes)
end
+
+ context 'with a valid external content root' do
+ setup do
+ @content_root = File.join(File.expand_path(File.dirname(__FILE__)), "external_content_root")
+ stub(Jekyll).configuration do
+ Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'content_root' => @content_root })
+ end
+ @site = Site.new(Jekyll.configuration)
+ end
+
+ should "read posts when the root is explicitly specified" do
+ @site.read_posts(@content_root)
+ posts = Dir[external_source_dir('**', '*')]
+ assert_equal posts.size, @site.posts.size
+ end
+
+ should "correct categorize posts" do
+ @site.read_posts(@content_root)
+ posts = Dir[external_source_dir('**', '*')]
+ assert_equal 1, @site.categories['external'].size
+ end
+
+ should "contain externally rooted posts when processed" do
+ clear_dest
+ @site.process
+
+ posts = Dir[external_source_dir('**', '*')]
+ posts += Dir[source_dir("**", "_posts", "*")]
+ assert_equal posts.size - 1, @site.posts.size
+ end
+ end
context 'with an invalid markdown processor in the configuration' do

No commit comments for this range

Something went wrong with that request. Please try again.