
[티스토리 블로그 스킨 제작 가이드 강의 10] 최근글과 인기글
안녕하세요.
이번 시간에는 최근댓글 위에 있는 최근글과 인기글 두 개를 다뤄보도록 하겠습니다.
최근글
을 클릭하면 최근 글 목록이 나오고 인기글
을 클릭하면 인기있는 글 목록이 나오는데요. 아쉽게도 이렇게 클릭에 따라 글이 다르게 나오는 기능은 Javascript로 구현을 해야하기 때문에 우리는 최근글과 인기글이 따로 나타나도록 하겠습니다.
최근글과 인기글
우선 스킨가이드를 보시면 최근글과 인기글 항목이 있는데, 둘다 같이 보면 그룹치환자를 빼고는 모두 동일한 것을 알 수 있는데요.
참고로 rctps에서 ps는 post가 아닐까 생각합니다.

둘이 똑같이 동작하기 때문에 최근글 예시만 먼저 복사해서 사이드바에 넣어보겠습니다. 그리고 이 예시에는 author와 date, 그리고 simple_date가 없기 때문에 같이 추가해서 어떻게 나오는지 볼게요.
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recentPost">
<h3>최근에 올라온 글</h3>
<ul>
<s_rctps_rep>
<li>
<a href="[##_rctps_rep_link_##]">[##_rctps_rep_title_##]</a>
<span class="cnt">[##_rctps_rep_rp_cnt_##]</span>
<s_rctps_rep_thumbnail>
<img src="[##_rctps_rep_thumbnail_##]" />
</s_rctps_rep_thumbnail>
<a href="[##_rctps_rep_category_link_##]"
>[##_rctps_rep_category_##]</a
>
<div class="author">[##_rctps_rep_author_##]</div>
<div class="date">[##_rctps_rep_date_##]</div>
<div class="simple_date">[##_rctps_rep_simple_date_##]</div>
</li>
</s_rctps_rep>
</ul>
</div>
</s_sidebar_element>
적용하고 새로고침을 해서 또 안 나타난다면 사이드바 설정에서 조정해주시면 되겠습니다.

그리고 글들이 나와야하니까 기본적인 글이 몇 개 있어야겠죠? 글 관리에 들어가서 예시 글들을 3개 정도 써보겠습니다

이번에는 글을 발행할 때 대표 이미지를 넣어야 합니다. 썸네일도 같이 보여줘야하기 때문인데요.

이렇게 글을 쓰셨다면 블로그로 가서 어떻게 나타나는지 보겠습니다.

치환자들
지금은 이미지가 너무 커서 잘 안보이겠지만, 개발자 도구를 통해서 보시면 치환자들이 어떻게 치환되었는지 알 수 있습니다. 해당 글의 링크, 제목은 자주 봐서 익숙하죠?
좀 신기한것은 댓글 수 인데요. 이렇게 태그 하나가 만들어집니다.
이 글에는 댓글이 없기 때문에 빈 태그만 나왔지만 댓글이 있는 경우 이 사이에 숫자가 들어갑니다.
그리고 그 아래에 thumbnail의 경우 rep_thumbnail이라는 그룹 치환자를 같이 사용하고 있는데요. 그룹치환자의 기능은 대표이미지가 있을 때 그 안에 있는 태그들이 나타나게 하는겁니다.
대표이미지가 없는 경우 이 태그는 나타나지 않습니다.
category도 제목과 마찬가지로 링크 치환자와 이름용 치환자가 있습니다.
그리고 그 아래에 author
와 date
, simple_date
가 어떻게 나오는지 보입니다.
여기서 인기글을 구현하려면 그룹 치환자만 바꿔주시면 됩니다. 간단하죠?
이제 우리는 Book Club 스킨과 비슷하게 최근글과 인기글을 만들어보겠습니다.
Book Club 스킨처럼 적용
우선 Book Club 스킨을 보시면 제목과 날짜, 썸네일, 그리고 클릭했을 때 이동할 수 있는 링크가 사용된 것 같습니다.
이와 비슷하게 구현해볼게요. HTML 편집 페이지로 돌아와서 이전 예시는 다 지워주시구요. recent-post
라는 class를 가진 <div>
태그를 추가하고 제목은 최근글이라고 하겠습니다.
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recent-post">
<h3>최근글</h3>
</div>
</s_sidebar_element>
그리고 그 아래에 그룹치환자와 a태그를 추가해서 여러 개의 글 링크가 나올 수 있게 하겠습니다.
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recent-posts">
<h3>최근글</h3>
<s_rctps_rep>
<a class="item" href="[##_rctps_rep_link_##]">
</a>
</s_rctps_rep>
</div>
</s_sidebar_element>
그런 다음 왼쪽엔 글, 오른쪽엔 이미지가 나올 수 있게 글자용 태그 하나와 img 태그를 추가할게요. 이미지 태그에는 대표이미지가 있을 때 나타날 수 있도록 그룹치환자도 넣겠습니다.
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recent-posts">
<h3>최근글</h3>
<s_rctps_rep>
<a class="item" href="[##_rctps_rep_link_##]">
<div class="text"></div>
<s_rctps_rep_thumbnail>
<img />
</s_rctps_rep_thumbnail>
</a>
</s_rctps_rep>
</div>
</s_sidebar_element>
그리고 글자 있는 곳에는 제목과 날짜가 나오게 하고, img 태그에는 썸네일 주소를 넣습니다.
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recent-posts">
<h3>최근글</h3>
<s_rctps_rep>
<a class="item" href="[##_rctps_rep_link_##]">
<div class="text">
<h4>[##_rctps_rep_title_##]</h4>
<p>[##_rctps_rep_simple_date_##]</p>
</div>
<s_rctps_rep_thumbnail>
<img src="[##_rctps_rep_thumbnail_##]" />
</s_rctps_rep_thumbnail>
</a>
</s_rctps_rep>
</div>
</s_sidebar_element>
여기까지해서 적용하고 미리보기를 하면 이렇게 최근글들이 나오는데요. 이제 스타일을 꾸며보겠습니다.
스타일 꾸미기
우선 이전 recent-reply 스타일을 그대로 가져와서 class 명만 바꿔주겠습니다.
.recent-posts {
margin-bottom: 30px;
font-size: 14px;
color: gray;
line-height:1.6;
}
.recent-posts h3 {
font-size: 14px;
margin-bottom: 5px;
}
그리고 <h3>
태그 margin-bottom
만 10px
로 바꿔줄게요. 그 다음에 .item
class에 display:flex
를 넣어서 텍스트와 이미지가 가로로 배치되게 하겠습니다. 그리고 높이는 60px
정도로 하고, margin-bottom으로 글마다 약간 간격이 있게 할게요
.recent-posts .item {
display: flex;
height: 60px;
margin-bottom: 15px;
}
이미지의 높이는 item과 똑같이 하게하고, 가로세로 비율은 1대1로 만들겠습니다. 그런 다음 object-fit
을 cover
로 넣어서 삐져나가는 이미지는 잘리게 할게요.
.recent-posts .item img {
height: 100%;
aspect-ratio: 1;
object-fit: cover;
}
text의 경우 오른쪽에 margin을 넣어서 글자와 이미지가 붙지 않게 하겠습니다.
.recent-posts .item .text {
margin-right: 25px;
}
마지막으로 제목과 날짜의 글자크기와 굵기, 그리고 간격을 조정하겠습니다.
.recent-posts .item h4 {
font-size: 13px;
font-weight: normal;
margin-top: 3px;
margin-bottom: 0;
}
.recent-posts .item p {
font-size: 12px;
font-weight: normal;
margin-top: 0;
margin-bottom: 0;
}
적용해서 결과를 보면 이렇게 최근글이 완성이 되었습니다. 이미지가 없는 경우는 좀 허전하네요.
이번에는 인기글도 만들어보겠습니다. HTML 편집페이지로 돌아와서 최근글 코드를 복사해서 아래에 붙여넣습니다. 그리고 최근을 인기로 바꾸고 그룹치환자를 바꿔줄게요. recent-posts라는 class는 그대로 사용하겠습니다. 어차피 똑같은 스타일을 적용할거니까요
<s_sidebar_element>
<!-- 인기글 -->
<div class="recent-posts">
<h3>인기글</h3>
<s_rctps_popular_rep>
<!-- ... -->
</s_rctps_popular_rep>
</div>
</s_sidebar_element>
이제 적용하고 새로고침을 해보면 이렇게 인기글과 최근글이 구현되었습니다.
인기글과 최근글이 나오는 개수도 마찬가지로 사이드바 설정에서 바꿀 수 있습니다. 아쉽게도 하나로 통일 되어 있어서 별개로 숫자를 정할 수가 없다는 단점이 있습니다.
네 다음 시간에는 공지사항을 구현해보도록 하겠습니다.
감사합니다.
전체코드
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<s_t3>
<div class="container">
<header>
<div class="top">
<a class="title" href="[##_blog_link_##]">[##_title_##]</a>
<s_search>
<div class="search">
<input
name="[##_search_name_##]"
value="[##_search_text_##]"
placeholder="검색내용을 입력하세요."
onkeypress="if (event.keyCode == 13) { [##_search_onclick_submit_##] }"
/>
<button onclick="[##_search_onclick_submit_##]">
<img src="./images/search.svg" />
</button>
</div>
</s_search>
[##_blog_image_##]
</div>
[##_blog_menu_##]
</header>
<div class="wrapper">
<main></main>
<aside>
<s_sidebar>
<s_sidebar_element>
<!-- 방문자 수 -->
<div class="counter">
<div class="total">
<div>전체 방문자</div>
<div>[##_count_total_##]</div>
</div>
<div class="today">Total : [##_count_today_##]</div>
<div class="yesterday">
Yesterday : [##_count_yesterday_##]
</div>
</div>
</s_sidebar_element>
<s_sidebar_element>
<!-- 태그 클라우드 -->
<div class="tagbox">
<h3>태그</h3>
<s_random_tags>
<a href="[##_tag_link_##]" class="[##_tag_class_##]">[##_tag_name_##]</a>,
</s_random_tags>
</div>
</s_sidebar_element>
<s_sidebar_element>
<!-- 최근 댓글 -->
<div class="recent-reply">
<h3>최근댓글</h3>
<ul>
<s_rctrp_rep>
<li>
<a href="[##_rctrp_rep_link_##]">[##_rctrp_rep_desc_##]</a>
</li>
</s_rctrp_rep>
</ul>
</div>
</s_sidebar_element>
<s_sidebar_element>
<!-- 최근에 올라온 글 -->
<div class="recent-posts">
<h3>최근글</h3>
<s_rctps_rep>
<a class="item" href="[##_rctps_rep_link_##]">
<div class="text">
<h4>[##_rctps_rep_title_##]</h4>
<p>[##_rctps_rep_simple_date_##]</p>
</div>
<s_rctps_rep_thumbnail>
<img src="[##_rctps_rep_thumbnail_##]" />
</s_rctps_rep_thumbnail>
</a>
</s_rctps_rep>
</div>
</s_sidebar_element>
<s_sidebar_element>
<!-- 인기 글 -->
<div class="recent-posts">
<h3>인기글</h3>
<s_rctps_popular_rep>
<a class="item" href="[##_rctps_rep_link_##]">
<div class="text">
<h4>[##_rctps_rep_title_##]</h4>
<p>[##_rctps_rep_simple_date_##]</p>
</div>
<s_rctps_rep_thumbnail>
<img src="[##_rctps_rep_thumbnail_##]" />
</s_rctps_rep_thumbnail>
</a>
</s_rctps_popular_rep>
</div>
</s_sidebar_element>
</s_sidebar>
</aside>
</div>
</div>
</s_t3>
</body>
</html>
a {
color: inherit;
text-decoration: none;
}
ul,
ol {
list-style-type: none;
padding: 0;
}
button {
background-color: transparent;
border: 0;
padding: 0;
cursor: pointer;
}
header {
max-width: 1080px;
margin: 0 auto;
}
header .top {
display: flex;
justify-content: flex-end;
align-items: center;
padding: 15px 0;
}
header .top > img {
width: 30px;
height: 30px;
border-radius: 50%;
margin-left: 10px;
}
header .title {
font-size: 30px;
margin-right: auto;
}
header ul {
display: flex;
}
header ul li {
padding: 0 30px;
}
header ul a {
padding: 20px 0;
color: #666;
border-bottom: 5px solid transparent;
transition: all 0.3s;
}
header ul a:hover {
color: black;
border-color: black;
}
.search {
width: 200px;
height: 30px;
position: relative;
}
.search input {
width: 100%;
height: 100%;
border: 1px solid #eee;
border-radius: 15px;
padding: 0 33px 0 10px;
box-sizing: border-box;
}
.search button {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 10px;
width: 20px;
height: 20px;
}
.search img {
width: 100%;
height: 100%;
opacity: 0.5;
}
.wrapper {
display: flex;
max-width: 1080px;
margin: 0 auto;
}
main {
flex: 1;
padding-top: 60px;
padding-right: 40px;
}
aside {
width: 230px;
padding: 60px 40px;
border-left: 1px solid #eee;
}
.counter .total div:nth-child(1) {
font-size: 16px;
}
.counter .total div:nth-child(2) {
font-size: 26px;
font-weight: bold;
margin-top: 10px;
margin-bottom: 2px;
}
.counter .today,
.counter .yesterday {
color: gray;
}
.tagbox {
margin-bottom: 30px;
font-size: 14px;
color: gray;
line-height: 1.6;
}
.tagbox h3 {
font-size: 14px;
margin-bottom: 5px;
}
.recent-reply {
margin-bottom: 30px;
font-size: 14px;
color: gray;
line-height: 1.6;
}
.recent-reply h3 {
font-size: 14px;
margin-bottom: 5px;
}
.recent-posts {
margin-bottom: 30px;
font-size: 14px;
color: gray;
line-height: 1.6;
}
.recent-posts h3 {
font-size: 14px;
margin-bottom: 10px;
}
.recent-posts .item {
display: flex;
height: 60px;
margin-bottom: 15px;
}
.recent-posts .item .text {
margin-right: 25px;
}
.recent-posts .item h4 {
font-size: 13px;
font-weight: normal;
margin-top: 3px;
margin-bottom: 0;
}
.recent-posts .item p {
font-size: 12px;
font-weight: normal;
margin-top: 0;
margin-bottom: 0;
}
.recent-posts .item img {
height: 100%;
aspect-ratio: 1;
object-fit: cover;
border: 1px solid gray;
}