[BlogDev] 사이드바 카테고리 만들기

작성:    

업데이트:

카테고리:

태그: , , ,

도입

본 게시물은 공부하는 식빵맘님의 게시물을 통해 배우고 따라하는 과정을 기록한 포스트입니다. 게시물에는 훌륭한 선배 개발자분께서 좋은 글들을 많이 써두셨으니 참고하시기 바랍니다. 그리고 저 역시 실력을 키워 나중에 후배 개발자들에게 도움을 줄 수 있는 사람이 되고 싶다는 귀감을 받았습니다. 이 글을 통해 사이드바를 카테고리별로 정리하는 숙원사업을 가능케 해주신 식빵맘님께 다시 한 번 감사의 마음을 전합니다.


참고문서

  1. 공부하는 식빵맘 - minimal-mistaks 블로그 카테고리 만들기
  2. 공부하는 식빵맘 - minimal-mistakes 테마의 디렉토리 구조

본 게시물은 minimal-mistakes의 디렉토리 구조에 대한 깊은 이해가 요구되는 과정이므로 위의 2. minimal-mistakes 테마의 디렉토리 구조 포스트를 참고하면 좋을 것이다.


Mission

  1. 같은 카테고리의 글들을 모아둔 페이지
  2. 이 페이지들을 모아둔 사이드바


포스팅시 카테고리 등록

각각의 포스트를 작성할 때 머릿말에 카테고리를 등록해야 한다. 카테고리는 다음과 같이 등록하면 된다.

categories:
  - Python

나는 처음 Github Blog를 운영할 때부터 이 카테고리 코드를 작성해왔는데, 예를 들면 Python과 관련된 포스트를 게시하게 되면, Python 이라는 이름의 카테고리를 적어 분류하게 해두었다. 카테고리 페이지는 minimal-mistakes 테마에서 기본적으로 제공하는 페이지여서 커스터마이징 전에 유용하게 사용하였다.

image

글을 올릴 때 해당 포스트의 카테고리가 포스트 상단에 표시되도록 하였다. 아직 레이아웃이나 텍스트 표시 설정이 조금 남아있어 아쉬운 모습이긴 하지만 말이다.


같은 카테고리만 모아두는 페이지 작성

우선 카테고리별로 해당 카테고리의 게시물들만 표시하는 페이지를 만든다. minimal-mistakes의 📁_pages 폴더에 📁categories 폴더를 만들고, 이 안에 각각에 카테고리에 해당하는 페이지 md 파일들을 만드는 것이다. 파일명은 📃category-python.md, 📃category-TIL.md 등으로 만든다.

코드는 다음과 같다.

---
title: "Python"
layout: archive
permalink: categories/python
author_profile: true
sidebar_main: true
---


{% assign posts = site.categories.Python %}
{% for post in posts %} {% include archive-single.html type=page.entries_layout %} {% endfor %}

주의📣 이후에 📃archive-single2.html 페이지를 새로 만들어 커스터마이징하므로 {% include archive-single2.html type=page.entries_layout %} 로 적는 것을 권장한다.

나는 Python 같은 경우에는 Capitalize해서 앞에만 대문자, TIL 같은 경우는 Upper해서 모두 대문자 등 카테고리마다 이를 다르게 설정하였다. 일부러 그런 건 아니다. 이 부분에 유의해서 {% assign posts = site.categories.Python %} 부분을 작성해야 한다.

머릿말에 설정된 각각의 코드들에 대해 설명한다.


title: “Python”

페이지의 이름은 “Python”으로 나올 것이다. 수정하고 싶으면 나중에 수정하면 된다.


layout: archive


페이지의 layout은 archive 방식이다. archive 방식은 minimal-mistakes에서 전체 포스트의 목록을 보여주는 형식의 페이지 레이아웃 방식이다. 같은 카테고리의 글들을 나열하므로 archive 방식이 유리할 것이다.


permalink: categories/python

페이지의 링크는 “categories/python”이다. permalink는 baseurl에 붙는 sub주소이다. 때문에 이 Python 카테고리 페이지의 전체 url은 https://Orchemi.github.io/categories/python이 될 것이다.


author_profile: true

해당 페이지에서 내 author_profile 이 보이게 할 것인지에 대한 여부를 결정한다. 나는 모든 페이지에서 이를 true로 설정하여 모든 페이지에서 보이게 하였다.


