Skip to content

Commit 90029a8

Browse files
committed
refactor: Overhaul build process with Go and separate concerns
feat: Implement post categories
1 parent fc3e5dd commit 90029a8

8 files changed

Lines changed: 209 additions & 76 deletions

File tree

content/에세이/단일 책임 원칙이 무너지고 있다.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
date: 2025-09-13
3-
category: [에세이]
3+
category: [에세이, foo]
44
published: true
55
fixed: false
66
---

content/해커톤/d.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
date: 2025-01-01
3+
desc:
4+
category: [해커톤]
5+
published: true
6+
fixed: false
7+
---
8+
9+
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

layout/category.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@
4040
<link rel="stylesheet" href="/styles/layout.css" />
4141
<link rel="stylesheet" href="/styles/color-palette.css">
4242

43-
<link rel="stylesheet" href="/styles/posts.css">
43+
<link rel="stylesheet" href="/styles/category.css">
4444

4545
<link rel="icon" href="/favicons/favicon.ico" sizes="any">
4646
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
4747
<link rel="apple-touch-icon" href="/favicons/apple-touch-icon.png">
4848
</head>
4949
<body>
5050
<div class="root">
51-
<div class="posts">
52-
<nav class="posts-nav">
51+
<div class="category">
52+
<nav class="category-nav">
5353
<a href="/" class="{{if eq .CurrentURL "/"}}active{{end}}">
5454
<span></span>
5555
</a>
@@ -61,10 +61,10 @@
6161
</a>
6262
</nav>
6363

64-
<main class="posts-list">
64+
<main class="category-list">
6565
{{ .PostList }}
6666
</main>
67-
<footer class="posts-footer">
67+
<footer class="category-footer">
6868
<section>
6969
<p>&copy; 2025 Cha Haneum</p>
7070
</section>

layout/post.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@
6868
<header class="post-header">
6969
<h1 class="post-title">{{- .Title -}}</h1>
7070
<p class="post-date"><time datetime="{{- .Date -}}">{{- .FormattedDate -}}</time></p>
71-
<p class="post-category">{{- .Category -}}</p>
71+
<p class="post-category">
72+
{{- range .Categories -}}
73+
<a href="{{ .URL }}">[{{ .Name }}]</a>
74+
{{- end -}}
75+
</p>
7276
</header>
7377
<div class="post-body">
7478
<article class="markdown-body">

layout/styles/category.scss

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
.category-nav {
2+
position: sticky;
3+
top: 0;
4+
z-index: 10;
5+
display: flex;
6+
height: 4rem;
7+
flex-direction: row;
8+
background-color: white;
9+
10+
a {
11+
-webkit-tap-highlight-color: transparent;
12+
-moz-user-select: none;
13+
-webkit-user-select: none;
14+
-ms-user-select: none;
15+
user-select: none;
16+
17+
position: relative;
18+
flex: 1;
19+
display: flex;
20+
justify-content: center;
21+
align-items: center;
22+
span {
23+
font-size: 1rem;
24+
line-height: 1.5;
25+
font-weight: 900;
26+
color: black;
27+
}
28+
&::after {
29+
content: '';
30+
position: absolute;
31+
bottom: 0.5rem;
32+
height: 1.5px;
33+
background-color: black;
34+
width: 50%;
35+
left: 50%;
36+
transform: translateX(-50%) scaleX(0);
37+
transform-origin: center;
38+
}
39+
&.active::after {
40+
transform: translateX(-50%) scaleX(1);
41+
}
42+
}
43+
}
44+
45+
46+
.category-list {
47+
padding: 1rem 0 1rem 0;
48+
@media (max-width: 35rem) {
49+
padding: 1rem 1.3rem 1rem 1.3rem;
50+
}
51+
52+
display: flex;
53+
flex-direction: column;
54+
gap: 3rem;
55+
56+
.category-group {
57+
.category-group-title {
58+
font-size: 1rem;
59+
line-height: 1.5;
60+
font-weight: 800;
61+
padding-bottom: 0.5rem;
62+
text-decoration: underline;
63+
}
64+
65+
.category-group-list {
66+
display: flex;
67+
flex-direction: column;
68+
69+
gap: 2rem;
70+
71+
.category-item {
72+
display: flex;
73+
flex-direction: column;
74+
gap: 0.125rem;
75+
76+
.category-item-title {
77+
font-size: 1.2rem;
78+
line-height: 1.5;
79+
font-weight: 700;
80+
text-decoration: underline;
81+
}
82+
83+
.category-item-date {
84+
font-size: 1rem;
85+
line-height: 1.5;
86+
}
87+
88+
.category-item-description {
89+
font-size: 1rem;
90+
line-height: 1.5;
91+
}
92+
93+
.category-item-category {
94+
font-size: 1rem;
95+
line-height: 1.5;
96+
}
97+
}
98+
99+
.back-link {
100+
text-decoration: underline;
101+
font-size: 1rem;
102+
font-weight: 600;
103+
line-height: 1.5;
104+
}
105+
}
106+
}
107+
}
108+
109+
.category-footer {
110+
padding: 3rem 0 3rem 0;
111+
section {
112+
display: flex;
113+
flex-direction: row;
114+
justify-content: center;
115+
align-items: center;
116+
117+
padding: 0.25rem;
118+
119+
font-size: 1rem;
120+
font-weight: 400;
121+
line-height: 1.5;
122+
123+
gap: 0.5rem;
124+
125+
a {
126+
text-decoration: underline;
127+
}
128+
}
129+
}

