loading

카테고리별 다른 게시물 추천하기(이전글, 다음글)


Blog theme, 서버 관리, 웹 디자인

Published on December 16, 2022 by JunYoung

web designer blog github recommendation

9 min READ

카테고리별 게시글 넘어갈 수 있는 버튼 만들기

시험공부하면서 농땡이 피울때마다 홈페이지를 업데이트했다. 하루에 기능 하나씩 추가하는게 초반 목표였는데, 어느 정도는 달성되어서 거의 완성되는 중이다. Course work 끝나기 전까지 웹 커스터마이즈는 끝내고 이후에 논문리뷰나 공부할 내용들을 올리는 것이 목표였는데, 한 1/3 정도는 마무리한 것 같다.
그래서 이번에 하고자 했던 것은 바로 네이버 블로그나 이런저런 포스팅 사이트에 가면 볼 수 있는 “이전글, 다음글” 버튼이다. 본인의 경우 포스팅이 각 카테고리별로 구분되기 때문에, 카테고리가 같은 다른 게시물을 추천해주고자 하였다. 완성된 모습은 다음과 같다.

특정 게시글에 들어가면, 같은 카테고리의 글들 중 바로 직전에 작성한 글과 바로 직후에 작성한 글을 추천해준다. 만약 본인이 모바일로 보고 있다면 축약되어서 나올텐데, 이는 타이틀 길이가 길어질 경우 제목이 잘리는 경우가 생기기 때문에 윈도우의 width(너비)에 따라 나타날 수 있는 텍스트의 길이를 제한해주는 스크립트를 사용했다.
어떠한 방식으로 구현했는지 순서대로 하나씩 설명하도록 하겠다.


같은 카테고리의 글을 가져와서 리스트 형태로 받고, 이전글과 다음글의 인덱스를 리턴하는 html 코드

작성한 코드는 위와 같다. page의 카테고리들 중 하나를 cat에 assign하고, 해당 카테고리를 만족하는 글들을 site의 post에서 서칭한다. 그리고 해당 리스트를 기준으로 자신보다 하나 이전의 글에 대한 index를 prevIndex로, 하나 이후의 글에 대한 index를 nextIndex로 정의한다. 그리고 만약 처음 포스트라면(이전에 작성된 포스트가 없다면) next_post만 assign하고 가장 마지막 포스트라면(이후에 작성된 포스트가 없다면) prev_post만 assign해준다.

해당 내용들을 각 버튼에 url 및 제목과 함께 링크해주는 코드는 다음과 같다.

본인은 해당 코드를 post_categorize.html이라는 새로운 파일에다가 만들었다. 혹시라도 전체 소스코드가 궁금하다면 본인의 깃허브 코드를 참고해주면 좋을 것 같다. 코드를 복사하고 싶다면 해당 링크에서 복붙이 가능하다.


텍스트 액션 만들기

결과물을 보면 “ANOTHER POST IN CATEGORY”라는 글자가 빙글빙글 돌고 있는 것을 볼 수 있는데, 이는 이전에 다루었던 'HELLO' 꾸며서 넣기랑 거의 똑같다. 다만 액션의 형태를 다르게 주었을 뿐이다.
우선 ANOTHER, POST, IN, CATEGORY 각각 단어를 기준으로 액션이 동시에 먹게 하고 싶었기 때문에 다음과 같이 각 글자에 대한 span을 작성해준다.

<div class="anothercat" align="center">
    <body>
        <div class="waviy">
        <span style="--i:1">A</span>
        <span style="--i:1">n</span>
        <span style="--i:1">o</span>
        <span style="--i:1">t</span>
        <span style="--i:1">h</span>
        <span style="--i:1">e</span>
        <span style="--i:1">r</span>
        <span style="--i:2"> </span>
        <span style="--i:2"> </span>
        <span style="--i:2"> </span>
        <span style="--i:3">p</span>
        <span style="--i:3">o</span>
        <span style="--i:3">s</span>
        <span style="--i:3">t</span>
        <span style="--i:4"> </span>
        <span style="--i:4"> </span>
        <span style="--i:4"> </span>
        <span style="--i:5">i</span>
        <span style="--i:5">n</span>
        <span style="--i:6"> </span>
        <span style="--i:6"> </span>
        <span style="--i:6"> </span>
        <span style="--i:7">c</span>
        <span style="--i:7">a</span>
        <span style="--i:7">t</span>
        <span style="--i:7">e</span>
        <span style="--i:7">g</span>
        <span style="--i:7">o</span>
        <span style="--i:7">r</span>
        <span style="--i:7">y</span>
        </div>
    </body>
</div>

하드코딩처럼 작성되어있기는 한데, 중간에 space를 많이 넣은 이유는 빈칸이 잘 보이지 않아서 그랬다. 아무튼 이렇게 하고 나서 css를 통해 다음과 같이 스타일을 제어해준다.

.anothercat{
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
    }
    .waviy {
        margin-top: 10px;
        margin-bottom: 50px;
        position: relative;
    }
    .waviy span {
        position: relative;
        display: inline-block;
        font-size: 4.2vmin;
        color: #242424;
        text-transform: uppercase;
        animation: flip 2s infinite;
        animation-delay: calc(.2s * var(--i))
    }
    @keyframes flip {
        0%,80% {
            transform: rotateY(360deg) 
        }
    }
}

