Skip to content

Commit e3ca463

Browse files
committed
feat: Add sitemap.xml
1 parent 4e71b81 commit e3ca463

1 file changed

Lines changed: 203 additions & 122 deletions

File tree

main.go

Lines changed: 203 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package main
33
import (
44
"blog/lib"
55
"bytes"
6+
"encoding/xml"
67
"fmt"
78
"html/template"
89
"io"
910
"os"
1011
"path/filepath"
1112
"sort"
1213
"strings"
14+
"time"
1315

1416
"github.com/yuin/goldmark"
1517
"github.com/yuin/goldmark/extension"
@@ -273,128 +275,6 @@ func main() {
273275
fmt.Printf("sucess: %s 파일 생성\n", publicPath)
274276
}
275277

276-
// index.html 처리
277-
fmt.Println()
278-
fmt.Println("-- index.html 처리 --")
279-
280-
homeMdBytes, err := os.ReadFile("content/home/home.md")
281-
if err != nil {
282-
fmt.Printf("home.md 파일 읽기 실패: %v\n", err)
283-
return
284-
}
285-
286-
var homeBodyBytes []byte
287-
if bytes.HasPrefix(homeMdBytes, []byte("---")) {
288-
parts := bytes.SplitN(homeMdBytes, []byte("---"), 3)
289-
if len(parts) >= 3 {
290-
homeBodyBytes = parts[2]
291-
} else {
292-
homeBodyBytes = homeMdBytes
293-
}
294-
} else {
295-
homeBodyBytes = homeMdBytes
296-
}
297-
298-
var homeContentBuf bytes.Buffer
299-
if err := md.Convert(homeBodyBytes, &homeContentBuf); err != nil {
300-
fmt.Printf("home.md 변환 실패: %v\n", err)
301-
return
302-
}
303-
304-
sourceHomeFile := "layout/index.html"
305-
tmplHome, err := template.ParseFiles(sourceHomeFile)
306-
if err != nil {
307-
fmt.Printf("템플릿 파일 파싱 실패: %v\n", err)
308-
return
309-
}
310-
311-
destHomeFile := "public/index.html"
312-
outputHomeFile, err := os.Create(destHomeFile)
313-
if err != nil {
314-
fmt.Printf("출력 파일 생성 실패: %v\n", err)
315-
return
316-
}
317-
defer outputHomeFile.Close()
318-
319-
type HomePageData struct {
320-
IsProduction bool
321-
CurrentURL string
322-
Content template.HTML
323-
}
324-
homePageData := HomePageData{
325-
IsProduction: appEnv == "production",
326-
CurrentURL: "/",
327-
Content: template.HTML(homeContentBuf.String()),
328-
}
329-
330-
if err := tmplHome.Execute(outputHomeFile, homePageData); err != nil {
331-
fmt.Printf("템플릿 실행 실패: %v\n", err)
332-
return
333-
}
334-
335-
fmt.Printf("성공: %s 파일 생성\n", destHomeFile)
336-
337-
// about.html 처리
338-
fmt.Println()
339-
fmt.Println("-- abou.html 처리 --")
340-
341-
aboutMdBytes, err := os.ReadFile("content/about/about.md")
342-
if err != nil {
343-
fmt.Printf("about.md 파일 읽기 실패: %v\n", err)
344-
return
345-
}
346-
347-
var aboutBodyBytes []byte
348-
if bytes.HasPrefix(aboutMdBytes, []byte("---")) {
349-
parts := bytes.SplitN(aboutMdBytes, []byte("---"), 3)
350-
if len(parts) >= 3 {
351-
aboutBodyBytes = parts[2]
352-
} else {
353-
aboutBodyBytes = aboutMdBytes
354-
}
355-
} else {
356-
aboutBodyBytes = aboutMdBytes
357-
}
358-
359-
var aboutContentBuf bytes.Buffer
360-
if err := md.Convert(aboutBodyBytes, &aboutContentBuf); err != nil {
361-
fmt.Printf("about.md 변환 실패: %v\n", err)
362-
return
363-
}
364-
365-
sourceAboutFile := "layout/about.html"
366-
tmplabout, err := template.ParseFiles(sourceAboutFile)
367-
if err != nil {
368-
fmt.Printf("템플릿 파일 파싱 실패: %v\n", err)
369-
return
370-
}
371-
372-
destAboutFile := "public/about.html"
373-
outputAboutFile, err := os.Create(destAboutFile)
374-
if err != nil {
375-
fmt.Printf("출력 파일 생성 실패: %v\n", err)
376-
return
377-
}
378-
defer outputAboutFile.Close()
379-
380-
type AboutPageData struct {
381-
IsProduction bool
382-
CurrentURL string
383-
Content template.HTML
384-
}
385-
aboutPageData := AboutPageData{
386-
IsProduction: appEnv == "production",
387-
CurrentURL: "/about",
388-
Content: template.HTML(aboutContentBuf.String()),
389-
}
390-
391-
if err := tmplabout.Execute(outputAboutFile, aboutPageData); err != nil {
392-
fmt.Printf("템플릿 실행 실패: %v\n", err)
393-
return
394-
}
395-
396-
fmt.Printf("성공: %s 파일 생성\n", destAboutFile)
397-
398278
// Post list 처리
399279
fmt.Println()
400280
fmt.Println("-- Post List 처리 --")
@@ -664,4 +544,205 @@ func main() {
664544

665545
fmt.Printf("성공: %s 파일 생성\n", outputFilePath)
666546
}
547+
548+
// index.html 처리
549+
fmt.Println()
550+
fmt.Println("-- index.html 처리 --")
551+
552+
homeMdBytes, err := os.ReadFile("content/home/home.md")
553+
if err != nil {
554+
fmt.Printf("home.md 파일 읽기 실패: %v\n", err)
555+
return
556+
}
557+
558+
var homeBodyBytes []byte
559+
if bytes.HasPrefix(homeMdBytes, []byte("---")) {
560+
parts := bytes.SplitN(homeMdBytes, []byte("---"), 3)
561+
if len(parts) >= 3 {
562+
homeBodyBytes = parts[2]
563+
} else {
564+
homeBodyBytes = homeMdBytes
565+
}
566+
} else {
567+
homeBodyBytes = homeMdBytes
568+
}
569+
570+
var homeContentBuf bytes.Buffer
571+
if err := md.Convert(homeBodyBytes, &homeContentBuf); err != nil {
572+
fmt.Printf("home.md 변환 실패: %v\n", err)
573+
return
574+
}
575+
576+
sourceHomeFile := "layout/index.html"
577+
tmplHome, err := template.ParseFiles(sourceHomeFile)
578+
if err != nil {
579+
fmt.Printf("템플릿 파일 파싱 실패: %v\n", err)
580+
return
581+
}
582+
583+
destHomeFile := "public/index.html"
584+
outputHomeFile, err := os.Create(destHomeFile)
585+
if err != nil {
586+
fmt.Printf("출력 파일 생성 실패: %v\n", err)
587+
return
588+
}
589+
defer outputHomeFile.Close()
590+
591+
type HomePageData struct {
592+
IsProduction bool
593+
CurrentURL string
594+
Content template.HTML
595+
}
596+
homePageData := HomePageData{
597+
IsProduction: appEnv == "production",
598+
CurrentURL: "/",
599+
Content: template.HTML(homeContentBuf.String()),
600+
}
601+
602+
if err := tmplHome.Execute(outputHomeFile, homePageData); err != nil {
603+
fmt.Printf("템플릿 실행 실패: %v\n", err)
604+
return
605+
}
606+
607+
fmt.Printf("성공: %s 파일 생성\n", destHomeFile)
608+
609+
// about.html 처리
610+
fmt.Println()
611+
fmt.Println("-- abou.html 처리 --")
612+
613+
aboutMdBytes, err := os.ReadFile("content/about/about.md")
614+
if err != nil {
615+
fmt.Printf("about.md 파일 읽기 실패: %v\n", err)
616+
return
617+
}
618+
619+
var aboutBodyBytes []byte
620+
if bytes.HasPrefix(aboutMdBytes, []byte("---")) {
621+
parts := bytes.SplitN(aboutMdBytes, []byte("---"), 3)
622+
if len(parts) >= 3 {
623+
aboutBodyBytes = parts[2]
624+
} else {
625+
aboutBodyBytes = aboutMdBytes
626+
}
627+
} else {
628+
aboutBodyBytes = aboutMdBytes
629+
}
630+
631+
var aboutContentBuf bytes.Buffer
632+
if err := md.Convert(aboutBodyBytes, &aboutContentBuf); err != nil {
633+
fmt.Printf("about.md 변환 실패: %v\n", err)
634+
return
635+
}
636+
637+
sourceAboutFile := "layout/about.html"
638+
tmplabout, err := template.ParseFiles(sourceAboutFile)
639+
if err != nil {
640+
fmt.Printf("템플릿 파일 파싱 실패: %v\n", err)
641+
return
642+
}
643+
644+
destAboutFile := "public/about.html"
645+
outputAboutFile, err := os.Create(destAboutFile)
646+
if err != nil {
647+
fmt.Printf("출력 파일 생성 실패: %v\n", err)
648+
return
649+
}
650+
defer outputAboutFile.Close()
651+
652+
type AboutPageData struct {
653+
IsProduction bool
654+
CurrentURL string
655+
Content template.HTML
656+
}
657+
aboutPageData := AboutPageData{
658+
IsProduction: appEnv == "production",
659+
CurrentURL: "/about",
660+
Content: template.HTML(aboutContentBuf.String()),
661+
}
662+
663+
if err := tmplabout.Execute(outputAboutFile, aboutPageData); err != nil {
664+
fmt.Printf("템플릿 실행 실패: %v\n", err)
665+
return
666+
}
667+
668+
fmt.Printf("성공: %s 파일 생성\n", destAboutFile)
669+
670+
// sitemap.xml 처리
671+
type SitemapURL struct {
672+
XMLName xml.Name `xml:"url"`
673+
Loc string `xml:"loc"`
674+
LastMod string `xml:"lastmod"`
675+
ChangeFreq string `xml:"changefreq"`
676+
}
677+
678+
type URLSet struct {
679+
XMLName xml.Name `xml:"urlset"`
680+
Xmlns string `xml:"xmlns,attr"`
681+
XmlnsXSI string `xml:"xmlns:xsi,attr"`
682+
XSILocation string `xml:"xsi:schemaLocation,attr"`
683+
URLs []SitemapURL `xml:"url"`
684+
}
685+
686+
fmt.Println()
687+
fmt.Println("-- Sitemap 생성 --")
688+
689+
const baseURL = "https://chebread.github.io"
690+
691+
var urlset = &URLSet{
692+
Xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9",
693+
XmlnsXSI: "http://www.w3.1/XMLSchema-instance",
694+
XSILocation: "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd",
695+
}
696+
697+
var today = time.Now().Format("2006-01-02")
698+
699+
var staticPages = []string{"", "about.html"} // index.html은 경로가 "" 임.
700+
for _, page := range staticPages {
701+
urlEntry := SitemapURL{
702+
Loc: fmt.Sprintf("%s/%s", baseURL, page),
703+
LastMod: today,
704+
ChangeFreq: "monthly",
705+
}
706+
urlset.URLs = append(urlset.URLs, urlEntry)
707+
}
708+
709+
for _, data := range postsData {
710+
var slug, okSlug = data["slug"].(string)
711+
var date, okDate = data["date"].(string)
712+
713+
if !okSlug || !okDate {
714+
continue
715+
}
716+
717+
var postURL string
718+
if appEnv == "production" {
719+
postURL = fmt.Sprintf("%s/post/%s", baseURL, slug)
720+
} else {
721+
postURL = fmt.Sprintf("%s/post/%s.html", baseURL, slug)
722+
}
723+
724+
var urlEntry = SitemapURL{
725+
Loc: postURL,
726+
LastMod: date, // 포스트의 실제 최종 수정일
727+
ChangeFreq: "weekly", // 포스트는 비교적 자주 변경될 수 있으므로 weekly로 설정함
728+
}
729+
urlset.URLs = append(urlset.URLs, urlEntry)
730+
}
731+
732+
xmlBytes, err := xml.MarshalIndent(urlset, "", " ")
733+
if err != nil {
734+
fmt.Printf("error: Sitemap XML 변환 실패\n")
735+
return
736+
}
737+
738+
var sitemapContent = []byte(xml.Header + string(xmlBytes))
739+
740+
var sitemapPath = "public/sitemap.xml"
741+
err = os.WriteFile(sitemapPath, sitemapContent, 0644)
742+
if err != nil {
743+
fmt.Printf("error: %s 파일 생성 실패\n", sitemapPath)
744+
return
745+
}
746+
747+
fmt.Printf("성공: %s 파일 생성\n", sitemapPath)
667748
}

0 commit comments

Comments
 (0)