sidebar_main: true

이는 새로 만든 변수값인데 이후에서 더 설명하게 된다.


모든 파일을 다 만든 모습이다. 더 추가될 것이다.

image


새 코드파일 만들기

기존의 archive의 구성과 달리 제목, 날짜, 카테고리, 태그가 한 줄로 붙어있는 상태로 나열하기 위한 코드이다.


archive-single2.html

📁_includes 폴더 내에 📃archive-single2.html을 아래의 코드로 새로 만들어주면 된다. 다시 말하지만 출처는 공부하는 식빵맘님 블로그


{% if post.header.teaser %}
  {% capture teaser %}{{ post.header.teaser }}{% endcapture %}
{% else %}
  {% assign teaser = site.teaser %}
{% endif %}

{% if post.id %}
  {% assign title = post.title | markdownify | remove: "<p>" | remove: "</p>" %}
{% else %}
  {% assign title = post.title %}
{% endif %}

<div class="{{ include.type | default: "list" }}__item">
    <article class="archive-item">
        <div>
            <span>
              <a href="{{ post.url }}">{{post.title}}</a>
            </span>
            <small>
              <i class="fas fa-fw fa-calendar-alt" aria-hidden="true"> </i>{{ post.date | date: " %Y.%m.%d" }}
              {% if site.category_archive.type and post.categories[0] and site.tag_archive.type and post.tags[0] %}
                {%- include post__taxonomy.html -%}
              {% endif %}
            </small>
        </div>
      </article>
</div>


post__taxonomy.html

마찬가지로 📁_includes 폴더 내에 📃post__taxonomy.html을 아래의 코드로 새로 만들어주면 된다.


<!--Archive page 용-: (post -> page)-->
<!--page__taxonomy.html에서 가져 옴-->

