Multiple and Hierarchical Category » 이력 » 버전 10

Jinwuk Admin, 2018/07/25 15:15

1 1 Jinwuk Admin
h1. Multiple and Hierarchical Category
2 1 Jinwuk Admin
3 3 Jinwuk Admin
기본적으로는 Wordpress 등에서 제공하는 다음과 같은 계층적 Category를 구현하기 위해서이다. 
4 1 Jinwuk Admin
5 2 Jinwuk Admin
!picture940-1.png!
6 1 Jinwuk Admin
7 1 Jinwuk Admin
인터넷에 살펴보면 여러가지 방법론들이 나오는데, 여기에서는 오직, Category 만으로 이러한 계층적 Category를 만들고 Sidebar 에 구현하고 이를 이용할 수 있도록 해 보고자 한다.
8 3 Jinwuk Admin
여기서는 Hydeout Theme를 기본으로 구현 하였다.
9 1 Jinwuk Admin
10 3 Jinwuk Admin
Hydeout Theme 는 다음의 특징을 가지고 있다.
11 3 Jinwuk Admin
* Jekyll 3.x 의 특성을 충실히 반영하고 있다.
12 3 Jinwuk Admin
* Jekyll 을 이용한 Blog를 만들시 의 가장 기본적인 구조인 Minimal Theme에서 Sidebar 구조를 제외하고는 크게 변경된 것이 없다. 
13 3 Jinwuk Admin
14 3 Jinwuk Admin
그러므로 Hydeout Theme에서 사용된 기법을 다른 Theme에 적용시키는 것은 거의 문제가 없을 것으로 본다.
15 3 Jinwuk Admin
16 1 Jinwuk Admin
h2. 기본 구조
17 1 Jinwuk Admin
18 1 Jinwuk Admin
Category를 다음과 같은 기본 구조로 만들고 싶다.
19 1 Jinwuk Admin
20 1 Jinwuk Admin
<pre>
21 3 Jinwuk Admin
------ 상위 Category (1)
22 3 Jinwuk Admin
 |  |---- 하위 Category (1)
23 3 Jinwuk Admin
 |  |---- 하위 Category (2) 
24 3 Jinwuk Admin
 |---- 상위 Category (2)
25 3 Jinwuk Admin
    |---- 하위 Category (3)
26 4 Jinwuk Admin
</pre>
27 3 Jinwuk Admin
28 3 Jinwuk Admin
h3. Multiple and Hierarchical 구조를 위한 기본 Front matter
29 3 Jinwuk Admin
30 3 Jinwuk Admin
기본적으로 Fron matter를 어떻게 설계 하느냐가 중요하다.
31 3 Jinwuk Admin
32 3 Jinwuk Admin
다음과 같이 Category의 Front matter를 놓는다.
33 3 Jinwuk Admin
34 3 Jinwuk Admin
<pre><code class="ruby">
35 3 Jinwuk Admin
---
36 3 Jinwuk Admin
layout: category
37 3 Jinwuk Admin
title: Briefs
38 3 Jinwuk Admin
menu: true
39 3 Jinwuk Admin
submenu: true
40 3 Jinwuk Admin
order: 2
41 3 Jinwuk Admin
---
42 3 Jinwuk Admin
</code></pre>
43 3 Jinwuk Admin
44 3 Jinwuk Admin
중요한 부분은 menu와 submenu의 존재이다. 이것을 사용하여 html 에서 상위 Category인지 하위 Category인지를 파악하고자 한다.
45 3 Jinwuk Admin
46 3 Jinwuk Admin
* menu 에서 true 이면 sidebar 에서 category 의 이름이 나타나도록 하며 최상위 category 임을 의미한다.
47 3 Jinwuk Admin
* submenu 에서 true 이면 자신의 category에 속하는 하위 category가 있음을 나타낸다.
48 3 Jinwuk Admin
49 3 Jinwuk Admin
하위 category의 Front matter는 다음과 같이 놓는다.
50 3 Jinwuk Admin
예를 들어 "Brief" category 에 속하는 "Machine Learning" Category를 다음과 같아야 한다.
51 3 Jinwuk Admin
52 3 Jinwuk Admin
<pre><code class="ruby">
53 3 Jinwuk Admin
---
54 3 Jinwuk Admin
layout: category
55 3 Jinwuk Admin
title: Machine Learning
56 3 Jinwuk Admin
category: Briefs
57 3 Jinwuk Admin
menu: false
58 3 Jinwuk Admin
order: 2
59 3 Jinwuk Admin
---
60 3 Jinwuk Admin
</code></pre>
61 3 Jinwuk Admin
62 1 Jinwuk Admin
* 최상위 category사 아니므로 menu는 false 이다. 
63 4 Jinwuk Admin
* 만일 하위 category를 주고 싶다면 submenu에서 true를 준다.
64 4 Jinwuk Admin
65 4 Jinwuk Admin
마지막으로 post는 다음과 같이 쓰면 된다.
66 4 Jinwuk Admin
67 4 Jinwuk Admin
<pre><code class="ruby">
68 4 Jinwuk Admin
---
69 4 Jinwuk Admin
layout: post
70 4 Jinwuk Admin
title:  "Deep Image Compression via End to End Learning"
71 4 Jinwuk Admin
date:   2018-07-07 22:03:00 +0900
72 4 Jinwuk Admin
categories: [Briefs, Machine Learning]
73 4 Jinwuk Admin
tags:
74 4 Jinwuk Admin
  - Machine-Learning
