Merge pull request #764 from mojombo/jekyll-new

`jekyll new`: scaffold site generator
This commit is contained in:
Parker Moore 2013-03-17 07:47:56 -07:00
commit e2d0697f30
13 changed files with 502 additions and 0 deletions

View File

@ -30,6 +30,15 @@ def normalize_options(options)
options options
end end
command :new do |c|
c.syntax = 'jekyll new PATH'
c.description = 'Creates a new Jekyll site scaffold in PATH'
c.action do |args, options|
Jekyll::Commands::New.process(args)
end
end
command :build do |c| command :build do |c|
c.syntax = 'jekyll build [options]' c.syntax = 'jekyll build [options]'
c.description = 'Build your site' c.description = 'Build your site'

View File

@ -70,6 +70,8 @@ Gem::Specification.new do |s|
lib/jekyll.rb lib/jekyll.rb
lib/jekyll/command.rb lib/jekyll/command.rb
lib/jekyll/commands/build.rb lib/jekyll/commands/build.rb
lib/jekyll/commands/migrate.rb
lib/jekyll/commands/new.rb
lib/jekyll/commands/serve.rb lib/jekyll/commands/serve.rb
lib/jekyll/converter.rb lib/jekyll/converter.rb
lib/jekyll/converters/identity.rb lib/jekyll/converters/identity.rb
@ -93,6 +95,15 @@ Gem::Specification.new do |s|
lib/jekyll/tags/highlight.rb lib/jekyll/tags/highlight.rb
lib/jekyll/tags/include.rb lib/jekyll/tags/include.rb
lib/jekyll/tags/post_url.rb lib/jekyll/tags/post_url.rb
lib/site_template/_config.yml
lib/site_template/_layouts/default.html
lib/site_template/_layouts/post.html
lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
lib/site_template/css/screen.css
lib/site_template/css/syntax.css
lib/site_template/images/.gitkeep
lib/site_template/images/rss.png
lib/site_template/index.html
script/bootstrap script/bootstrap
site/.gitignore site/.gitignore
site/CNAME site/CNAME

View File

@ -0,0 +1,46 @@
require 'erb'
module Jekyll
module Commands
class New < Command
def self.process(args)
raise ArgumentError.new('You must specify a path.') if args.empty?
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
FileUtils.mkdir_p new_blog_path
create_sample_files new_blog_path
File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
f.write(self.scaffold_post_content(site_template))
end
puts "New jekyll site installed in #{new_blog_path}."
end
def self.scaffold_post_content(template_site)
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
end
# Internal: Gets the filename of the sample post to be created
#
# Returns the filename of the sample post, as a String
def self.initialized_post_name
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
end
private
def self.create_sample_files(path)
FileUtils.cp_r site_template + '/.', path
FileUtils.rm File.expand_path(scaffold_path, path)
end
def self.site_template
File.expand_path("../../site_template", File.dirname(__FILE__))
end
def self.scaffold_path
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
end
end
end
end

View File

@ -0,0 +1,2 @@
markdown: rdiscount
pygments: true

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>{{ page.title }}</title>
<!-- syntax highlighting CSS -->
<link rel="stylesheet" href="/css/syntax.css" type="text/css" />
<!-- Homepage CSS -->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen, projection" />
</head>
<body>
<div class="site">
<div class="title">
<a href="/">Your Name</a>
<a class="extra" href="/">home</a>
</div>
{{ content }}
<div class="footer">
<div class="contact">
<p>
Your Name<br />
What You Are<br />
your@email.com
</p>
</div>
<div class="contact">
<p>
<a href="http://github.com/yourusername/">github.com/yourusername</a><br />
<a href="http://twitter.com/yourusername/">twitter.com/yourusername</a><br />
</p>
</div>
</div>
</div>
<a href="http://github.com/yourusername"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub" /></a>
</body>
</html>

View File

@ -0,0 +1,6 @@
---
layout: default
---
<div id="post">
{{ content }}
</div>

View File

@ -0,0 +1,24 @@
---
layout: post
title: "Welcome to Jekyll!"
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
categories: jekyll update
---
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
Jekyll also offers powerful support for code snippets:
{% highlight ruby %}
def print_hi(name)
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endhighlight %}
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
[jekyll-gh]: https://github.com/mojombo/jekyll
[jekyll]: http://jekyllrb.com

View File

