지킬 Tale테마 카테고리 만들기

서론

필자는 JekyllTale테마를 이용해서 Github Page를 운영하고 있다.

Tale테마가 제일 예쁘다고 생각되서 바로 포크해서 가져왔다.

페이지네이션도 있고 무엇보다 깔끔해서 마음에 들었는데 한가지 의문점이 들었다.

도대체 Tale과 Posts는 왜 같은 곳을 가리키는거지??

그래서 Posts를 카테고리로 바꾸기로 했다!

1) 카테고리 생성

기본적으로 Tale엔 카테고리가 없기에 만들어야한다.

출처: 지킬(Jekyll) 블로그 카테고리(category) 만들기

물론 필자는 루비에 전혀 지식이 없기에 검색엔진과 이 블로그를 상당히 많이 참조했다.

일단 최상위 디렉토리에 카테고리 폴더를 생성해준다.
그 후 카테고리의 이름.md 파일을 생성한다.

이제 파일 안에 내용을 작성한다.

---

layout: category
title: 알고리즘
category: algorithm
weight: 3

---

title은 카테고리를 눌렀을 때 탭의 이름이고
category는 글을 분류하기 위한 영문 키워드이고
weight는 내가 원하는 대로 정렬하기 위한 가중치이다.

2) Tale nav의 구조 및 수정

Tale은 크게 나눴을때 nav, main, footer로 구성되어있다.
우리가 볼 것은 _includes/navigation.html 파일에 있는
nav안에 존재하는 Posts라는 a태그다.

<nav class="nav">  
	<div class="nav-container">  
		<a href="{{ site.baseurl }}/">  
			<h2 class="nav-title">{{ site.title }}</h2>  
		</a>  
		<ul>  
			<li><a href="{{ '/about' | prepend: site.baseurl }}">About</a></li>  
			<li><a href="{{ site.baseurl }}/">Posts</a></li>
			</ul>  
	</div>  
</nav>  
  

역시 site.baseurl이 중복으로 나타나고 있다.

이를 다음과 같이 수정해준다.

<nav class="nav">
	<div class="nav-container">
		<a href="{{ site.baseurl }}/">
			<h2 class="nav-title">{{ site.title }}</h2>
		</a>
		<ul>
			<li>
				<a href="{{ '/about' | prepend: site.baseurl }}">소개</a>
			</li>
      {% assign pages_list = site.pages | sort:"weight" %} 
      {% for node in pages_list %} 
      {% if node.title != null %} 
      {% if node.layout == "category" %}
      <li>
        <a class="category-link {% if page.url == node.url %} active{% endif %}" href="{{ site.baseurl }}{{ node.url }}">{{ node.title }}</a>
      </li>
      {% endif %} {% endif %} {% endfor %}
		</ul>
	</div>
</nav>
  

이렇게 하면 내가 생성한 카테고리들이 싹 나온다!

이제 클릭했을시 카테고리에 해당하는 포스트들을 보여주기위해 _layouts폴더에 category.html을 만들고 이와 같이 작성한다.

---  
layout: default  
---  
<ul class="posts-list">  
	{% assign category = page.category | default: page.title %}  
	{% for post in site.categories[category] %}  
		<li>  
			<h3>  
				<a href="{{ site.baseurl }}{{ post.url }}">  
					{{ post.title }}  
				</a>  
			<small>{{ post.date | date: "%Y. %m. %d.(%a)" }}</small>  
			</h3>  
		</li>  
	{% endfor %}  
</ul>  

카테고리로 분류한 요소들이 잘 나오는 것을 확인할 수 있다.

필자는 UI의 통일성을 위해 home화면에서 보이는 요소들을 카테고리에서도 똑같이 보이게 만들 것이다.

따라서 category.html을 수정한다.

---
layout: default
---
<div class="catalogue">
  {% assign category = page.category %}
  {% assign title = page.title %}

  <h1>{{ title }}</h1>
  {% for post in site.categories[category] %}
  <a href="{{ post.url | prepend: site.baseurl }}" class="catalogue-item">
    <div>
      <time datetime="{{ post.date }}" class="catalogue-time">{{ post.date | date: "%Y. %m. %d" }}</time>
      <h1 class="catalogue-title">{{ post.title }}</h1>
      <div class="catalogue-line"></div>

      <p>
        {{ post.excerpt | markdownify | strip_html | markdownify }}
      </p>

    </div>
  </a>
  {% endfor %}
  
</div>