{%- if site.category_archive.type and post.categories[0] -%}
    {%- case site.category_archive.type -%}
        {%- when "liquid" -%}
        {%- assign path_type = "#" -%}
        {%- when "jekyll-archives" -%}
        {%- assign path_type = nil -%}
    {%- endcase -%}

    {% case site.tag_archive.type %}
        {% when "liquid" %}
            {% assign path_type = "#" %}
        {% when "jekyll-archives" %}
            {% assign path_type = nil %}
    {% endcase %}

    {%- if site.category_archive.path and site.tag_archive.path -%}
        {%- capture post_categories -%}{%- for category in post.categories -%}{{ category | downcase }}|{{ category }}{%- unless forloop.last -%},{%- endunless -%}{%- endfor -%}{%- endcapture -%}
        {%- assign category_hashes = post_categories | split: ',' | sort -%}
        {% capture post_tags %}{% for tag in post.tags %}{{ tag | downcase }}|{{ tag }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
        {% assign tag_hashes = post_tags | split: ',' | sort %}
        <span class="page__taxonomy">
            <span itemprop="keywords">
                {%- for hash in category_hashes -%}
                    {%- assign keyValue = hash | split: '|' -%}
                    {%- capture category_word -%}{{ keyValue[1] | strip_newlines }}{%- endcapture -%}
                    <a href="{{ category_word | slugify | prepend: path_type | prepend: site.category_archive.path | relative_url }}" class="page__taxonomy-item-category" rel="tag">{{ category_word }}</a>{%- unless forloop.last -%}<span class="sep"> </span>{%- endunless -%}
                {%- endfor -%}
                {% for hash in tag_hashes %}
                    {% assign keyValue = hash | split: '|' %}
                    {% capture tag_word %}{{ keyValue[1] | strip_newlines }}{% endcapture %}
                    <a href="{{ tag_word | slugify | prepend: path_type | prepend: site.tag_archive.path | relative_url }}" class="page__taxonomy-item-tag" rel="tag">{{ tag_word }}</a>{% unless forloop.last %}<span class="sep"> </span>{% endunless %}
                {% endfor %}
            </span>
        </span>
    {%- endif -%}
{%- endif -%}


category.md 페이지

처음에 만든 category.md 파일과 다른 것은 include archive-single2.html 부분이다. 이 부분에 유의한다.


{% assign posts = site.categories.Python %}
{% for post in posts %} {% include archive-single2.html type=page.entries_layout %} {% endfor %}


페이지들을 모아 사이드바로 반영

📁_includes 폴더 내에 📃nav_list_main 파일을 생성한다.

이 파일은 md파일도, html파일도 아니다. nav_list_main은 파일명(ex. .html) 없이 그냥 제목만 적고 만들어야 한다. 파일명은 꼭 nav_list_main일 필요는 없지만 원활하게 따라오기 위해서는 nav_list_main으로 하는 걸 권한다.

📃sidebar.html에 직접 코드를 작성해도 되지만, 그렇게 되면 📃sidebar.html의 코드가 너무 길어지기 때문에 📁_includes 폴더 내에 📃nav_list_main 파일을 따로 생성하여 이를 📃sidebar.html에 포함시키는 방식으로 작성한다.

<!--전체 글 수를 세기 위한 연산. sum 변수에 전체 글 수 저장-->

{% assign sum = site.posts | size %}

<nav class="nav__list">
  <input id="ac-toc" name="accordion-toc" type="checkbox" />
  <label for="ac-toc">{{ site.data.ui-text[site.locale].menu_label }}</label>
  <ul class="nav__items" id="category_tag_menu">
      <!--전체 글 수-->
      <li>
            <div>📃 전체 게시글 수 {{sum}} 개</div>
      </li>
      <li>
        <!-- 대분류 with span 태그-->
        <span class="nav__sub-title"> <!-- FrontEnd 문자 표시 -->
            FrontEnd
        </span>

            <!-- 소분류 with ul 태그-->
            <ul> <!--HTML 카테고리 글들을 모아둔 페이지인 /categories/HTML 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "HTML" %}
                        <li><a href="/categories/HTML" class="">HTML ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>


            <ul> <!--CSS 카테고리 글들을 모아둔 페이지인 /categories/CSS 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "CSS" %}
                        <li><a href="/categories/CSS" class="">CSS ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>



        <!-- 대분류 with span 태그-->
        <span class="nav__sub-title"> <!-- BackEnd 문자 표시 -->
            BackEnd
        </span>

            <!-- 소분류 with ul 태그-->
            <ul><!--Python 카테고리 글들을 모아둔 페이지인 /categories/Python 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Python" %}
                        <li><a href="/categories/python" class="">Python ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>



        <!-- 대분류 with span 태그-->
        <span class="nav__sub-title"> <!-- CodingTest 문자 표시 -->
            CodingTest
        </span>

            <!-- 소분류 with ul 태그-->
            <ul><!--Coding Test Study 카테고리 글들을 모아둔 페이지인 /categories/coding-test-study 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Coding Test Study" %}
                        <li><a href="/categories/coding-test-study" class="">Coding Test Study ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>



        <!-- 대분류 with span 태그-->
        <span class="nav__sub-title">  <!-- etc 문자 표시 -->
            etc
        </span>

             <!-- 소분류 with ul 태그-->
            <ul> <!--Blog 카테고리 글들을 모아둔 페이지인 /categories/Blog 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Blog" %}
                        <li><a href="/categories/Blog" class="">BlogDev ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>


            <ul> <!--Git 카테고리 글들을 모아둔 페이지인 /categories/Git 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Git" %}
                        <li><a href="/categories/git" class="">Git ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>


        <!-- 대분류 with span 태그-->
        <span class="nav__sub-title">  <!-- Private 문자 표시 -->
            Private
        </span>

             <!-- 소분류 with ul 태그-->
             <ul> <!--TIL 카테고리 글들을 모아둔 페이지인 /categories/til 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "TIL" %}
                        <li><a href="/categories/til" class=""> TIL ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>


             <!-- 소분류 with ul 태그-->
            <ul> <!--Volunteer 카테고리 글들을 모아둔 페이지인 /categories/volunteer 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Volunteer" %}
                        <li><a href="/categories/volunteer" class=""> Volunteer ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>


            <ul> <!--research 카테고리 글들을 모아둔 페이지인 /categories/research 주소의 글로 링크 연결-->
                {% for category in site.categories %}
                    {% if category[0] == "Research" %}
                        <li><a href="/categories/research" class="">Research ({{category[1].size}})</a></li>
                    {% endif %}
                {% endfor %}
            </ul>
      </li>
  </ul>
</nav>

본 코드는 공부하는 식빵맘님의 코드와 상당부분 다르다. 가시성을 확보하기 위해 행간 거리를 두었고, 주석이 긴 부분은 과감히 줄였다. 전체 글 수를 표시하는 폰트를 다르게 하기 위해 식빵맘님은 <span> 태그 내에 style을 지정해 폰트를 따로 지정하였으나, 나는 그럴 필요를 느끼지 못해 <div> 태그로 정리하였다. 그러니 필요하신분은 위의 링크의 해당 부분을 더 참고하시길 바란다.

각각의 의미에 대해 살펴보자.


ul class = "nav__items

  • 이 태그 안에 카테고리들을 모아둔 페이지들 링크를 나열한다. (위의 페이지마다 설정한 permalink)
  • CSS에서 “nav_items” 영역을 꾸미도록 할 수 있다.


<li>

  • 전체 글의 수를 표시하는 <li> 영역과 카테고리별로 페이지를 표시하는 <li> 영역으로 나뉜다.
  • 추후에는 사이트를 방문하는 방문자를 집계해서 표시하는 기능을 해당 사이드바에 넣어보려 한다.


<span class="nav__sub-title">

  • 카테고리들을 대분류하는 문자들을 나타낸 클래스들이다.
  • CSS에서 “nav_sub-title” 영역에 코드를 수정하여 폰트, 색상 등을 커스터마이징할 수 있다.


<ul>

  • <ul> 태그 하나하나마다 <a href="#"> 를 이용해 위에서 만들었떤 해당 카테고리의 글들을 모은 페이지로 가는 링크를 각각 설정한다.

  • 위의 href ="#"의 “#” 내에는 해당 카테고리 페이지의 permalink를 쓰면 된다.

  • 📁_pages📁categories 내의 각각의 📃category-~~~.md 파일의 permalink를 어떻게 써두었는지 잘 참고해서 📃nav_list_main을 작성하도록 한다.


{{category[1].size}}

  • 해당 카테고리를 가진 포스트의 개수를 표시한다.

     <ul>
          {% for category in site.categories %}
                    {% if category[0] == "CSS" %}
                        <li><a href="/categories/CSS" class="">CSS ({{category[1].size}})</a></li>
                    {% endif %}
            {% endfor %}
      </ul>


📃sidebar.html 에 📃page.sidebar_main 삽입

어렵게 만든 📃nav_list_main을 📃sidebar.html에 추가할 차례이다.


{% if page.sidebar_main %}
    {% include nav_list_main %}
{% endif %}

이 코드의 의미는 page.sidebar_main 이 true일 때 📃nav_list_main 을 가져오라는 말이다. 때문에 후술하겠지만, 📃_config.yml 파일에서 이를 true로 하는 코드를 추가하게 된다.

아무튼 이 코드를 추가한 📃sidebar.html의 코드는 다음과 같다.


{% if page.author_profile or layout.author_profile or page.sidebar %}
  <div class="sidebar sticky">
  {% if page.author_profile or layout.author_profile %}{% include author-profile.html %}{% endif %}
  {% if page.sidebar %}
    {% for s in page.sidebar %}
      {% if s.image %}
        <img src="{{ s.image | relative_url }}"
             alt="{% if s.image_alt %}{{ s.image_alt }}{% endif %}">
      {% endif %}
      {% if s.title %}<h3>{{ s.title }}</h3>{% endif %}
      {% if s.text %}{{ s.text | markdownify }}{% endif %}
      {% if s.nav %}{% include nav_list nav=s.nav %}{% endif %}
    {% endfor %}
    {% if page.sidebar.nav %}
      {% include nav_list nav=page.sidebar.nav %}
    {% endif %}
  {% endif %}

  {% if page.sidebar_main %}
    {% include nav_list_main %}
  {% endif %}

  </div>
{% endif %}


📃_config.yml

📃_config.yml 파일에 sidebar_main: true를 추가하여 블로그 전체 페이지에서 위에 만든 사이드바가 활성화되게 하면 된다.

# Defaults
defaults:
  # _posts
  - scope:
      path: ""
      type: posts
    values:
      layout: single
      author_profile: true
      read_time: true
      comments: true
      share: true
      related: true
      sidebar_main: true


📃index.html

layout: home
sidebar_main: true
author_profile: true

메인 페이지에 사이드바가 반영되지 않는다면 메인 페이지를 담당하는 📃index.html 의 머릿말에 sidebar_main: true 코드를 추가한다. 📃index.html는 블로그 개인 폴더의 가장 상위 디렉토리에 있다.

댓글남기기