Creating a Project

Once you are done with the installation, it’s time to immerse yourself in the Jekyll magic. The jekyll new commandcreates a rough sketch for your project. For this article, I created a project named linuxmagazine with

jekyll new linuxmagazine

which tells Jekyll to create a new project directory within the working directory and ensures a working website, even without manual changes. Thus, the moment you create a project with Jekyll you have a working website at your disposal.

Changing to the newly created project directory and running

jekyll serve

cross-checks all the files and plugins and renders the website to a local server. The site is usually hosted under localhost:4000 , to which you can navigate in your browser to see the basic site layout.

The default theme provides a minimalist design (Figure 1) and is frugal on resources. For this article, I use the default theme and build on it by leveraging various plugins and variables. Note that the new and serve commands require bundler to manage dependencies, so during the build process, you might notice some exception messages in the terminal (Figure 2).

Figure 1: Jekyll default theme.
Figure 2: Build errors when bundler is not installed.

Like jekyll , bundler is a Ruby gem that has to be installed using Ruby commands, rather than a distro’s package manager. To install, simply initiate

ruby install bundler

then close the existing running Jekyll server by pressing Ctrl+C and build the project again with

bundle exec jekyll serve

to render the website, perform version control, check and meet all dependencies, and host your project on a local server.

Project Structure

Since version 1, jekyll new  populates and creates a project template, making the development process simple. Understanding the project layout is imperative for the lucid functioning of your project. Your directory layout might differ if you use a different theme, but for homogeneous behavior, Jekyll implemented a code of conduct from version 2 onward for a streamlined directory layout.

The directory structure has been encapsulated, and certain directories are now stored directly under a theme configuration folder, which, however, can be overridden by simply creating a similar directory layout within the project folder. Jekyll will automatically append newly defined folders and files during build time.

Because I am using the minima theme, I will restrict my focus on its directory structure to show how the core directories and configuration file are organized (Figure 3).

Figure 3: Folder layout of a Jekyll project.

The _config.yml file manages, alters, and defines site parameters. Jekyll initially reads this file and then initiates the process of building the website.

Basictasks, like setting up the website name, email, and descriptions, are defined within this configuration file.Because this file is not regenerated automatically, to reflect any changes, the project has to be rebuilt again.

The _config.yml file is a one-stop configuration file for managing Jekyll; from defining the name of your website to setting the server or restricting directory inclusion, this file p it all. A unique feature lets you define a global variable here that can be called in any file within the purview of the project definition.

Simply define anything (e.g., name: linuxmagazine ), and you can use the variable (name in this example) without having to redefine it. The syntax for reusing a variable is {{site:<variable>}} . Note that site here is not the name of your site but simply the word “site.” For this example, I use {{site:name}} to render the value defined in the variable name (i.e., linuxmagazine ).

Another useful prebuilt variable is port: , which lets you change the default port at which your local server is hosted. For example, by default, the port is set to 4000, but you can define any port number at which to host your local server, other than those pre-reserved for common file tasks (e.g., port:7000 will host the site at localhost:7000/ ).

Other important variables are exclude , include , and timezone , to name a few. The include  variable forcefully includes any file that follows, and you can include dot (.) files, which are excluded by default in the build process. The exclude  variable will leave out a set of files and directories defined by the user during the build process.

Gemfile and Gemfile.lock

A core file is the bundler gem, a handy configuration file with which you define gems (and their versions) that you want to install and use with your project. Bundler manages and installs gems on the fly.

Bundler automatically generates Gemfile.lock , which records the exact version of the gems installed. Then, when the same project is run on a different machine, bundler will read the Gemfile.lock file to ascertain dependencies, thus avoiding the logjam that can occur when an updated version of the required gem exists. This comes in handy if you have not specified version control in the resultant Gemfile .

Both Gemfile and Gemfile.lock are automatically generated, even if you don’t initiate bundler. As mentioned previously, the jekyll new command initiates bundle exec by default.

The _ posts directory contains all your site content and normal blog posts: content and layout can vary.

The _ site directory holds the generated assets. Once Jekyll transforms the rich text into HTML, it places all the rendered objects into this folder, which is not visible unless you render your project.

The very important _layouts directory holds the layouts of the posts and pages you want to create. You can define a topic-specific layout and use it under the front matter, and you can create a layout that can exclude certain features of the website (e.g., posts that allow comments and others that don’t).

The layout is initiated within the front matter of the post with the use of the layout  variable. You can define multiple layouts and save them under the _layouts  directory, substantially reducing duplication of code and helping to keep the structure spick and span.