3) 드롭다운

필자는 클릭시 드롭다운이 펼쳐지고 다시 클릭시 접히는 형식을 택했다.
이런 편이 모바일 기기에 편했다.

hover와 click둘다 해봤지만 click쪽이 아무래도 편했다

먼저 _includes/navigation.html의 코드를 수정하겠다

<nav class="nav">
	<div class="nav-container">
		<a href="{{ site.baseurl }}/">
			<h2 class="nav-title">{{ site.title }}</h2>
		</a>
		<ul>
			<li>
				<a href="{{ '/about' | prepend: site.baseurl }}">소개</a>
			</li>
			<li class="dropdown">
				<input id="check-dropdown" type="checkbox" name="menu">
				<label for="check-dropdown">카테고리</label>
				<div class="dropdown-content">
					{% assign pages_list = site.pages | sort:"weight" %} 
					{% for node in pages_list %} 
					{% if node.title != null %} 
					{% if node.layout == "category" %}
					<a class="category-link {% if page.url == node.url %} active{% endif %}" href="{{ site.baseurl }}{{ node.url }}">{{ node.title }}</a>
					{% endif %} {% endif %} {% endfor %}
				</div>
			</li>
		</ul>
	</div>
</nav>

이제 label를 클릭하면 input이 체크되거나 체크가 해제될 것이고
이에 따라 div.dropdown-content를 보이게하면 된다!

이는 CSS를 사용해서 구현할 것이다.

다음은 _sass/tale/_layout.scss파일의 일부분이다

.nav {
  ...
	
	//dropdown layout
	.dropdown {	
		padding: 0;
		input { display: none; }
		input:checked~div.dropdown-content {
  		max-height: 300px;
			-webkit-transition: max-height 0.2s ease-out;
			-moz-transition: max-height 0.2s ease-out;
			-ms-transition: max-height 0.2s ease-out;
			-o-transition: max-height 0.2s ease-out;
			transition: max-height 0.2s ease-out;
		}
		
		label {
      display: block;
			cursor: pointer;
		}
		opacity: 1;
	}
	
	.dropdown-content {
		-webkit-transition: max-height 0.2s ease-out;
		-moz-transition: max-height 0.2s ease-out;
		-ms-transition: max-height 0.2s ease-out;
		-o-transition: max-height 0.2s ease-out;
		transition: max-height 0.2s ease-out;
		margin: .5rem 0 0 0;
		overflow: hidden;
		background-color: #f9f9f9;
		min-width: 115px;
		max-height: 0px;
		position: sticky;
		a {
			padding: 12px 16px;
			text-decoration: none;
			display: block;
			text-align: left;
		}
	}
  &::after { 
    content:''; 
    display:table; 
    clear:both; 
  }
}

중요한 부분만 가져왔다.
.dropdown-content의 높이를 0으로 한다.
이는 transition을 원활하게 적용시키기 위함이다.

input이 체크상태가 된다면 형제인 div.dropdown-content의 높이를 300px로 지정한다.
이렇게 변화함으로써 transition이 적용되게 된다.

중요한 점은 .nav의 overflow속성을 지워야 된다는 것이다.
그래야 카테고리가 잘 나온다.
대신 공간을 주기 위해 ::after속성으로 공간을 마련한다.

참고로 위 코드는 모바일 환경에서 적용되는 코드이다.

데스크탑 환경에서도 잘 사용하기 위해 추가로 미디어 쿼리를 손보았다.

@media (min-width: 600px) {
  .nav {
    &-container {
      text-align: left;
    }

    ul {
      bottom: 0;
      position: absolute;
      right: 0;
    }

    li {
      opacity: .6;
      display: inline-block;
      padding: 0 2rem 0 0;
    }

    .dropdown {
      .dropdown-content {
        position: absolute;
        box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);

        a:hover {
          background-color: #f1f1f1;
        }
      }
    }
  }
}

필자의 _layout.scss 전체 소스는 여기서 확인할 수 있다.
소스

끝맺음

수정 2022.10.23

필자는 Jekyll, Ruby on rails는 잘 모르지만 공식문서, 블로그를 보고 여차여차 잘 해결했다.
내 입맛대로 고치니 아주 좋다!

한가지 주의할 점은 이 글은 철저하게 Tale 테마를 사용하는 유저가 Tale 테마를 뜯어 고친것이기 때문에
정말 그대로 따라하다간 동작이 안 될 수도 있다.
그 부분만 조심하면 되겠다.