Multiple and Hierarchical Category » 이력 » 버전 9

Jinwuk Admin, 2018/07/25 14:53

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 9 Jinwuk Admin
이것을 *submenu* 변수를 사용하여 상위 category이면 해당 되는 post가 모두 표시되도록 하고 하위 category 이면, 
클립보드 이미지 추가 (최대 크기: 977.563 MB)