Merge pull request #1339 from mojombo/no-layouts-for-excerpt

No layouts for excerpt
This commit is contained in:
Matt Rogers 2013-07-23 18:43:08 -07:00
commit d68d29c06f
8 changed files with 188 additions and 58 deletions

View File

@ -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 "<p>content for entry1.</p>" 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 "<p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
And I should see exactly "<p>content for entry1.</p>" 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 "<html><head></head><body>{{ page.excerpt }}</body></html>"
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 "<p>content for entry1.</p>" in "_site/index.html"
And I should see exactly "<html><head></head><body><p>content for entry1.</p></body></html>" in "_site/2007/12/31/entry1.html"

View File

@ -4,6 +4,8 @@ Before do
Dir.chdir(TEST_DIR) Dir.chdir(TEST_DIR)
end end
World(Test::Unit::Assertions)
Given /^I have a blank site in "(.*)"$/ do |path| Given /^I have a blank site in "(.*)"$/ do |path|
FileUtils.mkdir(path) FileUtils.mkdir(path)
end end
@ -143,6 +145,10 @@ Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
assert Regexp.new(text).match(File.open(file).readlines.join) assert Regexp.new(text).match(File.open(file).readlines.join)
end 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| Then /^I should not see "(.*)" in "(.*)"$/ do |text, file|
assert_no_match Regexp.new(text), File.read(file) assert_no_match Regexp.new(text), File.read(file)
end end

View File

@ -1,41 +1,5 @@
module Jekyll module Jekyll
class Excerpt 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: "<!-- more -->"
#
# 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 include Convertible
attr_accessor :post attr_accessor :post
@ -49,22 +13,41 @@ module Jekyll
# #
# Returns the new Post. # Returns the new Post.
def initialize(post) def initialize(post)
@post = post self.post = post
@content = extract_excerpt(post.content) self.content = extract_excerpt(post.content)
end end
%w[site name data ext].each do |meth| %w[site name ext].each do |meth|
define_method(meth) do define_method(meth) do
post.send(meth) post.send(meth)
end end
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 def path
File.join(post.path, "#excerpt") File.join(post.path, "#excerpt")
end end
# Check if excerpt includes a string
#
# Returns true if the string passed in
def include?(something) def include?(something)
(output && output.include?(something)) || content.include?(something) (self.output && self.output.include?(something)) || self.content.include?(something)
end end
# The UID for this post (useful in feeds). # The UID for this post (useful in feeds).
@ -75,15 +58,8 @@ module Jekyll
File.join(post.dir, post.slug, "#excerpt") File.join(post.dir, post.slug, "#excerpt")
end 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 def to_s
output || content self.output || self.content
end end
# Returns the shorthand String identifier of this Post. # Returns the shorthand String identifier of this Post.

View File

@ -10,8 +10,7 @@ module Jekyll
# Valid post name regex. # Valid post name regex.
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/ MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
# Attributes for Liquid templates EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
ATTRIBUTES_FOR_LIQUID = %w[
title title
url url
date date
@ -20,11 +19,15 @@ module Jekyll
next next
previous previous
tags tags
content
excerpt
path path
] ]
# Attributes for Liquid templates
ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID.concat(%w[
content
excerpt
])
# Post name validator. Post filenames must be like: # Post name validator. Post filenames must be like:
# 2008-11-05-my-awesome-post.textile # 2008-11-05-my-awesome-post.textile
# #
@ -249,12 +252,12 @@ module Jekyll
# construct payload # construct payload
payload = { payload = {
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) }, "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) }.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 end
# Obtain destination path. # Obtain destination path.
@ -272,8 +275,8 @@ module Jekyll
# Convert this post into a Hash for use in Liquid templates. # Convert this post into a Hash for use in Liquid templates.
# #
# Returns the representative Hash. # Returns the representative Hash.
def to_liquid def to_liquid(attrs = ATTRIBUTES_FOR_LIQUID)
further_data = Hash[ATTRIBUTES_FOR_LIQUID.map { |attribute| further_data = Hash[attrs.map { |attribute|
[attribute, send(attribute)] [attribute, send(attribute)]
}] }]
data.deep_merge(further_data) data.deep_merge(further_data)

View File

@ -15,6 +15,16 @@ module Jekyll
def initialize(level = INFO) def initialize(level = INFO)
@log_level = level @log_level = level
end 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 # Public: Print a jekyll message to stdout
# #

View File

@ -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/

62
test/test_excerpt.rb Normal file
View File

@ -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 "<p>First paragraph with <a href='http://www.jekyllrb.com/'>link ref</a>.</p>", @extracted_excerpt.content
end
should "link properly" do
assert @extracted_excerpt.content.include?("http://www.jekyllrb.com/")
end
end
end
end
end

View File

@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase
end end
should "ensure post count is as expected" do should "ensure post count is as expected" do
assert_equal 34, @site.posts.size assert_equal 35, @site.posts.size
end end
should "insert site.posts into the index" do should "insert site.posts into the index" do