75 4 Jinwuk Admin
subtitle:   "Machine Learning"  
76 4 Jinwuk Admin
comments: true
77 4 Jinwuk Admin
---
78 4 Jinwuk Admin
</code></pre>
79 4 Jinwuk Admin
80 4 Jinwuk Admin
* category는 복수이므로 caterories가 되고 상위는 Brief 그리고 하위는 Machine Learning임을 가켜야 한다.
81 5 Jinwuk Admin
82 6 Jinwuk Admin
h2. HTML 편집
83 7 Jinwuk Admin
84 7 Jinwuk Admin
Hydeout 기본 테마에서는 가장 높은 단계의 Category 혹은 Category 폴더의 Category가 모두 나타난다.
85 7 Jinwuk Admin
Post 에서는 만일 [category_1, Category_2] 라고 Post의 Front matter에 적었다면, 모든 상위, 하위 Category에서 두 Category중 하나라도 속하는 post가 모두 표시된다.
86 7 Jinwuk Admin
87 7 Jinwuk Admin
우리가 원하는 것은 상위 Category에 속하는 post가 표시되고 하위 Category에 표시되는 것은 상위 Category에 표시되는 것 중 하위 Category에 속하는 post만 표시 되었으면 한다.
88 7 Jinwuk Admin
89 8 Jinwuk Admin
이러한 기능이 구현 되려면, HTML 에서는 Side bar에 계층적 Category가 나타나도록 하는 것과, Post에서 계층적 Category에서의 Post가 정확히 표시 되도록 하는 2가지 기능이 제공되어야 한다.
90 7 Jinwuk Admin
91 7 Jinwuk Admin
h3. HTML 에서는 Side bar에 계층적 Category가 나타나도록 하는 것
92 7 Jinwuk Admin
93 7 Jinwuk Admin
sidebar를 표시하는 HTML은 다음과 같다. (sidebar.html in _includes 폴더)
94 7 Jinwuk Admin
95 7 Jinwuk Admin
<pre><code class="ruby">
96 7 Jinwuk Admin
<div id="sidebar">
97 7 Jinwuk Admin
  <header>
98 7 Jinwuk Admin
    <{% if page.layout == "index" %}h1{% else %}div{% endif %} class="site-title">
99 7 Jinwuk Admin
      <a href="{{ site.baseurl }}/">
100 7 Jinwuk Admin
        {% unless page.url == "/" %}
101 7 Jinwuk Admin
          <span class="back-arrow icon">{% include svg/back-arrow.svg %}</span>
102 7 Jinwuk Admin
        {% endunless %}
103 7 Jinwuk Admin
        {{ site.title }}
104 7 Jinwuk Admin
      </a>
105 7 Jinwuk Admin
    </{% if page.layout == "index" %}h1{% else %}div{% endif %}>
106 7 Jinwuk Admin
    <p class="lead">{{ site.description }}</p>
107 7 Jinwuk Admin
  </header>
108 7 Jinwuk Admin
  {% include sidebar-nav-links.html %}
109 7 Jinwuk Admin
110 7 Jinwuk Admin
  {% if site.version %}
111 7 Jinwuk Admin
    <span class="site-version">Currently v{{ site.version }}</span>
112 7 Jinwuk Admin
  {% endif %}
113 7 Jinwuk Admin
114 7 Jinwuk Admin
  {% include sidebar-icon-links.html %}
115 7 Jinwuk Admin
  {% include copyright.html %}