layout/styles/post.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@
6565
}
6666

6767
.post-category {
68+
text-decoration: underline;
6869
font-weight: 500;
70+
display: flex;
71+
flex-direction: row;
72+
gap: 0.25rem;
6973
}
7074
}
7175
}

layout/styles/posts.scss

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,6 @@
105105
font-weight: 600;
106106
line-height: 1.5;
107107
}
108-
109-
.back-link {
110-
text-decoration: underline;
111-
font-size: 1rem;
112-
font-weight: 600;
113-
line-height: 1.5;
114-
}
115108
}
116109
}
117110
}

main.go

Lines changed: 56 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -21,48 +21,6 @@ import (
2121
highlighting "github.com/yuin/goldmark-highlighting/v2"
2222
)
2323

24-
// Refactor TODO:
25-
/*
26-
0. CI/CD
27-
1. pnpm run build 하면 build.sh 먼저 실행 및 go run .
28-
2. pnpm run build:prod 하면 build.sh 먼저 실행 및 cross-env APP_ENV=production go run .
29-
30-
1. data 처리:
31-
1. build.sh:
32-
1. unix 명령어로 public 디렉토리 초기화(없으면 생성, 있으면 초기화)
33-
DOCS: public 디렉토리 자체는 이제 main.go에서 처리하지 않음(즉, 생성 및 초기화 안함)
34-
2. sass 명령어로 public/styles 디렉토리 생성 및 scss 컴파일
35-
3. esbuild 명령어로 public/js 디렉토리 생성 및 js 컴파일
36-
4. unix 명령어로 .nojekyll 파일 생성
37-
5. unix 명령어로 robots.txt 파일 복사해서 붙여넣기
38-
6. content/assets 속 모든 파일 public/assets에 붙여넣기
39-
2. main.go:
40-
1. 포스트 관련 처리
41-
1. PostsData 처리
42-
- title string
43-
- date string
44-
- description string
45-
- category []string
46-
- fixed bool
47-
- sourceFilePath string <- 실제 블로그가 저장된 위치
48-
e.g. content/tgpl/go 정리법
49-
- slug <- 그냥 가공된 PATH로 활용될 이름임
50-
e.g. go-정리법
51-
-> 여기에 .html, post/, public/ 붙여서 활용하기
52-
2. post.html 생성
53-
href: posts/category-foo, /, about, posts
54-
DOCS: href는 해당 html에 포함된 hyperlink임
55-
3. posts.html 생성
56-
href: posts/category-foo, /, about, posts
57-
4. posts/category-foo.html 생성
58-
href: /, about, posts
59-
2. 블로그 관련 처리
60-
1. index.html 생성
61-
2. about.html 생성
62-
2.
63-
64-
*/
65-
6624
func main() {
6725
// Get env
6826
var appEnv string = os.Getenv("APP_ENV")
@@ -199,16 +157,22 @@ func main() {
199157
fmt.Printf("error: layout/post.html - 템플릿 파싱 실패\n")
200158
}
201159

160+
type CategoryInfo struct {
161+
Name string
162+
URL string
163+
}
164+
202165
type PostTmplData struct {
203166
IsProduction bool
204167
Title string
205168
Date string
206169
FormattedDate string
207-
Category []string
208-
Description string
209-
Permalink string
210-
Content template.HTML
211-
CurrentURL string // for nav tag
170+
// Category []string
171+
Description string
172+
Permalink string
173+
Content template.HTML
174+
CurrentURL string // for nav tag
175+
Categories []CategoryInfo
212176
}
213177

214178
for _, data := range postsData {
@@ -232,6 +196,23 @@ func main() {
232196
return
233197
}
234198

199+
var categoriesData []CategoryInfo
200+
for _, c := range category {
201+
var linkURL string
202+
slugifiedPath := lib.SlugifyPath(c)
203+
204+
if appEnv == "production" {
205+
linkURL = filepath.ToSlash(filepath.Join("/", "posts", slugifiedPath))
206+
} else {
207+
linkURL = filepath.ToSlash(filepath.Join("/", "posts", fmt.Sprintf("%s.html", slugifiedPath)))
208+
}
209+
210+
categoriesData = append(categoriesData, CategoryInfo{
211+
Name: c, // "Go"
212+
URL: linkURL, // "/posts/go.html"
213+
})
214+
}
215+
235216
// Post 생성
236217
sourceBytes, err := os.ReadFile(sourceFilePath)
237218
if err != nil {
@@ -268,11 +249,12 @@ func main() {
268249
Title: title,
269250
Date: date,
270251
FormattedDate: formattedDate,
271-
Category: category,
272-
Description: description,
273-
Permalink: permalink,
274-
Content: template.HTML(contentBuf.String()),
275-
CurrentURL: "/posts",
252+
// Category: category,
253+
Description: description,
254+
Permalink: permalink,
255+
Content: template.HTML(contentBuf.String()),
256+
CurrentURL: "/posts",
257+
Categories: categoriesData,
276258
}
277259

278260
if err := postTemplate.Execute(outputFile, postTmplData); err != nil {
@@ -630,22 +612,34 @@ func main() {
630612

631613
var templateString string
632614
if isFixed {
633-
templateString = `<li><article class="post-item"><h3 class="post-item-title"><a href="%s">[고정됨] %s</a></h3><p class="post-item-date"><time datetime="%s">%s</time></p><p class="post-item-description">%s</p></article></li>`
615+
templateString = `<li>
616+
<article class="category-item">
617+
<h3 class="category-item-title"><a href="%s">[고정됨] %s</a></h3>
618+
<p class="category-item-date"><time datetime="%s">%s</time></p>
619+
<p class="category-item-description">%s</p>
620+
</article>
621+
</li>`
634622
postListHtml.WriteString(fmt.Sprintf(templateString, permalink, title, date, formattedDate, description))
635623
} else {
636-
templateString = `<li><article class="post-item"><h3 class="post-item-title"><a href="%s">%s</a></h3><p class="post-item-date"><time datetime="%s">%s</time></p><p class="post-item-description">%s</p></article></li>`
624+
templateString = `<li>
625+
<article class="category-item">
626+
<h3 class="category-item-title"><a href="%s">%s</a></h3>
627+
<p class="category-item-date"><time datetime="%s">%s</time></p>
628+
<p class="category-item-description">%s</p>
629+
</article>
630+
</li>`
637631
postListHtml.WriteString(fmt.Sprintf(templateString, permalink, title, date, formattedDate, description))
638632
}
639633
}
640634

641-
var backLinkURL string
642-
if appEnv == "production" {
643-
backLinkURL = "/posts"
644-
} else {
645-
backLinkURL = "/posts.html"
646-
}
647-
backButtonHTML := fmt.Sprintf(`<li><article class="back-link"><a href="%s">돌아가기</a></article></li>`, backLinkURL)
648-
postListHtml.WriteString(backButtonHTML)
635+
// var backLinkURL string
636+
// if appEnv == "production" {
637+
// backLinkURL = "/posts"
638+
// } else {
639+
// backLinkURL = "/posts.html"
640+
// }
641+
// backButtonHTML := fmt.Sprintf(`<li><article class="back-link"><a <a href="#" onclick="history.back(); return false;">돌아가기</a></article></li>`, backLinkURL)
642+
// postListHtml.WriteString(backButtonHTML)
649643

650644
postListHtml.WriteString("</ul>")
651645
postListHtml.WriteString("</section>")

0 commit comments

Comments
 (0)