이건 논외인데 굳이 anothercat으로 class name을 만든 이유는 고양이가 귀여워서다. 너무 TMI였나 암튼..
위와 같이 작성해주었는데 font-size를 보면 vmin을 기준으로 크기가 맞춰지게끔 하였다. 이는 모바일 환경에서도 텍스트가 적당한 크기를 유지할 수 있도록 하기 위함이었다.
흔히 데스크탑이나 노트북으로 접속하면 가로 길이가 더 길고(window의 width가 height보다 큼), 모바일기기나 태블릿으로 접속하면 세로 길이가 더 긴 경우가 생긴다(window의 height가 width보다 큼). 만약 vmax를 기준으로 한다면 모바일 기기에서는 글자 크기가 너무 작고, 반대로 컴퓨터 모니터에서는 글자 크기가 너무 커보이는 문제가 발생한다. 따라서 이를 잘 통합할 수 있는 vmin을 사용하였다. 참고로 본인은 theme이 다크모드랑 라이트모드 두 개로 구성되기 때문에 .waviy span 부분의 color 요소를 테마마다 다르게 적용해주었다.


버튼 꾸미기

이제 텍스트를 꾸몄기 때문에 남은 것은 버튼을 꾸미는 작업이다. 앞서 보여준 결과물을 보게 되면, 마우스를 버튼 위에 올리면 색이 쭉 채워짐과 동시에 조금 커지는 형태를 보인다. 이러한 이펙트는 css를 통해 구현하였다.

.adjacent{
    vertical-align: center;
    height: 120px;
    font-size: 3.5vmin;
    #prev, #next{
        background: white;
        transition: all 0.60s ease;
        color: #242424;
        z-index: 1;
        font: 'tahoma';
        margin-top: 15px;
        margin-bottom: 15px;
        max-width: 70vw;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;

        &:after {
            position: absolute;
            content: "";
            width: 0;
            height: 100%;
            top: 0;
            right: 0;
            z-index: -1;
            background: #242424;
            transition: all 0.3s ease;
        }
        &:hover {
            transform: scale(1.03);
            color: white;
        }
        &:hover:after {
            left: 0;
            width: 100%;
        }
        &:active {
            top: 2px;
        }
    }
}

hover 옵션이 마우스를 가져다대면 어떤 식으로 스타일 변형을 줄 지에 대한 부분이다. hover를 하게 되면 scale를 확대하고, 텍스트 색을 white로 바꾸며 배경색을 #242424로 바꾸는 코드다. 이것도 테마마다 서로 다르게 적용해주었다.


타이틀 길이 조절해주기

이제 필수적인 요소 넣기는 모두 끝났고, 마무리해야겠다 싶은 찰나에 큰 문제를 하나 발견한다. 이는 바로 모바일 기기에서의 title 길이 문제였다. 다음과 같은 그림을 보면,

서로 다른 기기에서 홈페이지에 접속을 하게 되면 text 길이가 잘려서 나타나야한다는 것이다. 바로 이걸 구현하기 위해 post_categorize.html에 다음과 같은 코드를 추가해주었다.

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
    const title1 = $("#prev_title").text();
    const title2 = $('#next_title').text();
    var speed = 100;
    var dots = '⋯⋯';

    var titlelength = function () {
        setInterval(function () {
            var ww = $(window).width();
            if(ww < 400){
                offset = 10;
                if(title1.length > offset){
                    part = title1.substr(0, offset);
                    $("#prev_title").text(part + dots);
                }

                if(title2.length > offset){
                    part = title2.substr(0, offset);
                    $("#next_title").text(part + dots)
                }
            }
            else if(ww < 600){
                offset = 20;
                if(title1.length > offset){
                    part = title1.substr(0, offset);
                    $("#prev_title").text(part + dots);
                }

                if(title2.length > offset){
                    part = title2.substr(0, offset);
                    $("#next_title").text(part + dots)
                }
            }
            else{
                $("#prev_title").text(title1);
                $("#next_title").text(title2);
            }
        }, speed);
    };

    $(document).ready(function () {
        titlelength();
    });
</script>

JQuery로 작성되었다. 결국 하고자 했던 것은 특정 inverval을 기준으로 window의 가변적인 길이에 따라 반응하여 ww (윈도우의 가로 길이)를 기준으로 특정 값보다 작아지면 text의 offset을 조절해주는 것이었다. 이렇게 수고스런 작업을 하는 이유는 첫번째로 <a> 요소는 text-align 요소를 left로 설정할 수 없었으며, 이미 button에 적용한 hover 효과를 그대로 유지한 채로 적용할 수 있는 방법을 찾았기 때문에 흔히 사용되는 css 코드의 overflow, text-overflow는 사용할 수 없었기 때문이다.
그리고 두번째는 이를 통해 텍스트의 일부를 가릴 수 있더라도 원하는 부분을 노출시키기 힘들었기 때문이다. 구구절절 설명하기는 했지만 이런 이유 때문에 위와 같은 코드를 사용하였고, 본인은 html 등 언어에 익숙치 않아서 택한 방법이기 때문에 다른 좋은 방법들을 사용해봐도 좋을 것 같다.

이렇게 모든 작업을 마무리하면 각 테마에 맞게 다음 추천글, 이전 추천글이 각 카테고리별로 잘 나오는 것을 볼 수 있었다. 바로 아래에 보이는 모습과 같다.

A n o t h e r p o s t i n c a t e g o r y