116 7 Jinwuk Admin
</div>
117 7 Jinwuk Admin
</code></pre>
118 1 Jinwuk Admin
119 8 Jinwuk Admin
여기에서 *sidebar-nav-links.html*를 수정하여 계층적 카테고리가 표시될 수 있도록 한다.
120 8 Jinwuk Admin
Hydeout 테마에서 원래의 sidebar-nav-links.html 은 다음과 같다.
121 1 Jinwuk Admin
122 8 Jinwuk Admin
<pre><code class="html">
123 8 Jinwuk Admin
<nav id="sidebar-nav-links">
124 8 Jinwuk Admin
  {% if site.sidebar_home_link %}
125 8 Jinwuk Admin
    <a class="home-link {% if page.url == '/' %} active{% endif %}"
126 8 Jinwuk Admin
        href="{{ site.baseurl }}/">Home</a>
127 8 Jinwuk Admin
  {% endif %}
128 8 Jinwuk Admin
  {% if site.sidebar_blog_link %}
129 8 Jinwuk Admin
    <a class="page-link {% if page.url == site.sidebar_blog_link %} active{% endif %}"
130 8 Jinwuk Admin
	href="{{ site.baseurl }}{{ site.sidebar_blog_link }}">Blog</a>
131 8 Jinwuk Admin
  {% endif %}
132 8 Jinwuk Admin
133 8 Jinwuk Admin
  {% comment %}
134 8 Jinwuk Admin
    The code below dynamically generates a sidebar nav of pages with
135 8 Jinwuk Admin
    `sidebar_link: true` in the front-matter. See readme for usage.
136 8 Jinwuk Admin
  {% endcomment %}
137 8 Jinwuk Admin
138 8 Jinwuk Admin
  {% include page-links.html %}
139 8 Jinwuk Admin
  {% include category-links.html %}
140 8 Jinwuk Admin
141 8 Jinwuk Admin
  {% include custom-nav-links.html %}
142 8 Jinwuk Admin
</nav>
143 8 Jinwuk Admin
</code></pre> 
144 8 Jinwuk Admin
145 8 Jinwuk Admin
여기를 살펴보면 *category-links.html* 를 통해 Category가 표시됨을 알 수 있다.
146 8 Jinwuk Admin
다시, category-links.html 를 살펴보면 
147 8 Jinwuk Admin
148 8 Jinwuk Admin
<pre><code class="html">
149 8 Jinwuk Admin
{% comment %}
150 8 Jinwuk Admin
  Dynamically generate list of links to all category pages
151 8 Jinwuk Admin
{% endcomment %}
152 8 Jinwuk Admin
{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}
153 8 Jinwuk Admin
{% for node in pages_list %}
154 8 Jinwuk Admin
  {% if node.title != null %}
155 8 Jinwuk Admin
    {% if node.layout == "category" %}
156 8 Jinwuk Admin
      <a class="category-link {% if page.url == node.url %} active{% endif %}"
157 8 Jinwuk Admin
          href="{{ site.baseurl }}{{ node.url }}">{{ node.title }}</a>
158 8 Jinwuk Admin
    {% endif %}
159 8 Jinwuk Admin
  {% endif %}
160 8 Jinwuk Admin
{% endfor %}
161 8 Jinwuk Admin
</code></pre>
162 8 Jinwuk Admin
163 8 Jinwuk Admin
site 내의 page의 내용을 읽고 (@{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}@) 이중에서 category에 해당하는 layout 정보에서 url을 가진 Category 제목을 side bar에 표시하는 것이다.
164 8 Jinwuk Admin
165 8 Jinwuk Admin
그러므로, 계층적 category가 표시될 수 없다.
166 8 Jinwuk Admin
167 8 Jinwuk Admin
이것을 다음과 같이 수정하여 계층적으로 표시한다.
168 8 Jinwuk Admin
169 8 Jinwuk Admin
<pre><code class="ruby">
170 8 Jinwuk Admin
{% comment %}
171 8 Jinwuk Admin
  Dynamically generate list of links to all category pages
172 8 Jinwuk Admin
{% endcomment %}
173 8 Jinwuk Admin
174 8 Jinwuk Admin
{% assign pages_list = site.pages| where: "menu", true |sort:"sidebar_sort_order" %}
175 8 Jinwuk Admin
{% assign subpages   = site.pages| where: "menu", false|sort:"sidebar_sort_order" %}
176 8 Jinwuk Admin
177 8 Jinwuk Admin
{% assign count = 0%}
178 8 Jinwuk Admin
{% for node in pages_list %}
179 8 Jinwuk Admin
  {% if node.title != null %}
180 8 Jinwuk Admin
    {% if node.layout == "category" %}
181 8 Jinwuk Admin
    {% assign count = count | plus: 1 %}
182 8 Jinwuk Admin
      <div  class="list-wrapper">