The _includes directory holds the modular code for your projects: All the scripts, modular code, and various site-specific files land here. This folder is a shot in the arm for streamlining your code. Files under _includes are called by Liquid syntax (e.g., {% include <file>.html %} ), allowing you to call any file in a post that is predefined within the _includes directory. You can also add certain conditions for the file to be included and pass a parameter to the included file when you initiate it (more about this later).


Modular code forms the backbone and is intrinsic to Jekyll. Modularity enhances code readability, impedes code duplication, regulates resource overhead, and improves project maintainability. To cater to these principles of modularity, Jekyll has implemented various subtleties that aid in better management of projects and keep the clutter to a minimum. The major tools provided by Jekyll are:

  • variables
  • front matter
  • Liquid
  • include
  • layout

As previously mentioned, you can define variables in the _config.yml file and make use of it to reduce repetition of data. However the scope and scale of these variables change with its definition. Two types of variables can be defined within a project: local and global. Global variables are defined in the config.yml file and can be accessed by any file within the purview of the project. Local variables are specific to a post and are defined within a file. The usage of that variable is limited to that particular file.

Any variable defined in config.yml has to be accessed through the modifier site . To access a variable, you use {{site. < variable_name > }} . The variable has to be used inside Liquid syntax (i.e., {{ }} ), or the program will render the expression in plain text.

Local variables are defined inside the front matter and can be accessed within that file. In this case, the syntax would be {{page. < variable_name > }} . Variables can hold multiple values as integers, strings, and arrays.

The heart of the Jekyll rendering engine is the front matter, which is powered by YAML, which provides a very powerful yet simple way to manage and define the structure of a post.

The beginning of any Jekyll post starts and ends with --- , which tells the renderer that text within these delimiters is YAML. Jekyll then treats and renders the projects, providing values to these variables to be used within the file.

No predefined structure defines a variable, and any variable can be defined as one deems fit. The flexibility to define, pass, and call a variable is immense and provides a user with ample room in which to work. Variables can have an array and objects to diversify the definition. To define a subset value, you use the format shown in Listing 1 within the front matter.

Listing 1: Front Matter

categories: tech
  - month: January
    cost: $15
  - month: February
    cost:  $10
  - month: March
    cost: $12
comments: true

As you can see, a variable named magazine has objects with associated values. You can use these objects within the Liquid tag and fetch data as needed.

Liquid programming syntax was developed to allow users to implement conditional statements and loops. With the use of Liquid, you can increase the productivity of code when coupled with front matter.

Liquid can be used in one of two ways: to call a variable defined within front matter or as a conditional statement with a modifier:

  • Variable call. To call a predefined variable, you use curly brackets {{ }}  containing objects such as site or page and its variable to be called.
  • Conditional statement. A conditional statement uses curly brackets followed by an ampersand ({% < condition >  %} ) and ends with whatever condition is being used. In the example in Listing 1, then, you can render the output as:
{% for value in page.magazine %}
 <li> item.month, item.cost </li>

In the for loop, variables and objects extract values stored in the predefined variable magazine . Similarly, you can use if statements to create a conditional loop.

Because Jekyll doesn’t support a database, if you want to set up a comment section in your blog posts, you have to resort to third-party Disqus comments. Disqus is a fairly popular and widely used blog comment hosting service that allows users to post a comment using their social profiles.

An admin uses include and front matter to control where readers may post a comment. First, you should create a file within the _include s directory that will act as a global file for Disqus (Listing 2). Save the code as comments.html under the _includes directory. From this point on you can use {{ include comments.html }} where you want readers to comment. After that, register your website with Disqus and generate a short name for your website. Simply save that name in _config.yml as <disqus-shortname>: linuxmagazine .

Listing 2: Disqus Comment

{% if page.comments %} 
<div id="disqus_thread"></div>
 var disqus_config = function () {
  this.page.url = PAGE_URL;  // Replace PAGE_URL with your page's canonical URL variable
  this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = 'https://EXAMPLE.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus</a>.</noscript>
{% endif %}

Notice the {% if page.comments %} conditional statement at the start of the file, which checks for the variable comments within the front matter of a post. If the value is true, it will load Discus comments within that blog post. In the previous example, the front matter variable comments holds a true value, so if you were to include this Disqus file in the above code, it would load the comment section for that blog post.

Reducing clutter by including a file whenever needed is a nice idea, but it becomes cumbersome and archaic, and you might even forget to include a file at some point. To avoid such situations, you can write a generic layout file that houses all the repetitive and necessary code needed for blog posts or any kind of site content.

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus