Jekyll & Liquid 시작하기 (2)

Updated:

Jekyll & Liquid 시작하기 (1)에 이은 두 번째 정리

주요 관련 사이트 링크:

6. includes

{% include filename %}

<site root>/_includes/ 폴더를 만들고, 안에 head.html을 아래와 같이 입력한다.

<head>
  <meta charset="UTF-8">
  <title>{{ page.title }}</title>
</head>

_includes에 있는 코드는 {% include <filename> %} 방식으로 어디서든 내용을 포함 시킬 수 있다. <site root>/_layouts/default.html을 아래와 같이 수정한다.

<!DOCTYPE html>
<html>
{% include head.html %}
<body>
  {{ content }}
</body>
</html>

<site root>/_layouts/page.html을 원래대로 아래와 같이 작성한다.

---
layout: default
---
<h2>start page layout</h2>
{{ content }}

마찬가지로 <site root>/index.html을 원래대로 아래와 같이 작성한다.

---
layout: page
title: My Homepage
---
<h1>Introduction to layouts</h1>

build 결과 <site root>/_site/index.html는 다음과 같다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My Homepage</title>
</head>
<body>
  <h2>start page layout</h2>
<h1>Introduction to layouts</h1>
</body>
</html>

include에 parameters 전달

<site root>/_includes/foo.html 의 내용이 다음과 같고,

<h3 style="color:{{ include.color }}">foo.html in includes</h3>

<site root>/temp.html의 내용이 아래와 같다고 하자.

---
---
{% include foo.html color="red" %}

build후에 <site root>/_site/temp.html의 결과는 다음과 같다.

<h3 style="color:red">foo.html in includes</h3>

7. Liquid 흐름제어문

CloudCannon 튜토리얼7 에서는 다음과 같은 내용을 소개하고 있다.

  • collection을 만드는 방법
  • collection을 참조하는 방법(site.을 이용)
  • collection과 for, if 등을 조합한 예제
  • 비교 연산자 !=, < , >=
  • 특정 문자열이 속해 있는가? {% if "Chocolate" contains "Choco" %}
  • unless
  • case & when

다른 것들은 이미 살펴보았거나 앞으로 다시 나올 것이기 때문에 여기서는 unlesswhen의 기능만 살펴본다.

unless

아래 파일은 ex7-1.html이다. unless는 “조건이 아니면”의 의미로 if와 반대이다. {% unless item.score >= 90 %}{% if item.score < 90 %} 과 같다. 닫는 문법이 {% endunless %} 임을 주의하라.

---
obj:
  - name: abc
    score: 90
  - name: def
    score: 95
  - name: ghi
    score: 80
---
{% for item in page.obj %}
  {% unless item.score >= 90 %}
    <h2>name={{ item.name }}, score={{ item.score }}</h2>
  {% endunless %}
{% endfor %}

build 결과는 아래와 같다. (이제 부터 빈줄은 생략한다.)

    <h2>name=ghi, score=80</h2>

when

아래 파일은 ex7-2.html이다.

---
obj:
  - name: abc
    id: 1
  - name: def
    id: 2
  - name: ghi
    id: 3
  - name: jkl
    id: 2
---
{% for item in page.obj %}
  {% case item.id %}
    {% when 1 %}
       <h2>{{ item.name }} : apple</h2>
    {% when 2 %}
       <h2>{{ item.name }} : banana</h2>
    {% when 3 %}
       <h2>{{ item.name }} : melon</h2>
  {% endcase %}
{% endfor %}

{% when 1 %}{% if item.id == 1 %} 과 동일한 쓰임이지만 좀 더 깔끔해 보인다. build 결과는 다음과 같다.

       <h2>abc : apple</h2>
       <h2>def : banana</h2>
       <h2>ghi : melon</h2>
       <h2>jkl : banana</h2>

8. 문자열 필터 (String filters)

이미 한번 나왔었던 필터에 대한 더 자세한 예시를 보여준다. 필터에 대한 더 많은 자료는 Liquid를 참고할 것. 아래 표 데이터를 보면서 기능을 어떤게 있구나 정도로 넘어가고 나중에 필요할 때 다시 찾아보면 될 것 같다.

필터 결과
{{ "apple pie" | replace: "apple", "banana" }} banana pie
{{ "cupcake" | prepend: "chocolate " }} chocolate cupcake
{{ "lemon" | append: " cake" }} lemon cake
{{ "i like cupcakes" | capitalize }} I like cupcakes
{{ "BakeryStore" | downcase }} bakerystore
{{ "apple pie" | upcase }} APPLE PIE
{{ "muffin&cupcake?" | cgi_escape }} muffin%26cupcake%3F
{{ "<h1>Banana Split</h1>" | escape }} <h1>Banana Split</h1>
{{ "blueberry muffin.html" | slugify }} blueberry-muffin-html
{{ "<h1>Greentea cheesecake</h1>" | strip_html }} Greentea cheesecake
{{ "**Sour dough** bread" | markdownify }} Sour dough bread
{{ "I really really like cupcakes" | remove_first: 'really' }} I really like cupcakes
{{ "I really really like cupcakes" | remove: 'really' }} I like cupcakes
{{ "I really really like cupcakes" | replace_first: "really", "truly" }} I truly really like cupcakes
{{ "I really really like cupcakes" | replace: "really", "truly" }} I truly truly like cupcakes
{{ "Carrot cake" | size }} 11
{{ "Peanut butter cheesecake" | number_of_words }} 3
{{ "Souffle" | slice: 0 }} S
{{ "Souffle" | slice: 1 }} o
{{ "Souffle" | slice: -2 }} l
{{ "Souffle" | slice: 2,4 }} uffl
{{ "apple,banana,carrot" | split:"," | jsonify }} [“apple”,”banana”,”carrot”]
{{ "The freshest bread in San Francisco" | truncate: 15 }} The freshest…
{{ "Who ate all the cupcakes?" | truncatewords: 3 }} Who ate all…

9. 반복 (Loop)

이 tutorial에서는 loop 를 사용하는데 여러가지 기능들을 더 소개해 주고 있다.

cycle

아래 파일은 ex9-1.html이다. {% cycle <items> %} 는 호출될 때 마다 항목을 순차적으로 하나씩 불러온다.

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr %}
    <h2>{{ item }} = {% cycle "x", "y", "z" %}</h2>
{% endfor %}

build 결과는 다음과 같다. (빈 줄은 생략)

    <h2>a = x</h2>
    <h2>b = y</h2>
    <h2>c = z</h2>
    <h2>d = x</h2>

forloop.index

아래 파일은 ex9-2.html이다. forloop.index를 사용하면 1부터 시작하는 loop index을 얻을 수 있다. 0부터 시작하는 index는 forloop.index0를 쓰면 된다.

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr %}
    <h2>{{ item }} {{ forloop.index }} {{ forloop.index0 }}</h2>
{% endfor %}

build 결과는 다음과 같다. (빈 줄은 생략)

    <h2>a 1 0</h2>
    <h2>b 2 1</h2>
    <h2>c 3 2</h2>
    <h2>d 4 3</h2>

forloop.first and forloop.last

아래 파일은 ex9-3.html이다. forloop.first, forloop.last는 루프의 첫번째와 마지막 인덱스를 얻는다.

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr %}
    {% if forloop.first or forloop.last %}
        <h2>{{ item }}</h2>
	{% endif %}
{% endfor %}

build 결과는 다음과 같다. (빈 줄은 생략)

        <h2>a</h2>
        <h2>d</h2>

forloop.rindex

아래 파일은 ex9-4.html이다. forloop.rindex는 현재 반복될 루프가 몇 번 남았는가를 알려준다. (응용이 궁금하다면 9. Looping in Liquid참고)

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr %}
        <h2>{{ item }} {{ forloop.rindex }}</h2>
{% endfor %}

build 결과는 다음과 같다. (빈 줄은 생략)

        <h2>a 4</h2>
        <h2>b 3</h2>
        <h2>c 2</h2>
        <h2>d 1</h2>

forloop.length

아래 파일은 ex9-5.html이다. 루프 안에서 forloop.length는 루프의 크기를 넘겨준다. 당연하지만 루프 밖에서는 forloop.length가 안먹히고 그때는 page.arr.size 처럼 array의 크기를 이용한다.

---
arr:
  - a
  - b
  - c
  - d
---
{{ page.arr.size }}
{% for item in page.arr %}
        <h2>{{ item }} {{ forloop.length }}</h2>
{% endfor %}

build 결과이다.

4
        <h2>a 4</h2>
        <h2>b 4</h2>
        <h2>c 4</h2>
        <h2>d 4</h2>

continue, break, reversed

아래 파일은 ex9-6.html이다. 루프 제어를 위한 {% continue %}, {% break %}, reversed 등이 있다.

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr %}
    {% if forloop.index == 3 %}
        {% continue %}  
	{% endif %}
    <h2>{{ item }} {{ forloop.index }}</h2>
{% endfor %}

{% for item in page.arr %}
    {% if forloop.index == 3 %}
        {% break %}  
	{% endif %}
    <h2>{{ item }} {{ forloop.index }}</h2>
{% endfor %}

{% for item in page.arr reversed %}
    <h2>{{ item }} {{ forloop.index }}</h2>
{% endfor %}

build 결과이다. (빈 줄은 적절히 생략)

    <h2>a 1</h2>   
    <h2>b 2</h2>
    <h2>d 4</h2>

    <h2>a 1</h2>
    <h2>b 2</h2>

    <h2>d 1</h2>
    <h2>c 2</h2>
    <h2>b 3</h2>
    <h2>a 4</h2>

limit and offset

아래 파일은 ex9-7.html이다. offset은 루프 시작위치이고 limit 는 최대 반복횟수다. 주의점은 offset 시작은 0이라는 것이다.

---
arr:
  - a
  - b
  - c
  - d
---
{% for item in page.arr limit: 2 offset: 1 %}
    <h2>{{ item }}</h2>
{% endfor %}

build 결과이다.

    <h2>b</h2>
    <h2>c</h2>

else

아래 파일은 ex9-8.html이다. YAML에서 빈 array을 만드는 방법은 arr = [] 인 것 같다. 루프에서 빈 array를 처리할 때 else를 사용할 수도 있다.

---
arr: []
---
{% for item in page.arr %}
    <h2>{{ item }}</h2>
{% else %}
    <h2>empty array</h2>
{% endfor %}

build 결과는 다음과 같다.

    <h2>empty array</h2>

range

liquid 정식문서를 보니 range도 정리할 필요가 있어 보인다. 입력한 범위 정수 array 비스무리 한 걸 만드나 보다.

---
---
{% assign num = 3 %}
{% for i in (1..num) %}
    <h2>{{ i }}</h2>
{% endfor %}

build 결과는 다음과 같다.

    <h2>1</h2>
    <h2>2</h2>
    <h2>3</h2>

Leave a comment