Merge pull request #287 from dijonkitchen/patch-1
[GalaxyBlog.git] / _posts / core-samples / 2011-12-29-jekyll-introduction.md
blob13fe3dc900550d0e550f87033142df34228ccc00
1 ---
2 layout: post
3 category : lessons
4 tagline: "Supporting tagline"
5 tags : [intro, beginner, jekyll, tutorial]
6 ---
7 {% include JB/setup %}
9 This Jekyll introduction will outline specifically  what Jekyll is and why you would want to use it.
10 Directly following the intro we'll learn exactly _how_ Jekyll does what it does.
12 ## Overview
14 ### What is Jekyll?
16 Jekyll is a parsing engine bundled as a ruby gem used to build static websites from
17 dynamic components such as templates, partials, liquid code, markdown, etc. Jekyll is known as "a simple, blog aware, static site generator".
19 ### Examples
21 This website is created with Jekyll. [Other Jekyll websites](https://github.com/mojombo/jekyll/wiki/Sites).
25 ### What does Jekyll Do?
27 Jekyll is a ruby gem you install on your local system.
28 Once there you can call `jekyll --server` on a directory and provided that directory
29 is setup in a way jekyll expects, it will do magic stuff like parse markdown/textile files,
30 compute categories, tags, permalinks, and construct your pages from layout templates and partials.
32 Once parsed, Jekyll stores the result in a self-contained static `_site` folder.
33 The intention here is that you can serve all contents in this folder statically from a plain static web-server.
35 You can think of Jekyll as a normalish dynamic blog but rather than parsing content, templates, and tags
36 on each request, Jekyll does this once _beforehand_ and caches the _entire website_ in a folder for serving statically.
38 ### Jekyll is Not Blogging Software
40 **Jekyll is a parsing engine.**
42 Jekyll does not come with any content nor does it have any templates or design elements.
43 This is a common source of confusion when getting started.
44 Jekyll does not come with anything you actually use or see on your website - you have to make it.
46 ### Why Should I Care?
48 Jekyll is very minimalistic and very efficient.
49 The most important thing to realize about Jekyll is that it creates a static representation of your website requiring only a static web-server.
50 Traditional dynamic blogs like Wordpress require a database and server-side code.
51 Heavily trafficked dynamic blogs must employ a caching layer that ultimately performs the same job Jekyll sets out to do; serve static content.
53 Therefore if you like to keep things simple and you prefer the command-line over an admin panel UI then give Jekyll a try.
55 **Developers like Jekyll because we can write content like we write code:**
57 - Ability to write content in markdown or textile in your favorite text-editor.
58 - Ability to write and preview your content via localhost.
59 - No internet connection required.
60 - Ability to publish via git.
61 - Ability to host your blog on a static web-server.
62 - Ability to host freely on GitHub Pages.
63 - No database required.
65 # How Jekyll Works
67 The following is a complete but concise outline of exactly how Jekyll works.
69 Be aware that core concepts are introduced in rapid succession without code examples.
70 This information is not intended to specifically teach you how to do anything, rather it
71 is intended to give you the _full picture_ relative to what is going on in Jekyll-world.
73 Learning these core concepts should help you avoid common frustrations and ultimately
74 help you better understand the code examples contained throughout Jekyll-Bootstrap.
77 ## Initial Setup
79 After [installing jekyll](/index.html#start-now) you'll need to format your website directory in a way jekyll expects.
80 Jekyll-bootstrap conveniently provides the base directory format.
82 ### The Jekyll Application Base Format
84 Jekyll expects your website directory to be laid out like so:
86     .
87     |-- _config.yml
88     |-- _includes
89     |-- _layouts
90     |   |-- default.html
91     |   |-- post.html
92     |-- _posts
93     |   |-- 2011-10-25-open-source-is-good.markdown
94     |   |-- 2011-04-26-hello-world.markdown
95     |-- _site
96     |-- index.html
97     |-- assets
98         |-- css
99             |-- style.css
100         |-- javascripts
103 - **\_config.yml**
104         Stores configuration data.
106 - **\_includes**
107         This folder is for partial views.
109 - **\_layouts**
110         This folder is for the main templates your content will be inserted into.
111         You can have different layouts for different pages or page sections.
113 - **\_posts**
114         This folder contains your dynamic content/posts.
115         the naming format is required to be `@YEAR-MONTH-DATE-title.MARKUP@`.
117 - **\_site**
118         This is where the generated site will be placed once Jekyll is done transforming it.
120 - **assets**
121         This folder is not part of the standard jekyll structure.
122         The assets folder represents _any generic_ folder you happen to create in your root directory.
123         Directories and files not properly formatted for jekyll will be left untouched for you to serve normally.
125 (read more: <https://github.com/mojombo/jekyll/wiki/Usage>)
128 ### Jekyll Configuration
130 Jekyll supports various configuration options that are fully outlined here:
131 (<https://github.com/mojombo/jekyll/wiki/Configuration>)
136 ## Content in Jekyll
138 Content in Jekyll is either a post or a page.
139 These content "objects" get inserted into one or more templates to build the final output for its respective static-page.
141 ### Posts and Pages
143 Both posts and pages should be written in markdown, textile, or HTML and may also contain Liquid templating syntax.
144 Both posts and pages can have meta-data assigned on a per-page basis such as title, url path, as well as arbitrary custom meta-data.
146 ### Working With Posts
148 **Creating a Post**
149 Posts are created by properly formatting a file and placing it the `_posts` folder.
151 **Formatting**
152 A post must have a valid filename in the form `YEAR-MONTH-DATE-title.MARKUP` and be placed in the `_posts` directory.
153 If the data format is invalid Jekyll will not recognize the file as a post. The date and title are automatically parsed from the filename of the post file.
154 Additionally, each file must have [YAML Front-Matter](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter) prepended to its content.
155 YAML Front-Matter is a valid YAML syntax specifying meta-data for the given file.
157 **Order**
158 Ordering is an important part of Jekyll but it is hard to specify a custom ordering strategy.
159 Only reverse chronological and chronological ordering is supported in Jekyll.
161 Since the date is hard-coded into the filename format, to change the order, you must change the dates in the filenames.
163 **Tags**
164 Posts can have tags associated with them as part of their meta-data.
165 Tags may be placed on posts by providing them in the post's YAML front matter.
166 You have access to the post-specific tags in the templates. These tags also get added to the sitewide collection.
168 **Categories**
169 Posts may be categorized by providing one or more categories in the YAML front matter.
170 Categories offer more significance over tags in that they can be reflected in the URL path to the given post.
171 Note categories in Jekyll work in a specific way.
172 If you define more than one category you are defining a category hierarchy "set".
173 Example:
175     ---
176     title :  Hello World
177     categories : [lessons, beginner]
178     ---
180 This defines the category hierarchy "lessons/beginner". Note this is _one category_ node in Jekyll.
181 You won't find "lessons" and "beginner" as two separate categories unless you define them elsewhere as singular categories.
183 ### Working With Pages
185 **Creating a Page**
186 Pages are created by properly formatting a file and placing it anywhere in the root directory or subdirectories that do _not_ start with an underscore.
188 **Formatting**
189 In order to register as a Jekyll page the file must contain [YAML Front-Matter](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter).
190 Registering a page means 1) that Jekyll will process the page and 2) that the page object will be available in the `site.pages` array for inclusion into your templates.
192 **Categories and Tags**
193 Pages do not compute categories nor tags so defining them will have no effect.
195 **Sub-Directories**
196 If pages are defined in sub-directories, the path to the page will be reflected in the url.
197 Example:
199     .
200     |-- people
201         |-- bob
202             |-- essay.html
204 This page will be available at `http://yourdomain.com/people/bob/essay.html`
207 **Recommended Pages**
209 - **index.html**
210   You will always want to define the root index.html page as this will display on your root URL.
211 - **404.html**
212   Create a root 404.html page and GitHub Pages will serve it as your 404 response.
213 - **sitemap.html**
214   Generating a sitemap is good practice for SEO.
215 - **about.html**
216   A nice about page is easy to do and gives the human perspective to your website.
219 ## Templates in Jekyll
221 Templates are used to contain a page's or post's content.
222 All templates have access to a global site object variable: `site` as well as a page object variable: `page`.
223 The site variable holds all accessible content and metadata relative to the site.
224 The page variable holds accessible data for the given page or post being rendered at that point.
226 **Create a Template**
227 Templates are created by properly formatting a file and placing it in the `_layouts` directory.
229 **Formatting**
230 Templates should be coded in HTML and contain YAML Front Matter.
231 All templates can contain Liquid code to work with your site's data.
233 **Rending Page/Post Content in a Template**
234 There is a special variable in all templates named : `content`.
235 The `content` variable holds the page/post content including any sub-template content previously defined.
236 Render the content variable wherever you want your main content to be injected into your template:
238 {% capture text %}...
239 <body>
240   <div id="sidebar"> ... </div>
241   <div id="main">
242     |.{content}.|
243   </div>
244 </body>
245 ...{% endcapture %}
246 {% include JB/liquid_raw %}
248 ### Sub-Templates
250 Sub-templates are exactly templates with the only difference being they
251 define another "root" layout/template within their YAML Front Matter.
252 This essentially means a template will render inside of another template.
254 ### Includes
255 In Jekyll you can define include files by placing them in the `_includes` folder.
256 Includes are NOT templates, rather they are just code snippets that get included into templates.
257 In this way, you can treat the code inside includes as if it was native to the parent template.
259 Any valid template code may be used in includes.
262 ## Using Liquid for Templating
264 Templating is perhaps the most confusing and frustrating part of Jekyll.
265 This is mainly due to the fact that Jekyll templates must use the Liquid Templating Language.
267 ### What is Liquid?
269 [Liquid](https://github.com/Shopify/liquid) is a secure templating language developed by [Shopify](http://shopify.com).
270 Liquid is designed for end-users to be able to execute logic within template files
271 without imposing any security risk on the hosting server.
273 Jekyll uses Liquid to generate the post content within the final page layout structure and as the primary interface for working with
274 your site and post/page data.
276 ### Why Do We Have to Use Liquid?
278 GitHub uses Jekyll to power [GitHub Pages](http://pages.github.com/).
279 GitHub cannot afford to run arbitrary code on their servers so they lock developers down via Liquid.
281 ### Liquid is Not Programmer-Friendly.
283 The short story is liquid is not real code and its not intended to execute real code.
284 The point being you can't do jackshit in liquid that hasn't been allowed explicitly by the implementation.
285 What's more you can only access data-structures that have been explicitly passed to the template.
287 In Jekyll's case it is not possible to alter what is passed to Liquid without hacking the gem or running custom plugins.
288 Both of which cannot be supported by GitHub Pages.
290 As a programmer - this is very frustrating.
292 But rather than look a gift horse in the mouth we are going to
293 suck it up and view it as an opportunity to work around limitations and adopt client-side solutions when possible.
295 **Aside**
296 My personal stance is to not invest time trying to hack liquid. It's really unnecessary
297 _from a programmer's_ perspective. That is to say if you have the ability to run custom plugins (i.e. run arbitrary ruby code)
298 you are better off sticking with ruby. Toward that end I've built [Mustache-with-Jekyll](http://github.com/plusjade/mustache-with-jekyll)
301 ## Static Assets
303 Static assets are any file in the root or non-underscored subfolders that are not pages.
304 That is they have no valid YAML Front Matter and are thus not treated as Jekyll Pages.
306 Static assets should be used for images, css, and javascript files.
311 ## How Jekyll Parses Files
313 Remember Jekyll is a processing engine. There are two main types of parsing in Jekyll.
315 - **Content parsing.**
316         This is done with textile or markdown.
317 - **Template parsing.**
318   This is done with the liquid templating language.
320 And thus there are two main types of file formats needed for this parsing.
322 - **Post and Page files.**
323   All content in Jekyll is either a post or a page so valid posts and pages are parsed with markdown or textile.
324 - **Template files.**
325         These files go in `_layouts` folder and contain your blogs **templates**. They should be made in HTML with the help of Liquid syntax.
326         Since include files are simply injected into templates they are essentially parsed as if they were native to the template.
328 **Arbitrary files and folders.**
329 Files that _are not_ valid pages are treated as static content and pass through
330 Jekyll untouched and reside on your blog in the exact structure and format they originally existed in.
332 ### Formatting Files for Parsing.
334 We've outlined the need for valid formatting using **YAML Front Matter**.
335 Templates, posts, and pages all need to provide valid YAML Front Matter even if the Matter is empty.
336 This is the only way Jekyll knows you want the file processed.
338 YAML Front Matter must be prepended to the top of template/post/page files:
340     ---
341     layout: post
342     category : pages
343     tags : [how-to, jekyll]
344     ---
346     ... contents ...
348 Three hyphens on a new line start the Front-Matter block and three hyphens on a new line end the block.
349 The data inside the block must be valid YAML.
351 Configuration parameters for YAML Front-Matter is outlined here:
352 [A comprehensive explanation of YAML Front Matter](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter)
354 #### Defining Layouts for Posts and Templates Parsing.
356 The `layout` parameter in the YAML Front Matter defines the template file for which the given post or template should be injected into.
357 If a template file specifies its own layout, it is effectively being used as a `sub-template.`
358 That is to say loading a post file into a template file that refers to another template file with work in the way you'd expect; as a nested sub-template.
364 ## How Jekyll Generates the Final Static Files.
366 Ultimately, Jekyll's job is to generate a static representation of your website.
367 The following is an outline of how that's done:
369 1. **Jekyll collects data.**
370   Jekyll scans the posts directory and collects all posts files as post objects. It then scans the layout assets and collects those and finally scans other directories in search of pages.
372 2. **Jekyll computes data.**
373   Jekyll takes these objects, computes metadata (permalinks, tags, categories, titles, dates) from them and constructs one
374   big `site` object that holds all the posts, pages, layouts, and respective metadata.
375   At this stage your site is one big computed ruby object.
377 3. **Jekyll liquifies posts and templates.**
378   Next jekyll loops through each post file and converts (through markdown or textile) and **liquifies** the post inside of its respective layout(s).
379   Once the post is parsed and liquified inside the the proper layout structure, the layout itself is "liquified".
380         **Liquification** is defined as follows: Jekyll initiates a Liquid template, and passes a simpler hash representation of the ruby site object as well as a simpler
381   hash representation of the ruby post object. These simplified data structures are what you have access to in the templates.
383 3. **Jekyll generates output.**
384         Finally the liquid templates are "rendered", thereby processing any liquid syntax provided in the templates
385         and saving the final, static representation of the file.
387 **Notes.**
388 Because Jekyll computes the entire site in one fell swoop, each template is given access to
389 a global `site` hash that contains useful data. It is this data that you'll iterate through and format
390 using the Liquid tags and filters in order to render it onto a given page.
392 Remember, in Jekyll you are an end-user. Your API has only two components:
394 1. The manner in which you setup your directory.
395 2. The liquid syntax and variables passed into the liquid templates.
397 All the data objects available to you in the templates via Liquid are outlined in the **API Section** of Jekyll-Bootstrap.
398 You can also read the original documentation here: <https://github.com/mojombo/jekyll/wiki/Template-Data>
400 ## Conclusion
402 I hope this paints a clearer picture of what Jekyll is doing and why it works the way it does.
403 As noted, our main programming constraint is the fact that our API is limited to what is accessible via Liquid and Liquid only.
405 Jekyll-bootstrap is intended to provide helper methods and strategies aimed at making it more intuitive and easier to work with Jekyll =)
407 **Thank you** for reading this far.
409 ## Next Steps
411 Please take a look at [{{ site.categories.api.first.title }}]({{ BASE_PATH }}{{ site.categories.api.first.url }})
412 or jump right into [Usage]({{ BASE_PATH }}{{ site.categories.usage.first.url }}) if you'd like.