Tìm hiểu kỹ về Jekyll, Shopify's Liquid template, YAML front matter

Nếu bạn muốn có 1 cái website đơn giản như là landing page hoặc blog cho bản thân, hay porfolio, hay một web giới thiệu doanh nghiệp đơn giản cho ông anh họ kiếm ít tiền mua beer uống, mà không muốn mất tiền thuê hosting, nhưng bạn không muốn web chỉ lèo tèo có 1 trang đơn giản quá, mà muốn nội dung có thể cập nhật, có nhiều trang, nhiều bài viết, nhiều mục, mỗi mục một giao diện tự động, ngoài ra còn sử dụng CSS có điều kiện, thiết kế giao diện sáng tạo vô biên, vòng lặp for phủng đủ kiểu... thậm chí nếu nghiên cứu kỹ còn thông được cả CMS vào... tóm lại là làm được tất cả mọi thứ một cách dễ dàng (trừ database và login > 5 users) mà không cần học thêm kiến thức gì nhiều thì có thể học sử dụng Jekyll. Jekyll sẽ giúp chúng ta tạo website động rồi host miễn phí lên Github Pages và chui qua Netlify để dùng cái CMS của nó.

Liquid template, Markdown và YAML front matter là những thứ được Jekyll sử dụng.

Note:
Máy mình sử dụng hệ điều hành Linux và đã cài xong Ruby, Gem, Bundler
Tất cả cặp mở ngoặc nhọn { { trong bài này đều bị thừa dấu cách ở giữa (do mình cứ đưa vào dấu nháy ngửa là lại bị chứ không phải mình gõ sai hoài mà lười sửa đâu huhu
alt text

Tạo website bằng Jekyll trên local

Tạo project

sudo jekyll new site-name

alt text

Tạo Gemfile

Tạo file tên là Gemfile (không extension) bên trong thư mục project vừa tạo, với nội dung như sau:

source 'https://rubygems.org'

alt text
Tại thời điểm viết bài này thì khi mình làm theo guide của github pages và thêm cả dòng gem 'github-pages', group: :jekyll_plugins vào Gemfile thì chính dòng này sẽ gây ra lỗi => Vì vậy đừng thêm

Launch website vừa tạo

cd vào thư mục gốc của project vừa tạo và dùng lệnh

sudo jekyll serve

Web vừa tạo sẽ được dọn ra tại http://localhost:4000/
alt text
alt text
Chúc mừng bạn đã setup thành công 1 site Jekyll trên local của mình :rose:

Chú ý

  • Bất cứ cái gì làm đúng rồi mà không được thì kiểm tra lại việc thừa thiếu ký tự space :laughing:

Đẩy lên Github Pages

Đi tới Github để tạo 1 repo mới.

Cd vào thư mục project Jekyll ban nãy và

git init
git remote add origin remote-repo-url

rồi push lên như bình thường.

Rieeng thư mục _site chứa các bài viết đã render nên sẽ được ignore

Thư mục project

Bên trong thư mục project vừa tạo sẽ có sẵn 1 số thứ cho chúng ta như sau:

  • vài bài viết mẫu: trang chủ index, trang about, trang 404...
  • các file Gem, tạm thời không cần bận tâm đến chúng
  • thư mục _posts để quăng các file vào rồi Jekyll sẽ render ra thành bài viết
  • và 1 file rất hữu ích cho cuộc đời đó là _config.yml, chúng ta sẽ lợi dụng nó triệt để kể từ bây giờ để chỉnh các setting
  • _site: thư mục chứa rendered files

Chú ý:

  • Những setting chỉnh trong _config.yml không hiện ra ngay mà phải serve lại project
  • Nếu refresh trang mà không thấy thay đổi gì thì có lẽ đã có lỗi build, khi đó bạn có thể mở terminal ra xem sẽ thấy đầy error, đôi khi chỉ là do 1 cái dấu đóng ngoặc hay % hic alt text
  • Nếu làm đúng hết rồi và cú pháp cũng không còn gì để sai nữa thì có thể do một số tính năng mới không được hỗ trợ ở Jekyll ver cũ, có thể update jekyll lên ver mới bằng lệnhgem update jekyll
  • Nếu update ver Jekyll ko nổi thì cài native gem bằng sudo apt-get install ruby-dev

Front matter

Nghe như "phản vật chất" trong truyện của Dan Brown ấy nhỉ hihi. "Front matter" là những thuộc tính được chú ra ở đầu mỗi file bài viết, nhằm nói với Jekyll bài viết đó muốn sử dụng layout thiết kế nào, tên bài muốn đặt là gì, và rất nhiều nữa mà chúng ta có thể tùy ý sáng tạo. Cách viết front matter rất đơn giản như sau

---
title: Tên bài viết
layout: mylayout
---

Như trên đây là front matter để thông báo tên bài viết và kiểu layout.

---
layout: post
title:  "haha"
date:   2019-06-01 21:01:15 +0700
categories: jekyll update
permalink: /haha/
yolo: lala 
---

Nếu trong front matter đề cập cả ngày tháng viết bài hay permalink thì các giá trị này sẽ đè lên ngày tháng xuất bản mặc định là ngày tạo file hoặc permalink mặc định là tên filename

giá trị defaults cho front matter

nếu không muốn suốt ngày phải lải nhải 1 value ví dụ nếu chỉ có 1 layout dùng cho tất cả các post, thì nói đi nói lại làm gì nhỉ, khi đó ta sử dụng thuộc tínhdefaults trong file _config.yml

defaults:
  -
    scope:
      path: "" 
    values:
      layout: "default"

chỗ path không cần ghi gì chỉ cần 1 string rỗng, có nghĩa là áp dụng cho toàn trang
chỗ values để chứa các front matter mặc định, ngoài layout ra còn muốn có những cái matter khác cũng được, không giới hạn số lượng.

Bài viết

Định dạng

Có thể sử dụng 3 định dạng cho bài viết:

  • html
  • markdown
  • .textfile

Thích đuôi gì ở trên cũng được miễn là có front matter là Jekyll sẽ lôi ra render thành bài viết

Riêng index.html nên được chú ý, dùng định dạng gì thì dùng nhưng hãy chêm cái front matter tử tế kẻo truy cập vào base url lại ko hiện ra 1 website mà ra cây thư mục D:

permalink đến các bài viết cho đẹp

Mặc định thì link bài viết sẽ dài dòng gồm cả danh mục, ngày tháng năm xuất bản...

http://localhost:4000/jekyll/update/2019/07/27/welcome-to-jekyll.html

vì nó theo mẫu sau

permalink: /:categories/:year/:month/:day/:title:output_ext

Muốn link bài chỉ có tên file thôi thì vô file _config.yml chêm đoạn sau:

permalink: /:title 

alt text
Ngoài ra còn các mẫu khác chúng ta xem qua cho biết thôi chứ cái nào cũng xấu cả.

date

/:categories/:year/:month/:day/:title:output_ext

pretty

/:categories/:year/:month/:day/:title/

ordinal

/:categories/:year/:y_day/:title:output_ext

weekdate

4.0.0   
/:categories/:year/W:week/:short_day/:title:output_ext

Giải nghĩa 1 số thứ trong cú pháp permalink

  • output_ext: extension
  • title: tên file, không phải tên bài viết nha
  • name: slug hoặc nếu không có slug thì cũng là tên file, và cũng không phải tên bài viết
  • categories: danh mục hoặc collection

Quy định độ dài excerpt (tóm tắt bài viết)

Theo mặc định, Jekyll lấy đoạn văn đầu tiên làm excerpt, nghĩa là nó sử dụng dấu xuống dòng để nhận diện. Chúng ta không phải tuân theo điều này và có thể sử dụng nhận diện riêng của mình bằng cách chêm vào file config:

excerpt_separator: <!--more-->
Như ở trên là nhận diện bằng kí tự <!--more-->

Nếu excerpt_separator bị làm sao hoặc bất cứ lỗi lầm gì trong việc tạo excerpt thì khi bị gọi excerpt sẽ lôi toàn bộ nội dung cả bài ra cmnl

Layout cho bài viết

Cũng không kém bố con nhà ai, Jekyll sắm sửa cho chúng ta hệ thống layout bài viết đúng quy chuẩn ra phết, đó là layout này lồng trong layout kia được, ví dụ layout post thì ăn theo từ layout default nhưng thêm tí.

Cách tạo layout:

alt text

Trong thư mục root, tạo thư mục _layouts, bên trong tạo các file layout như default.html, article.html... và tùy ý trang trí, bố cục, nội dung mặc định.

Đến phần chứa nội dung động dynamic thì sử dụng property { { content }}

include

Cách xài include

Tính năng này giúp ta quăng quật một đoạn code đi muôn nơi. Ví dụ điển hình là bỏ mấy cái header, footer, sidebar... vào thư mục _includes rồi gọi ra bằng

{% include header.html %}

Thật ra không bắt buộc là những thứ bị include phải nằm trong thư mục mang tên _includes

Gọi file trong thư mục hiện thời:

{% include_relative header.html %}

Gọi file trong thư mục con của thư mục hiện thời:

{% include_relative child-folder/header.html %}

hoặc muốn chui ra khỏi thư mục hiện thời thì ../

Cách xài include nâng cao

Nếu muốn quăng quật một đoạn code đi muôn nơi nhưng mỗi lần quăng lại thay đổi đi 1 tí thì trong lúc gọi include thì cho thêm variable vào:

Nội dung file note.html:

<div markdown="span" class="alert alert-info" role="alert">
<i class="fa fa-info-circle"></i> <b>Note:</b>
 { {  include.content }}
</div>

Đem file note.html này đi muôn nơi:

{% include note.html content="Hello World" %}

Viết nháp

Cách 1: Tạo thư mục _drafts rồi bỏ file md vào đó, thì các bài viết này sẽ không được render ra. Khi cần render có thể move các file này ra khỏi thư mục drafts.
Cách 2: Trong front matter của bài nháp, thêm property published: false

objects, properties

Để sử dụng được rất nhiều các thuộc tính của các object sẵn có khi xây dựng 1 Jekyll site, chúng ta cần trước tiên biết về sự tồn tại của chúng:

  • object lớn nhất là site gồm các properties như posts, url... các properties này mặc định hoặc tự tạo trong file config
  • object page là post hiện tại, có các properties mặc định như url, title, excerpt , excerpt_separator và các property tự tạo trong front matter. page.title thì chỉ lấy đc title của post hiện tại đang edit, nếu muốn tạo 1 cái mục lục liệt kê tất cả các tên bài viết có mặt trong blog của chúng ta thì phải sử dụng loop (sẽ giải thích sau)
  • layout
  • content
  • paginator
  • và các object khác

Gọi ra các properties

Cho tên object.property vào cặp ngoặc nhọn

 { {  page.title }}

các properties của site

static_files
data
time
pages
posts
static_files
collections là tất cả collections hoặc ngay cả tên 1 colelction cụ thể ví dụ animals có thể gọi bằng site.animals
documents

và các variables tự chế trong file config

các properties mặc định của page/post

permalink
date: nếu có date thì date này sẽ đè lên cái date ở filename
content
date
collection
categories
dir: thư mục chứa
name: filename
next, previous

Tự chế property

Ta có thể chế ra các property của project để khi cần lôi ra dùng, ví dụ 1 cái link facebook của chúng ta chẳng hạn, khi cần update thì ko phải mò vào từng chỗ đã sử dụng mà chỉ việc gọi nó ra, còn sửa value gốc ở trong file config

tênproperty có thể gồm kí tự, phân biệt hoa thường, số, dấu gạch - gạch dưới _

Chế property trong config

trong file _config.yml

alt text

Khi khai báo trong này thì dùng chung cho cả site luôn nên tiếp cận bằng cách site.propertyname

lưu ý sửa xong cái file config này ko tự reload nên phải restart server bằng ctrl c để stop rồi jekyll serve lại

Chế property trong thư mục _data

thay vì nằm tràn lan trong _config.yml thì ta có thể chia các property ra theo các nhóm, phân loaị theo nhiệm vụ hay nội dung hay bất cứ cái gì ta muốn, mỗi nhóm quăng vào 1 file yml (hoặc json, csv...), rồi quăng chung các file yml vô thư mục _data.

còn file _config.yml chỉ để chứa 1 số property cơ bản của Jekyll.

alt text

alt text

alt text

alt text

thậm chí tạo thư mục bên trong thư mục data cũng được luôn nhưng cũng chưa cần đến mức đó hic

Chế property trong front matter ở từng post

Trong front matter ở mỗi bài viết (đuôi md, html, textfile đều được. Nhưng chỉ có ở md là nó hiện đúng màu trong các trình sửa văn bản)
alt text

alt text

Khai báo trong post nào thì thuộc về post đó

trong post , tạo front matter ở trong dấu --- rồi ở nội dung post cứ thế sử dụng thôi

---
layout: post
title:  "haha"
date:   2019-06-01 21:01:15 +0700
categories: jekyll update
permalink: /haha/
yolo: lala 
---
 { {  page.yolo }}

alt text

Property nâng cao

Các property có thể có nhiều level, xuống nhiều dòng, chứa key:value...

Property nhiều level

Để tạo ra nhiều level, ta Tab thụt vào như sau

---
name:
  mom: Tom
  dad: Jerry
---

khi đó { { page.name.mom }} sẽ trả về là Tom

name:
  mom: 
    first: tom
    last: smith
  dad: Jerry
---

{ { page.name.mom.last }} sẽ trả về smith

Property nhiều dòng

Viết property trên nhiều dòng thì thêm dấu > hoặc |

> là viết trên nhiều dòng nhưng hiển thị 1 dòng nhưng khi hiện ra thì cũng chẳng khác gì là viết 1 dòng
| thì viết front matter trên nhiều dòng và hiển thị cũng trên nhiều dòng

alt text
alt text
alt text

Chú ý:

  • Tab thụt vào đầy đủ nếu không sẽ lỗi build
  • Ở thư mục _data không sử dụng được | có lẽ do lỗi của Jekyll

Property có key:value như associative array

animal:
  - one: dog
  - one: chicken
  - two: cat
 { {  page.animal }}

kết quả trả về là một array:
{“one”=>”dog”}{“one”=>”chicken”}{“two”=>”cat”}

Nếu là { { page.animal[1] }} thì trả về cặp key:value đầu tiên trong array "one"=>"dog"

Lưu ý: associative array multi level được, vẫn tab thụt vào như mọi khi

Một số ví dụ về If và For

Ở Jekyll chúng ta cho các hàm vào trong dấu {% khi mở và dấu %} khi đóng, nhìn cũng dễ thương đấy chứ nhỉ :laughing:

 {% if blablabla %}
 {% endif %}

Cách sử dụng có lẽ bản thân cú pháp đã tự giải thích cho chính nó hic.

for

{% for x in site.posts %}
   { {  x.url }}
{% endfor %}
<ul>
{% for sec in site.data.samplelist.mypages %}
{% if sec.audience == "writers" and sec.product == "gizmo" %}
<li> { { sec.url}}</li>
{% endif %}
{% endfor %}
</ul>

for trong front matter

for đối với các property front matter kiểu array 2 chiều nhiều level

salesteams:
- title: Regions
 subfolderitems:
   - location: US
   - location: Spain
   - location: France
{% for item in site.data.samplelist.salesteams %}
<h3> { { item.title}}</h3>
<ul>
{% for entry in item.subfolderitems %}
<li> { { entry.location}}</li>
{% endfor %}
</ul>
{% endfor %}

Result:

Regions
US
Spain
France

If lợi dụng front matter

---
iAmRich: true
---
 {% if page.iAmRich %}

 ...

 {% endif %}

If cho CSS

Tô sáng nav hiện tại

Tạo class:

.result li.active a {
    color: lightgray;
    cursor: default;
  }

Trong html:

{% for item in site.data.samplelist.docs %}
    <li class="{% if item.url == page.url %}active{% endif %}">
      <a href=" { {  item.url }}"> { {  item.title }}</a>
    </li>
{% endfor %}

Kết quả

alt text

collections

collection là cách mà Jekyll gọi các loại hình thức post khác nhau, tương tự bên Wordpress có "post type" thì đây Jekyll gọi là "collection" . Ví dụ mình đăng các bài review sách và phim thì ko thể sách hay phim đều quăng vào _posts được sẽ khó quản lí tìm loạn lên, hơn nữa các bài review này sẽ có các giao diện khác nhau nên để tiện lợi hơn mình sẽ tạo 2 thư mục _books_movies

my_collections các loại post type

Khác nhau giữa collections và categories

categories là tính năng phân loại bài viết theo thể loại của Jekyll version cũ, khi so sánh với collections thì mình thấy nên sử dụng collections vì:

  • Khi viết bài theo kiểu categories sẽ phải bị buộc đặt filename theo cú pháp có ngày tháng xuất bản. Rất mất công. Khi sử dụng collection thì đặt filename cho file bài viết sẽ ko phải thêm ngày tháng (ngày đăng chính là ngày tạo file, ngoài ra kể cả muốn đè lên ngày tạo file thì vẫn làm trong front matter được)
  • Khi chia bài theo kiểu categories thì lúc nào file bài viết cũng phải vứt vô cái thư mục chung tên là _posts rồi lại còn thư mục con gì gì nữa... rất lằng nhằng và ngứa mắt

Cách sử dụng collections

khai báo tên collection

trong config

collections:
  animals:
    output: true

rồi tạo 1 thư mục trong root tên là _animals
alt text

gom các thư mục collection lại (jekyll ver 3.7.0)

Nếu có nhiều collection quá mà ko muốn lan tràn trong thư mục root thì nhét tất thư mục collection vào 1 thư mục với cái tên không được bắt đầu bằng _ rồi khai báo thư mục tổng đó ở trong config nhưng bản Jekyll của mình nâng mãi ko lên được nên mình chưa test thành công cách này.

collections_dir: collections

Rút bài từ collection

Giả sử muốn liệt kê tất cả bài viết trong tất cả các collections trong site của mình


 {% for eachcollection in site.collections %}
       { {  eachcollection.label }}
      {% for eachpost in site.[eachcollection.label] %}
              { {  eachpost.title }}
      {% endfor %}
  {% endfor %}

Chú ý không nhầm như sau:

{% for eachcollection in site.collections %}

   { {  eachcollection.label }} 

        {% for eachpost in eachcollection %}

         { {  eachpost.title }}

        {% endfor %}

{% endfor %}

Hum nay đến đây đã, còn nốt đoạn thông CMS vào là xong ngon, hôm sau mềnh sẽ đào bới tiếp!

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

mòe

14 bài viết.
328 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
100 44
google cách học tốt tiếng anh thì ra hàng đống kết quả nhưng đảm bảo không có cái nào dùng được (nếu dùng được thì bạn đã tiến bộ rồi phải không). ...
mòe viết hơn 1 năm trước
100 44
White
42 10
(Ảnh) Dùng CSS để "sửa" nội dung HTML Ngoài nguyên nhân là muốn chơi nổi thì lí do phải dùng code CSS để tác động vào HTML là khi bạn không được ...
mòe viết 9 tháng trước
42 10
White
31 15
Bài này sẽ hướng dẫn tạo theme Wordpress mà không sử dụng gì. Gồm 5 phần với thứ tự như sau: Tạo theme tĩnh, Các khái niệm dễ gây nhầm lẫn trong Wo...
mòe viết 7 tháng trước
31 15
Bài viết liên quan
Male avatar
9 0
Giới thiệu về JAM Stack trong phát triển phần mềm Gần đây, JAM stack trở nên phổ biến hơn bên cạnh các stack hiện có như LAMP, MEAN. Trong bài viế...
tony.teo viết 9 tháng trước
9 0
White
18 2
Trước đây vài ngày, tôi có chuyển hẳn website từ (Link) sử dụng Namecheap hosting sang (Link) sử dụng (Link) lưu trữ website trực tiếp trên Github....
Nguyễn Việt Anh viết 2 năm trước
18 2
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
14 bài viết.
328 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!