183 8 Jinwuk Admin
	  <a class="category-link {% if page.url == node.url %} active{% endif %}"
184 8 Jinwuk Admin
          href="{{ site.baseurl }}{{ node.url }}">{{ node.title }}</a>
185 8 Jinwuk Admin
	    {% if node.submenu %}<label class="folder" for="list-item-{{ count }}">▾</label>{% endif %}
186 8 Jinwuk Admin
	  </div>
187 8 Jinwuk Admin
      <ul class="list-body">
188 8 Jinwuk Admin
		{% for subnode in subpages %}
189 8 Jinwuk Admin
			{% if subnode.layout == "category" %}
190 8 Jinwuk Admin
			    {% if subnode.category == node.title %}	
191 8 Jinwuk Admin
					<li>
192 8 Jinwuk Admin
					<a class="sidebar-nav-subitem{% if page.url == subnode.url %} active{% endif %}" href="{{ subnode.url | relative_url }}">{{ subnode.title }}</a>
193 8 Jinwuk Admin
					</li>
194 8 Jinwuk Admin
				{% endif %}
195 8 Jinwuk Admin
            {% endif %}
196 8 Jinwuk Admin
		{% endfor %}
197 8 Jinwuk Admin
	  </ul>
198 8 Jinwuk Admin
	{% endif %}
199 8 Jinwuk Admin
  {% endif %}
200 8 Jinwuk Admin
{% endfor %}
201 8 Jinwuk Admin
</code></pre>
202 8 Jinwuk Admin
  
203 8 Jinwuk Admin
먼저, *subpages* 변수를 선언하고, *menu* 변수가 false일때 해당 페이지로 할당한다. 앞에서 menu 변수값이 true이면 상위 category, false이면 하위 category로 두었으므로, menu 변수값이 false인 페이지는 하위 category 페이지이다.
204 8 Jinwuk Admin
205 8 Jinwuk Admin
그러므로 for문을 통해 page에서의 상위 category의 제목을 표시하고 하위 category를 검색하여 제목과 url을 표시하도록 수정하면 된다.
206 8 Jinwuk Admin
207 9 Jinwuk Admin
h3. Post에서 계층적 Category에서의 Post가 표시되는 것
208 8 Jinwuk Admin
209 9 Jinwuk Admin
위에서는 sidebar에서 하위 category가 표시되는 반면에 하위 category를 클릭하면 해당 하위 category 페이지가 열리면서, 해당 category에 해당하는 post가 표시되는 것에 대하여 알아보자.
210 8 Jinwuk Admin
211 9 Jinwuk Admin
해당 되는 page 는 category.html (in _layouts 폴더)이다.
212 8 Jinwuk Admin
213 9 Jinwuk Admin
<pre><code class="html">
214 9 Jinwuk Admin
---
215 9 Jinwuk Admin
layout: page
216 9 Jinwuk Admin
---
217 1 Jinwuk Admin
218 9 Jinwuk Admin
{% unless page.content == '' %}
219 9 Jinwuk Admin
  {{ content }}
220 9 Jinwuk Admin
{% endunless %}
221 9 Jinwuk Admin
222 9 Jinwuk Admin
<ul class="posts-list">
223 9 Jinwuk Admin
  {% assign category = page.category | default: page.title %}
224 9 Jinwuk Admin
  {% for post in site.categories[category] %}
225 9 Jinwuk Admin
    <li>
226 9 Jinwuk Admin
      <h3>
227 9 Jinwuk Admin
        <a href="{{ site.baseurl }}{{ post.url }}">
228 9 Jinwuk Admin
          {{ post.title }}
229 9 Jinwuk Admin
          <small>{{ post.date | date_to_string }}</small>
230 9 Jinwuk Admin
        </a>
231 9 Jinwuk Admin
      </h3>
232 9 Jinwuk Admin
    </li>
233 9 Jinwuk Admin
  {% endfor %}
234 9 Jinwuk Admin
</ul>
235 9 Jinwuk Admin
</code></pre>
236 9 Jinwuk Admin
237 9 Jinwuk Admin
여기에서 보면 상위 category에 대한 post 만 표시되도록 되어 있다.
238 10 Jinwuk Admin
이것을 *submenu* 변수를 사용하여 상위 category이면 해당 되는 post가 모두 표시되도록 하고 하위 category 이면, 하위 category에 해당하는 postdml title이 표시되도록 하였다. 
239 10 Jinwuk Admin
240 10 Jinwuk Admin
원본 코드와 비교해 보면 구현 방법을 쉽게 알 수 있으리라 생각한다.
클립보드 이미지 추가 (최대 크기: 977.563 MB)