Post

서브 카테고리 정렬 커스텀

서브 카테고리 정렬 커스텀

img


YML 파일로 정의

지난번에 큰 카테고리만 내가 원하는대로 정렬하도록 구현했는데, 이번엔 서브카테고리도 보기 좋게 정렬하려고 한다.




1️⃣ _data/categories.yml 파일 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# _data/categories.yml
Project:

Study:
  - C/C++
  - 자료구조
  - 알고리즘
  - 디자인 패턴
  - 게임 수학
  - 코드 조각
  - etc

Personal:
  - Gallery
  - Taste
  
Blogging:
  - Custom
  - Tutorial

서브 카테고리도 원하는 순서대로 작성해준다.




2️⃣ 서브 카테고리 리스트 출력 코드 수정

_layouts/categories.html 코드 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
---
layout: page
# All the Categories of posts
---

{% include lang.html %}

{% assign HEAD_PREFIX = 'h_' %}
{% assign LIST_PREFIX = 'l_' %}
{% assign group_index = 0 %}

{%- comment -%}
----------------------------------------
1️⃣ YAML에 정의된 카테고리를 먼저 출력
   - _data/categories.yml 에 명시한 순서대로 상위/하위 카테고리 출력
----------------------------------------
{%- endcomment -%}

{% assign defined_categories = site.data.categories %}

{% for category_hash in defined_categories %}
  {% assign category_name = category_hash[0] | string %}  <!-- 문자열로 강제 변환 -->
  {% assign sub_categories = category_hash[1] %}

  {% assign posts_of_category = site.categories[category_name] %}
  {% if posts_of_category %}
    <div class="card categories">
      <!-- 상위 카테고리 헤더 -->
      <div
        id="{{ HEAD_PREFIX }}{{ group_index }}"
        class="card-header d-flex justify-content-between hide-border-bottom"
      >
        <span class="ms-2">
          <i class="far fa-folder{% if sub_categories.size > 0 %}-open{% endif %} fa-fw"></i>

          {% capture _category_url %}/categories/{{ category_name | slugify | url_encode }}/{% endcapture %}
          <a href="{{ _category_url | relative_url }}" class="mx-2">{{ category_name }}</a>

          <!-- 글 수 표시 -->
          <span class="text-muted small font-weight-light">
            {{ posts_of_category.size }}
            {% if posts_of_category.size > 1 %}
              {{ site.data.locales[lang].categories.post_measure.plural | default: 'posts' }}
            {% else %}
              {{ site.data.locales[lang].categories.post_measure.singular | default: 'post' }}
            {% endif %}
          </span>
        </span>

        {% if sub_categories and sub_categories.size > 0 %}
          <!-- 하위 카테고리 토글 -->
          <a
            href="#{{ LIST_PREFIX }}{{ group_index }}"
            class="category-trigger hide-border-bottom"
            data-bs-toggle="collapse"
            aria-expanded="true"
            aria-controls="{{ LIST_PREFIX }}{{ group_index }}"
            aria-label="{{ HEAD_PREFIX }}{{ group_index }}-trigger"
          >
            <i class="fas fa-fw fa-angle-down"></i>
          </a>
        {% endif %}
      </div>

      {% if sub_categories and sub_categories.size > 0 %}
        <!-- 하위 카테고리 리스트 -->
        <div
          id="{{ LIST_PREFIX }}{{ group_index }}"
          class="collapse show"
          aria-labelledby="{{ HEAD_PREFIX }}{{ group_index }}"
        >
          <ul class="list-group">
            {% for sub_category in sub_categories %}
              {% assign posts_size = site.categories[sub_category] | size %}
              <li class="list-group-item">
                <i class="far fa-folder fa-fw"></i>
                {% capture _sub_ctg_url %}/categories/{{ sub_category | slugify | url_encode }}/{% endcapture %}
                <a href="{{ _sub_ctg_url | relative_url }}" class="mx-2">{{ sub_category }}</a>

                <span class="text-muted small font-weight-light">
                  {{ posts_size }}
                  {% if posts_size > 1 %}
                    {{ site.data.locales[lang].categories.post_measure.plural | default: 'posts' }}
                  {% else %}
                    {{ site.data.locales[lang].categories.post_measure.singular | default: 'post' }}
                  {% endif %}
                </span>
              </li>
            {% endfor %}
          </ul>
        </div>
      {% endif %}
    </div>
    {% assign group_index = group_index | plus: 1 %}
  {% endif %}
{% endfor %}

{%- comment -%}
----------------------------------------
2️⃣ YAML에 없는 카테고리 자동 추가
   - 글에만 존재하는 상위 카테고리를 뒤에 붙임
   - 정의된 순서 + 자동 추가 구조 완성
   - where_exp 대신 for+unless+push 사용
----------------------------------------
{%- endcomment -%}

{% assign defined_keys = defined_categories | map: "first" | map: "to_s" %}  <!-- 문자열로 변환 -->
{% assign all_categories = site.categories | map: "first" | map: "to_s" %}
{% assign extra_categories = "" | split: "" %}

{% for category_name in all_categories %}
  {% unless defined_keys contains category_name %}
    {% assign extra_categories = extra_categories | push: category_name %}
  {% endunless %}
{% endfor %}

{% assign extra_categories = extra_categories | sort %}

{% for category_name in extra_categories %}
  {% assign posts_of_category = site.categories[category_name] %}
  <div class="card categories">
    <div
      id="{{ HEAD_PREFIX }}{{ group_index }}"
      class="card-header d-flex justify-content-between hide-border-bottom"
    >
      <span class="ms-2">
        <i class="far fa-folder fa-fw"></i>
        {% capture _category_url %}/categories/{{ category_name | slugify | url_encode }}/{% endcapture %}
        <a href="{{ _category_url | relative_url }}" class="mx-2">{{ category_name }}</a>

        <span class="text-muted small font-weight-light">
          {{ posts_of_category.size }}
          {% if posts_of_category.size > 1 %}
            {{ site.data.locales[lang].categories.post_measure.plural | default: 'posts' }}
          {% else %}
            {{ site.data.locales[lang].categories.post_measure.singular | default: 'post' }}
          {% endif %}
        </span>
      </span>
    </div>
  </div>
  {% assign group_index = group_index | plus: 1 %}
{% endfor %}

This post is licensed under CC BY 4.0 by the author.