Test Github Site locally with Jekyll

Note

Posted by Becks on January 6, 2017

Install ruby, jekyll bundler

ruby

ruby --version #if version is lower than 2.2, install ruby as below

ruby

Even if have ruby installed, need to install below command.

brew install chruby ruby-install 
ruby-install ruby

jekyll bundler

gem install jekyll bundler

# if has below error
# You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
# or Could not locate Gemfile
# try 

export GEM_HOME="$HOME/.gem"

# then run 
gem install jekyll bundler

Init Bundler

creates a new Bundler project (by creating an empty Gemfile). If in your username.github.io has Gemfile and Gemfile.lock, remove both

cd documents/github/username.github.io
Bundle init

Configure Bundler Install Path(optional)

configure Bundler to install gems in the ./vendor/bundle/ project subdirectory. The advantage of doing this is that bundler will install gems within your project folder instead of the location used by gem install. This can help you avoid permissions errors you might otherwise get during gem installation. If you skip this step, Bundler will install your dependencies to the location used by gem install.

bundle config set --local path 'vendor/bundle'

Add Jekyll

add Jekyll as a dependency of project. This command will add the Jekyll gem to our Gemfile and install it to the ./vendor/bundle/ folder

Bundle add jekyll

Now Jekyll is installed. We need the --force parameter because our folder isn’t empty - it already has some Bundler files in it. run the bundle install separately because Jekyll gets confused if the Gemfile already exists.

bundle exec jekyll new --force --skip-bundle .
bundle install

Serve site

bundle exec jekyll serve

If run above with error, add two lines at the bottom of Gemfile

gem 'jekyll-sitemap'
gem 'jekyll-paginate' 

Then run below in the terminal

gem install jekyll-sitemap

Open browser with http://127.0.0.1:4000

Git Ignore

want to ignore the ./vendor/ and ./.bundle/ folders since they contain user- or platform-specific information.

# Ignore metadata generated by Jekyll
_site/
.sass-cache/
.jekyll-cache/
.jekyll-metadata

# Ignore folders generated by Bundler
.bundle/
vendor/

(Reference)[https://jekyllrb.com/tutorials/using-jekyll-with-bundler/]

Run with Draft

create _drafts folder inside Jekyll folder, then run below code. When write draft, don’t need to add a date for your draft, it will publish based on today’s date

Jekyll serve --draft

when ready for publish, move to _post folder and add date

Without using default link, using permalink in

permalink: /:year/:month:/:day/:title 

/: to refer the variable from front matter.

Default Front Matter

in _config.yml, add

defaults:
   - 
      scope:
        path: ""
        type: "post"
      values:
        layout: "post"

All post file inside _post folder even without front matter, write publish as post

Install Theme

go to ruby them search for jekyll-theme, then add it Gemfile and then run

bundle install

Access Varaible

Access Variable

{{page.tile}}   #access current page(md file)'s tile, 
{{layout.author} } # get front matter's author

e.g. post.md

---
layout:     post
title:      "Test Github Site locally with Jekyll"
date:       2017-01-06 12:00:00
author:     "Becks"
---

... ...

post.html

---
layout: "wrapper"
author: "Mike"
---

<h1> This is a post {{ page.title }} </h1>
<h1> This is a post {{ site.title }} </h1> #give the data from yml file
<h3> {{ layout.author}}</h3>  #Mike
<h3> {{ page.author}}</h3>  #Becks
<hr>

<content>  #to display the content from md

Include

Create a _includes folder, create html inside. Then in your layout html to include, can also add variables inside layout html, then include html can access those variable

header.html inside _includes

<h1 style = "color: {{ include.color }}">{{ site.url }}</h1>
<hr> <hr>

post.html inside _layout

<html>
<head>
    <meta charset = "UTF-8">
    <title>{{ site.title }}</title>
</head>
<body>
    {% include header.html color = "blue" %}  #include from _includes folder
    {{ content }}
</body>

Looping Posts

List all posts from _post directory,

{% for post in site.posts %}
    <li> <a href = "{{ post.url }} "{{ post.title }} </a> </li> <br/>
    {{ post.url }} <br>
{% endfor %}

List all pages local in .github.io folder

{% for post in site.pages %}
    <li> <a href = "{{ post.url }} "{{ post.title }} </a> </li> <br/>
    {{ post.url }} <br>
{% endfor %}

If


{% if page.title == "My First Post" or some_condition %}
    This is the first post
{% elsif page.title = "My Second post" and some_condition %}
    This is the second post
{% else %}
    This is another post
{% endif %}

<h2>{{ page.title }} </h2>
<hr>

{% for post in site.pages %}
    <li> <a style = "{% if page.url ==post.url %}color:red;{% endif %}" #if this page url equal to post url, make it red
        href = "{{ post.url }} "{{ post.title }} </a> </li> <br/>
    {{ post.url }} <br>
{% endfor %}

Data Files

create _data inside root directory, can put three format, yml, json, or csv

for example, create a people.yml

- name: "Mike"
    occupation: "Professor"

- name: "Steve"
    occupation: "Developer"

- name: "James"
    occupation: "Realtor"

Then in home.html

{% for person in site.data.people %}
    {{ person.name }}, {{ person.occupation }} <br/>

{% endfor %}

Static File

Create asset(Can change the name for the file) in root directory

Home.html

{% for file in site.static_files %}
    {{ file.path }}, {file.name}, {file.extname} <br> #extname: extension name
{% endfor %}

Home.html

{% for file in site.static_files %}
    {{ file.path }}  <br>
{% endfor %}

will print

/assets/img/dog.jpeg
/assets/img/logo.png
/my.pdf

can create default for those static files, in _config.yml, add

defaults:
   - 
      scope:
        path: "assets/img"
      values:
        image: true

in Home.html

{% for file in site.static_files %}
    {% if file.image %}
    <img src = "{{ file.path }}" alt ="{ file.name }">   <br>
    {% endif %}
{% endfor %}