449 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			449 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
h1. Jekyll
 | 
						|
 | 
						|
Jekyll is a simple, blog aware, static site generator. It takes a template
 | 
						|
directory (representing the raw form of a website), runs it through Textile or
 | 
						|
Markdown and Liquid converters, and spits out a complete, static website
 | 
						|
suitable for serving with Apache or your favorite web server. Visit
 | 
						|
"http://tom.preston-werner.com":http://tom.preston-werner.com to see an
 | 
						|
example of a Jekyll generated blog.
 | 
						|
 | 
						|
To understand how this all works, open up my
 | 
						|
"TPW":http://github.com/mojombo/tpw repo in a new browser window. I'll be
 | 
						|
referencing the code there.
 | 
						|
 | 
						|
Take a look at
 | 
						|
"index.html":http://github.com/mojombo/tpw/tree/master/index.html. This file
 | 
						|
represents the homepage of the site. At the top of the file is a chunk of YAML
 | 
						|
that contains metadata about the file. This data tells Jekyll what layout to
 | 
						|
give the file, what the page's title should be, etc. In this case, I specify
 | 
						|
that the "default" template should be used. You can find the layout files in
 | 
						|
the "_layouts":http://github.com/mojombo/tpw/tree/master/_layouts directory.
 | 
						|
If you open
 | 
						|
"default.html":http://github.com/mojombo/tpw/tree/master/_layouts/default.html
 | 
						|
you can see that the homepage is constructed by wrapping index.html with this
 | 
						|
layout.
 | 
						|
 | 
						|
You'll also notice Liquid templating code in these files.
 | 
						|
"Liquid":http://www.liquidmarkup.org/ is a simple, extensible templating
 | 
						|
language that makes it easy to embed data in your templates. For my homepage I
 | 
						|
wanted to have a list of all my blog posts. Jekyll hands me a Hash containing
 | 
						|
various data about my site. A reverse chronological list of all my blog posts
 | 
						|
can be found in <code>site.posts</code>. Each post, in turn, contains various
 | 
						|
fields such as <code>title</code> and <code>date</code>.
 | 
						|
 | 
						|
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.
 | 
						|
GitHub renders textile files by default, so to better understand the file,
 | 
						|
click on the
 | 
						|
"raw":http://github.com/mojombo/tpw/tree/master/_posts/2008-11-17-blogging-like-a-hacker.textile?raw=true
 | 
						|
view to see the original file. Here I've specified the <code>post</code>
 | 
						|
layout. If you look at that file you'll see an example of a nested layout.
 | 
						|
Layouts can contain other layouts allowing you a great deal of flexibility in
 | 
						|
how pages are assembled. In my case I use a nested layout in order to show
 | 
						|
related posts for each blog entry. The YAML also specifies the post's title
 | 
						|
which is then embedded in the post's body via Liquid.
 | 
						|
 | 
						|
Posts are handled in a special way by Jekyll. The date you specify in the
 | 
						|
filename is used to construct the URL in the generated site. The example post,
 | 
						|
for instance, ends up at
 | 
						|
<code>http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html</code>.
 | 
						|
 | 
						|
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
 | 
						|
interpreter. Binary files are copied over unmodified.
 | 
						|
 | 
						|
Jekyll is still a very young project. I've only developed the exact
 | 
						|
functionality that I've needed. As time goes on I'd like to see the project
 | 
						|
mature and support additional features. If you end up using Jekyll for your
 | 
						|
own blog, drop me a line and let me know what you'd like to see in future
 | 
						|
versions. Better yet, fork the project over at GitHub and hack in the features
 | 
						|
yourself!
 | 
						|
 | 
						|
h2. Example Proto-Site
 | 
						|
 | 
						|
My own personal site/blog is generated with Jekyll.
 | 
						|
 | 
						|
The proto-site repo
 | 
						|
("http://github.com/mojombo/tpw":http://github.com/mojombo/tpw) is converted
 | 
						|
into the actual site
 | 
						|
("http://tom.preston-werner.com/":http://tom.preston-werner.com)
 | 
						|
 | 
						|
h2. Install
 | 
						|
 | 
						|
The best way to install Jekyll is via RubyGems:
 | 
						|
 | 
						|
  $ sudo gem install mojombo-jekyll -s http://gems.github.com/
 | 
						|
 | 
						|
Jekyll requires the gems `directory_watcher`, `liquid`, `open4`, 
 | 
						|
and `maruku` (for markdown support). These are automatically
 | 
						|
installed by the gem install command.
 | 
						|
 | 
						|
Maruku comes with optional support for LaTeX to PNG rendering via
 | 
						|
"blahtex":http://gva.noekeon.org/blahtexml/ (Version 0.6) which must be in
 | 
						|
your $PATH along with `dvips`. 
 | 
						|
 | 
						|
(NOTE: the version of maruku I am using is `remi-maruku` on GitHub as it
 | 
						|
does not assume a fixed location for `dvips`.)
 | 
						|
 | 
						|
h2. Run
 | 
						|
 | 
						|
  $ cd /path/to/proto/site
 | 
						|
  $ jekyll
 | 
						|
 | 
						|
This will generate the site and place it in /path/to/proto/site/_site. If
 | 
						|
you'd like the generated site placed somewhere else:
 | 
						|
 | 
						|
  $ jekyll /path/to/place/generated/site
 | 
						|
 | 
						|
And if you don't want to be in the proto site root to run Jekyll:
 | 
						|
 | 
						|
  $ jekyll /path/to/proto/site /path/to/place/generated/site
 | 
						|
 | 
						|
h2. Run Options
 | 
						|
 | 
						|
There is an autobuild feature that will regenerate your site if any of the
 | 
						|
files change. The autobuild feature can be used on any of the invocations:
 | 
						|
 | 
						|
  $ jekyll --auto
 | 
						|
 | 
						|
By default, the "related posts" functionality will produce crappy results.
 | 
						|
In order to get high quality results with a true LSI algorithm, you must
 | 
						|
enable it (it may take some time to run if you have many posts):
 | 
						|
 | 
						|
  $ jekyll --lsi
 | 
						|
 | 
						|
For static code highlighting, you can install Pygments (see below) and then
 | 
						|
use that to make your code blocks look pretty. To activate Pygments support
 | 
						|
during the conversion:
 | 
						|
 | 
						|
  $ jekyll --pygments
 | 
						|
 | 
						|
By default, Jekyll uses "Maruku":http://maruku.rubyforge.org (pure Ruby) for
 | 
						|
Markdown support. If you'd like to use RDiscount (faster, but requires
 | 
						|
compilation), you must install it (gem install rdiscount) and then you can
 | 
						|
have it used instead:
 | 
						|
 | 
						|
  $ jekyll --rdiscount
 | 
						|
  
 | 
						|
When previewing complex sites locally, simply opening the site in a web 
 | 
						|
browser (using file://) can cause problems with links that are relative to
 | 
						|
the site root (e.g., "/stylesheets/style.css"). To get around this, Jekyll
 | 
						|
can launch a simple WEBrick server (works well in conjunction with --auto).
 | 
						|
Default port is 4000:
 | 
						|
 | 
						|
  $ jekyll --server [PORT]
 | 
						|
 | 
						|
h2. Data
 | 
						|
 | 
						|
Jekyll traverses your site looking for files to process. Any files with YAML
 | 
						|
front matter (see below) are subject to processing. For each of these files,
 | 
						|
Jekyll makes a variety of data available to the pages via the Liquid
 | 
						|
templating system. The following is a reference of the available data.
 | 
						|
 | 
						|
h3. Global
 | 
						|
 | 
						|
  site
 | 
						|
    Sitewide information.
 | 
						|
 | 
						|
  page
 | 
						|
    For Posts, this is the union of the data in the YAML front matter and the
 | 
						|
    computed data (such as URL and date). For regular pages, this is just the
 | 
						|
    YAML front matter.
 | 
						|
 | 
						|
  content
 | 
						|
    In layout files, this contains the content of the subview(s). In Posts or
 | 
						|
    Pages, this is undefined.
 | 
						|
 | 
						|
h3. Site
 | 
						|
 | 
						|
  site.time
 | 
						|
    The current Time (when you run the jekyll command).
 | 
						|
 | 
						|
  site.posts
 | 
						|
    A reverse chronological list of all Posts.
 | 
						|
 | 
						|
  site.related_posts
 | 
						|
    If the page being processed is a Post, this contains a list of up to ten
 | 
						|
    related Posts. By default, these are low quality but fast to compute. For
 | 
						|
    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
 | 
						|
    The title of the Post.
 | 
						|
 | 
						|
  post.url
 | 
						|
    The URL of the Post without the domain.
 | 
						|
    e.g. /2008/12/14/my-post.html
 | 
						|
 | 
						|
  post.date
 | 
						|
    The Date assigned to the Post.
 | 
						|
 | 
						|
  post.id
 | 
						|
    An identifier unique to the Post (useful in RSS feeds).
 | 
						|
    e.g. /2008/12/14/my-post
 | 
						|
 | 
						|
  post.categories
 | 
						|
    The list of categories to which this post belongs. Categories are
 | 
						|
    derived from the directory structure above the _posts directory. For
 | 
						|
    example, a post at /work/code/_posts/2008-12-24-closures.textile
 | 
						|
    would have this field set to ['work', 'code'].
 | 
						|
 | 
						|
  post.topics
 | 
						|
    The list of topics for this Post. Topics are derived from the directory
 | 
						|
    structure beneath the _posts directory. For example, a post at
 | 
						|
    /_posts/music/metal/2008-12-24-metalocalypse.textile would have this field
 | 
						|
    set to ['music', 'metal'].
 | 
						|
 | 
						|
  post.content
 | 
						|
    The content of the Post.
 | 
						|
 | 
						|
h2. YAML Front Matter
 | 
						|
 | 
						|
Any files that contain a YAML front matter block will be processed by Jekyll
 | 
						|
as special files. The front matter must be the first thing in the file and
 | 
						|
takes the form of:
 | 
						|
 | 
						|
<pre>
 | 
						|
---
 | 
						|
layout: post
 | 
						|
title: Blogging Like a Hacker
 | 
						|
---
 | 
						|
</pre>
 | 
						|
 | 
						|
Between the triple-dashed lines, you can set predefined variables (see below
 | 
						|
for a reference) or custom data of your own.
 | 
						|
 | 
						|
h3. Predefined Global Variables
 | 
						|
 | 
						|
  layout
 | 
						|
    If set, this specifies the layout file to use. Use the layout file
 | 
						|
    name without file extension. Layout files must be placed in the
 | 
						|
    <code>_layouts</code> directory.
 | 
						|
 | 
						|
h3. Predefined Post Variables
 | 
						|
 | 
						|
  permalink
 | 
						|
    If you need your processed URLs to be something other than the default
 | 
						|
    /year/month/day/title.html then you can set this variable and it will
 | 
						|
    be used as the final URL.
 | 
						|
 | 
						|
h3. Custom Variables
 | 
						|
 | 
						|
Any variables in the front matter that are not predefined are mixed into the
 | 
						|
data that is sent to the Liquid templating engine during the conversion. For
 | 
						|
instance, if you set a <code>title</code>, you can use that in your layout to
 | 
						|
set the page title:
 | 
						|
 | 
						|
<pre>
 | 
						|
<title>{{ page.title }}</title>
 | 
						|
</pre>
 | 
						|
 | 
						|
h2. Filters, Tags, and Blocks
 | 
						|
 | 
						|
In addition to the built-in Liquid filters, tags, and blocks, Jekyll provides
 | 
						|
some additional items that you can use in your site.
 | 
						|
 | 
						|
h3. Date to XML Schema (Filter)
 | 
						|
 | 
						|
Convert a Time into XML Schema format.
 | 
						|
 | 
						|
  {{ site.time | date_to_xmlschema }}
 | 
						|
 | 
						|
becomes
 | 
						|
 | 
						|
  2008-11-17T13:07:54-08:00
 | 
						|
 | 
						|
h3. XML Escape (Filter)
 | 
						|
 | 
						|
Escape some text for use in XML.
 | 
						|
 | 
						|
  {{ post.content | xml_escape }}
 | 
						|
 | 
						|
h3. Number of Words (Filter)
 | 
						|
 | 
						|
Count the number of words in some text.
 | 
						|
 | 
						|
  {{ post.content | number_of_words }}
 | 
						|
 | 
						|
becomes
 | 
						|
 | 
						|
  1337
 | 
						|
 | 
						|
h3. Array to Sentence String
 | 
						|
 | 
						|
Convert an array into a sentence.
 | 
						|
 | 
						|
  {{ page.tags | array_to_sentence_string }}
 | 
						|
 | 
						|
becomes
 | 
						|
 | 
						|
  foo, bar, and baz
 | 
						|
 | 
						|
h3. Include (Tag)
 | 
						|
 | 
						|
If you have small page fragments that you wish to include in multiple places
 | 
						|
on your site, you can use the <code>include</code> tag.
 | 
						|
 | 
						|
<pre>{% include sig.textile %}</pre>
 | 
						|
 | 
						|
Jekyll expects all include files to be placed in an <code>_includes</code>
 | 
						|
directory at the root of your source dir. So this will embed the contents of
 | 
						|
<code>/path/to/proto/site/_includes/sig.textile</code> into the calling file.
 | 
						|
 | 
						|
h3. Code Highlighting (Block)
 | 
						|
 | 
						|
Jekyll has built in support for syntax highlighting of over "100
 | 
						|
languages":http://pygments.org/languages/ via "Pygments":http://pygments.org/.
 | 
						|
In order to take advantage of this you'll need to have Pygments installed, and
 | 
						|
the pygmentize binary must be in your path. When you run Jekyll, make sure you
 | 
						|
run it with Pygments support:
 | 
						|
 | 
						|
  $ jekyll --pygments
 | 
						|
 | 
						|
To denote a code block that should be highlighted:
 | 
						|
 | 
						|
<pre>
 | 
						|
{% highlight ruby %}
 | 
						|
def foo
 | 
						|
  puts 'foo'
 | 
						|
end
 | 
						|
{% endhighlight %}
 | 
						|
</pre>
 | 
						|
 | 
						|
The argument to <code>highlight</code> is the language identifier. To find the
 | 
						|
appropriate identifier to use for your favorite language, look for the "short
 | 
						|
name" on the "Lexers":http://pygments.org/docs/lexers/ page.
 | 
						|
 | 
						|
In order for the highlighting to show up, you'll need to include a
 | 
						|
highlighting stylesheet. For an example stylesheet you can look at
 | 
						|
"syntax.css":http://github.com/mojombo/tpw/tree/master/css/syntax.css. These
 | 
						|
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:
 | 
						|
 | 
						|
<pre>
 | 
						|
{% for post in site.categories.foo %}
 | 
						|
	<li><span>{{ post.date | date_to_string }}</span> - {{ post.title }}</li>
 | 
						|
{% endfor %}
 | 
						|
</pre>
 | 
						|
 | 
						|
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
 | 
						|
all of the dependencies, install the gem first.
 | 
						|
 | 
						|
  $ git clone git://github.com/mojombo/jekyll
 | 
						|
 | 
						|
The best way to get your changes merged back into core is as follows:
 | 
						|
 | 
						|
# Fork mojombo/jekyll on GitHub
 | 
						|
# Clone down your fork
 | 
						|
# Create a topic branch to contain your change
 | 
						|
# Hack away
 | 
						|
# If you are adding new functionality, document it in README.textile
 | 
						|
# Do not change the version number, I will do that on my end
 | 
						|
# If necessary, rebase your commits into logical chunks, without errors
 | 
						|
# Push the branch up to GitHub
 | 
						|
# Send me (mojombo) a pull request for your branch
 | 
						|
 | 
						|
h2. Blog migrations
 | 
						|
 | 
						|
h3. Movable Type
 | 
						|
 | 
						|
To migrate your MT blog into Jekyll, you'll need read access to the database.
 | 
						|
The lib/jekyll/converters/mt.rb module provides a simple convert to create
 | 
						|
.markdown files in a _posts directory based on the entries contained therein.
 | 
						|
 | 
						|
  $ export DB=my_mtdb
 | 
						|
  $ export USER=dbuser
 | 
						|
  $ export PASS=dbpass
 | 
						|
  $ ruby -r './lib/jekyll/converters/mt' -e 'Jekyll::MT.process( \
 | 
						|
    "#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")'
 | 
						|
 | 
						|
You may need to adjust the SQL query used to retrieve MT entries. Left alone,
 | 
						|
it will attempt to pull all entries across all blogs regardless of status.
 | 
						|
Please check the results and verify the posts before publishing.
 | 
						|
 | 
						|
h3. Typo 4+
 | 
						|
 | 
						|
To migrate your Typo blog into Jekyll, you'll need read access to the MySQL
 | 
						|
database. The lib/jekyll/converters/typo.rb module provides a simple convert 
 | 
						|
to create .html, .textile, or .markdown files in a _posts directory based on 
 | 
						|
the entries contained therein.
 | 
						|
 | 
						|
  $ export DB=my_typo_db
 | 
						|
  $ export USER=dbuser
 | 
						|
  $ export PASS=dbpass
 | 
						|
  $ ruby -r './lib/jekyll/converters/typo' -e 'Jekyll::Typo.process( \
 | 
						|
    "#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")'
 | 
						|
 | 
						|
You may need to adjust the code used to filter Typo entries. Left alone,
 | 
						|
it will attempt to pull all entries across all blogs that were published.
 | 
						|
This code also has only been tested with Typo version 4+. Previous versions
 | 
						|
of Typo may not convert correctly. Please check the results and verify the 
 | 
						|
posts before publishing.
 | 
						|
 | 
						|
h3. TextPattern 4
 | 
						|
 | 
						|
To migrate your TextPattern blog into Jekyll, you'll need read access to the MySQL
 | 
						|
database. The lib/jekyll/converters/textpattern.rb module provides a simple convert to create .textile files in a _posts directory based on 
 | 
						|
the entries contained therein.
 | 
						|
 | 
						|
  $ ruby -r './lib/jekyll/converters/textpattern' -e 'Jekyll::TextPattern.process( \
 | 
						|
    "database_name", "username", "password", "hostname")'
 | 
						|
 | 
						|
The hostname defaults to _localhost_, all other variables are needed
 | 
						|
You may need to adjust the code used to filter entries. Left alone,
 | 
						|
it will attempt to pull all entries that are live or sticky.
 | 
						|
 | 
						|
h2. License
 | 
						|
 | 
						|
(The MIT License)
 | 
						|
 | 
						|
Copyright (c) 2008 Tom Preston-Werner
 | 
						|
 | 
						|
Permission is hereby granted, free of charge, to any person obtaining
 | 
						|
a copy of this software and associated documentation files (the
 | 
						|
'Software'), to deal in the Software without restriction, including
 | 
						|
without limitation the rights to use, copy, modify, merge, publish,
 | 
						|
distribute, sublicense, and/or sell copies of the Software, and to
 | 
						|
permit persons to whom the Software is furnished to do so, subject to
 | 
						|
the following conditions:
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be
 | 
						|
included in all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 | 
						|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
						|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
						|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
						|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
						|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
						|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 |