@ -0,0 +1,189 @@
/*****************************************************************************/
/*
/* Common
/*
/*****************************************************************************/
/* Global Reset */
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background-color: white;
font: 13.34px helvetica, arial, clean, sans-serif;
*font-size: small;
text-align: center;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
}
h1 {
margin-bottom: 1em;
}
p {
margin: 1em 0;
}
a {
color: #00a;
}
a:hover {
color: black;
}
a:visited {
color: #a0a;
}
table {
font-size: inherit;
font: 100%;
}
/*****************************************************************************/
/*
/* Home
/*
/*****************************************************************************/
ul.posts {
list-style-type: none;
margin-bottom: 2em;
}
ul.posts li {
line-height: 1.75em;
}
ul.posts span {
color: #aaa;
font-family: Monaco, "Courier New", monospace;
font-size: 80%;
}
/*****************************************************************************/
/*
/* Site
/*
/*****************************************************************************/
.site {
font-size: 110%;
text-align: justify;
width: 42em;
margin: 3em auto 2em auto;
line-height: 1.5em;
}
.title {
color: #a00;
font-weight: bold;
margin-bottom: 2em;
}
.site .title a {
color: #a00;
text-decoration: none;
}
.site .title a:hover {
color: black;
}
.site .title a.extra {
color: #aaa;
text-decoration: none;
margin-left: 1em;
}
.site .title a.extra:hover {
color: black;
}
.site .meta {
color: #aaa;
}
.site .footer {
font-size: 80%;
color: #666;
border-top: 4px solid #eee;
margin-top: 2em;
overflow: hidden;
}
.site .footer .contact {
float: left;
margin-right: 3em;
}
.site .footer .contact a {
color: #8085C1;
}
.site .footer .rss {
margin-top: 1.1em;
margin-right: -.2em;
float: right;
}
.site .footer .rss img {
border: 0;
}
/*****************************************************************************/
/*
/* Posts
/*
/*****************************************************************************/
#post {
}
/* standard */
#post pre {
border: 1px solid #ddd;
background-color: #eef;
padding: 0 .4em;
}
#post ul,
#post ol {
margin-left: 1.35em;
}
#post code {
border: 1px solid #ddd;
background-color: #eef;
font-size: 85%;
padding: 0 .2em;
}
#post pre code {
border: none;
}
/* terminal */
#post pre.terminal {
border: 1px solid black;
background-color: #333;
color: white;
}
#post pre.terminal code {
background-color: #333;
}

View File

@ -0,0 +1,60 @@
.highlight { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,13 @@
---
layout: default
title: Your New Jekyll Site
---
<div id="home">
<h1>Blog Posts</h1>
<ul class="posts">
{% for post in site.posts %}
<li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</div>

104
test/test_new_command.rb Normal file
View File

@ -0,0 +1,104 @@
require 'helper'
require 'jekyll/commands/new'
class TestNewCommand < Test::Unit::TestCase
def dir_contents(path)
Dir["#{path}/**/*"].each do |file|
file.gsub! path, ''
end
end
def site_template
File.expand_path("../lib/site_template", File.dirname(__FILE__))
end
context 'when args contains a path' do
setup do
@path = 'new-site'
@args = [@path]
@full_path = File.expand_path(@path, Dir.pwd)
end
teardown do
FileUtils.rm_r @full_path
end
should 'create a new directory' do
assert !File.exists?(@full_path)
capture_stdout { Jekyll::Commands::New.process(@args) }
assert File.exists?(@full_path)
end
should 'display a success message' do
output = capture_stdout { Jekyll::Commands::New.process(@args) }
success_message = "New jekyll site installed in #{@full_path}.\n"
assert_equal success_message, output
end
should 'copy the static files in site template to the new directory' do
static_template_files = dir_contents(site_template).reject do |f|
File.extname(f) == '.erb'
end
capture_stdout { Jekyll::Commands::New.process(@args) }
new_site_files = dir_contents(@full_path).reject do |f|
File.extname(f) == '.markdown'
end
assert_same_elements static_template_files, new_site_files
end
should 'process any ERB files' do
erb_template_files = dir_contents(site_template).select do |f|
File.extname(f) == '.erb'
end
stubbed_date = '2013-01-01'
stub.instance_of(Time).strftime { stubbed_date }
erb_template_files.each do |f|
f.chomp! '.erb'
f.gsub! '0000-00-00', stubbed_date
end
capture_stdout { Jekyll::Commands::New.process(@args) }
new_site_files = dir_contents(@full_path).select do |f|
erb_template_files.include? f
end
assert_same_elements erb_template_files, new_site_files
end
end
context 'when multiple args are given' do
setup do
@site_name_with_spaces = 'new site name'
@multiple_args = @site_name_with_spaces.split
end
teardown do
FileUtils.rm_r File.expand_path(@site_name_with_spaces, Dir.pwd)
end
should 'create a new directory' do
assert !File.exists?(@site_name_with_spaces)
capture_stdout { Jekyll::Commands::New.process(@multiple_args) }
assert File.exists?(@site_name_with_spaces)
end
end
context 'when no args are given' do
setup do
@empty_args = []
end
should 'raise an ArgumentError' do
exception = assert_raise ArgumentError do
Jekyll::Commands::New.process(@empty_args)
end
assert_equal 'You must specify a path.', exception.message
end
end
end