diff --git a/features/post_excerpts.feature b/features/post_excerpts.feature new file mode 100644 index 00000000..09e41338 --- /dev/null +++ b/features/post_excerpts.feature @@ -0,0 +1,50 @@ +Feature: Post excerpts + As a hacker who likes to blog + I want to be able to make a static site + In order to share my awesome ideas with the interwebs + But some people can only focus for a few moments + So just give them a taste + + Scenario: An excerpt without a layout + Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}" + And I have a _posts directory + And I have the following posts: + | title | date | layout | content | + | entry1 | 2007-12-31 | post | content for entry1. | + When I run jekyll + Then the _site directory should exist + And I should see exactly "
content for entry1.
" in "_site/index.html" + + Scenario: An excerpt from a post with a layout + Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}" + And I have a _posts directory + And I have a _layouts directory + And I have a post layout that contains "{{ page.excerpt }}" + And I have the following posts: + | title | date | layout | content | + | entry1 | 2007-12-31 | post | content for entry1. | + When I run jekyll + Then the _site directory should exist + And the _site/2007 directory should exist + And the _site/2007/12 directory should exist + And the _site/2007/12/31 directory should exist + And the "_site/2007/12/31/entry1.html" file should exist + And I should see exactly "content for entry1.
" in "_site/2007/12/31/entry1.html" + And I should see exactly "content for entry1.
" in "_site/index.html" + + Scenario: An excerpt from a post with a layout which has context + Given I have an "index.html" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}" + And I have a _posts directory + And I have a _layouts directory + And I have a post layout that contains "{{ page.excerpt }}" + And I have the following posts: + | title | date | layout | content | + | entry1 | 2007-12-31 | post | content for entry1. | + When I run jekyll + Then the _site directory should exist + And the _site/2007 directory should exist + And the _site/2007/12 directory should exist + And the _site/2007/12/31 directory should exist + And the "_site/2007/12/31/entry1.html" file should exist + And I should see exactly "content for entry1.
" in "_site/index.html" + And I should see exactly "content for entry1.
" in "_site/2007/12/31/entry1.html" diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb index 9208c4ec..136f048d 100644 --- a/features/step_definitions/jekyll_steps.rb +++ b/features/step_definitions/jekyll_steps.rb @@ -4,6 +4,8 @@ Before do Dir.chdir(TEST_DIR) end +World(Test::Unit::Assertions) + Given /^I have a blank site in "(.*)"$/ do |path| FileUtils.mkdir(path) end @@ -143,6 +145,10 @@ Then /^I should see "(.*)" in "(.*)"$/ do |text, file| assert Regexp.new(text).match(File.open(file).readlines.join) end +Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file| + assert_equal text, File.open(file).readlines.join.strip +end + Then /^I should not see "(.*)" in "(.*)"$/ do |text, file| assert_no_match Regexp.new(text), File.read(file) end diff --git a/lib/jekyll/excerpt.rb b/lib/jekyll/excerpt.rb index 16584963..a02272b5 100644 --- a/lib/jekyll/excerpt.rb +++ b/lib/jekyll/excerpt.rb @@ -1,41 +1,5 @@ module Jekyll class Excerpt - - # Internal: Extract excerpt from the content - # - # By default excerpt is your first paragraph of a post: everything before - # the first two new lines: - # - # --- - # title: Example - # --- - # - # First paragraph with [link][1]. - # - # Second paragraph. - # - # [1]: http://example.com/ - # - # This is fairly good option for Markdown and Textile files. But might cause - # problems for HTML posts (which is quite unusual for Jekyll). If default - # excerpt delimiter is not good for you, you might want to set your own via - # configuration option `excerpt_separator`. For example, following is a good - # alternative for HTML posts: - # - # # file: _config.yml - # excerpt_separator: "" - # - # Notice that all markdown-style link references will be appended to the - # excerpt. So the example post above will have this excerpt source: - # - # First paragraph with [link][1]. - # - # [1]: http://example.com/ - # - # Excerpts are rendered same time as content is rendered. - # - # Returns excerpt String - include Convertible attr_accessor :post @@ -49,22 +13,41 @@ module Jekyll # # Returns the new Post. def initialize(post) - @post = post - @content = extract_excerpt(post.content) + self.post = post + self.content = extract_excerpt(post.content) end - %w[site name data ext].each do |meth| + %w[site name ext].each do |meth| define_method(meth) do post.send(meth) end end + def to_liquid + post.to_liquid(Post::EXCERPT_ATTRIBUTES_FOR_LIQUID) + end + + # Fetch YAML front-matter data from related post, without layout key + # + # Returns Hash of post data + def data + @data ||= post.data.dup + @data.delete("layout") + @data + end + + # 'Path' of the excerpt. + # + # Returns the path for the post this excerpt belongs to with #excerpt appended def path File.join(post.path, "#excerpt") end + # Check if excerpt includes a string + # + # Returns true if the string passed in def include?(something) - (output && output.include?(something)) || content.include?(something) + (self.output && self.output.include?(something)) || self.content.include?(something) end # The UID for this post (useful in feeds). @@ -75,15 +58,8 @@ module Jekyll File.join(post.dir, post.slug, "#excerpt") end - # Convert this post into a Hash for use in Liquid templates. - # - # Returns the representative Hash. - def to_liquid - post.to_liquid - end - def to_s - output || content + self.output || self.content end # Returns the shorthand String identifier of this Post. diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index 1b70e31e..9ad25399 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -10,8 +10,7 @@ module Jekyll # Valid post name regex. MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/ - # Attributes for Liquid templates - ATTRIBUTES_FOR_LIQUID = %w[ + EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[ title url date @@ -20,11 +19,15 @@ module Jekyll next previous tags - content - excerpt path ] + # Attributes for Liquid templates + ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID.concat(%w[ + content + excerpt + ]) + # Post name validator. Post filenames must be like: # 2008-11-05-my-awesome-post.textile # @@ -249,12 +252,12 @@ module Jekyll # construct payload payload = { "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) }, - "page" => self.to_liquid + "page" => self.to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID) }.deep_merge(site_payload) - self.extracted_excerpt.do_layout(payload, layouts) + self.extracted_excerpt.do_layout(payload, {}) - do_layout(payload, layouts) + do_layout(payload.merge({"page" => self.to_liquid}), layouts) end # Obtain destination path. @@ -272,8 +275,8 @@ module Jekyll # Convert this post into a Hash for use in Liquid templates. # # Returns the representative Hash. - def to_liquid - further_data = Hash[ATTRIBUTES_FOR_LIQUID.map { |attribute| + def to_liquid(attrs = ATTRIBUTES_FOR_LIQUID) + further_data = Hash[attrs.map { |attribute| [attribute, send(attribute)] }] data.deep_merge(further_data) diff --git a/lib/jekyll/stevenson.rb b/lib/jekyll/stevenson.rb index b825cea5..898bc09f 100644 --- a/lib/jekyll/stevenson.rb +++ b/lib/jekyll/stevenson.rb @@ -15,6 +15,16 @@ module Jekyll def initialize(level = INFO) @log_level = level end + + # Public: Print a jekyll debug message to stdout + # + # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc. + # message - the message detail + # + # Returns nothing + def debug(topic, message = nil) + $stdout.puts(message(topic, message)) if log_level <= DEBUG + end # Public: Print a jekyll message to stdout # diff --git a/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown b/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown new file mode 100644 index 00000000..07b0e5f3 --- /dev/null +++ b/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown @@ -0,0 +1,23 @@ +--- +layout: post +title: Post Excerpt with Layout +categories: +- bar +- baz +- z_category +tags: +- first +- second +- third +- jekyllrb.com +--- + +First paragraph with [link ref][link]. + +Second paragraph + +--- + +Third paragraph + +[link]: http://www.jekyllrb.com/ diff --git a/test/test_excerpt.rb b/test/test_excerpt.rb new file mode 100644 index 00000000..a72d1bd2 --- /dev/null +++ b/test/test_excerpt.rb @@ -0,0 +1,62 @@ +require 'helper' + +class TestExcerpt < Test::Unit::TestCase + def setup_post(file) + Post.new(@site, source_dir, '', file) + end + + def do_render(post) + layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")} + post.render(layouts, {"site" => {"posts" => []}}) + end + + context "An extracted excerpt" do + setup do + clear_dest + stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS } + @site = Site.new(Jekyll.configuration) + @post = setup_post("2013-07-22-post-excerpt-with-layout.markdown") + @excerpt = @post.send :extract_excerpt + end + + context "#to_liquid" do + should "contain the proper page data to mimick the post liquid" do + assert_equal "Post Excerpt with Layout", @excerpt.to_liquid["title"] + assert_equal "/bar/baz/z_category/2013/07/22/post-excerpt-with-layout.html", @excerpt.to_liquid["url"] + assert_equal Time.parse("2013-07-22"), @excerpt.to_liquid["date"] + assert_equal %w[bar baz z_category], @excerpt.to_liquid["categories"] + assert_equal %w[first second third jekyllrb.com], @excerpt.to_liquid["tags"] + assert_equal "_posts/2013-07-22-post-excerpt-with-layout.markdown", @excerpt.to_liquid["path"] + end + end + + context "#content" do + + context "before render" do + should "be the first paragraph of the page" do + assert_equal "First paragraph with [link ref][link].\n\n[link]: http://www.jekyllrb.com/", @excerpt.content + end + + should "contain any refs at the bottom of the page" do + assert @excerpt.content.include?("[link]: http://www.jekyllrb.com/") + end + end + + context "after render" do + setup do + @rendered_post = @post.dup + do_render(@rendered_post) + @extracted_excerpt = @rendered_post.send :extracted_excerpt + end + + should "be the first paragraph of the page" do + assert_equal "First paragraph with link ref.
", @extracted_excerpt.content + end + + should "link properly" do + assert @extracted_excerpt.content.include?("http://www.jekyllrb.com/") + end + end + end + end +end diff --git a/test/test_generated_site.rb b/test/test_generated_site.rb index 35c451c5..dd24187f 100644 --- a/test/test_generated_site.rb +++ b/test/test_generated_site.rb @@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase end should "ensure post count is as expected" do - assert_equal 34, @site.posts.size + assert_equal 35, @site.posts.size end should "insert site.posts into the index" do