Simplified server initialization
This commit is contained in:
parent
12a3d7e16c
commit
48dbc0bbed
103
App.go
Normal file
103
App.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.akyoto.dev/go/markdown"
|
||||||
|
"git.akyoto.dev/go/web"
|
||||||
|
"git.akyoto.dev/go/web/send"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
html string
|
||||||
|
posts map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *App) Init() {
|
||||||
|
app.html = mustLoadClean("public/app.html")
|
||||||
|
css := mustLoadClean("public/app.css")
|
||||||
|
body := mustLoadClean("public/body.html")
|
||||||
|
app.html = strings.Replace(app.html, "{head}", fmt.Sprintf("<style>%s</style>", css), 1)
|
||||||
|
app.html = strings.Replace(app.html, "{body}", body, 1)
|
||||||
|
app.posts = loadPosts("posts")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *App) Run() {
|
||||||
|
s := web.NewServer()
|
||||||
|
|
||||||
|
s.Use(func(ctx web.Context) error {
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Recovered panic:", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ctx.Next()
|
||||||
|
})
|
||||||
|
|
||||||
|
render := func(ctx web.Context, content string) error {
|
||||||
|
return send.HTML(ctx, strings.Replace(app.html, "{content}", content, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Get("/", func(ctx web.Context) error {
|
||||||
|
return render(ctx, markdown.Render("# Frontpage"))
|
||||||
|
})
|
||||||
|
|
||||||
|
s.Get("/:post", func(ctx web.Context) error {
|
||||||
|
post := ctx.Request().Param("post")
|
||||||
|
return render(ctx, app.posts[post])
|
||||||
|
})
|
||||||
|
|
||||||
|
s.Run(":8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustLoadClean(path string) string {
|
||||||
|
data := mustLoad(path)
|
||||||
|
data = strings.ReplaceAll(data, "\t", "")
|
||||||
|
data = strings.ReplaceAll(data, "\n", "")
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustLoad(path string) string {
|
||||||
|
dataBytes, err := os.ReadFile(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(dataBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPosts(directory string) map[string]string {
|
||||||
|
entries, err := os.ReadDir(directory)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
posts := map[string]string{}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
fileName := entry.Name()
|
||||||
|
|
||||||
|
if !strings.HasSuffix(fileName, ".md") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
baseName := strings.TrimSuffix(fileName, ".md")
|
||||||
|
content := mustLoad("posts/" + fileName)
|
||||||
|
|
||||||
|
if strings.HasPrefix(content, "---\n") {
|
||||||
|
end := strings.Index(content[4:], "---\n") + 4
|
||||||
|
content = content[end+4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
posts[baseName] = markdown.Render(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return posts
|
||||||
|
}
|
37
main.go
37
main.go
@ -1,38 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.akyoto.dev/go/web"
|
|
||||||
"git.akyoto.dev/go/web/send"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
html := mustLoad("public/app.html")
|
app := App{}
|
||||||
css := mustLoad("public/app.css")
|
app.Init()
|
||||||
body := mustLoad("public/body.html")
|
app.Run()
|
||||||
layout := strings.Replace(html, "%head%", fmt.Sprintf("<style>%s</style>", css), 1)
|
|
||||||
|
|
||||||
s := web.NewServer()
|
|
||||||
|
|
||||||
s.Get("/", func(ctx web.Context) error {
|
|
||||||
return send.HTML(ctx, strings.Replace(layout, "%body%", body, 1))
|
|
||||||
})
|
|
||||||
|
|
||||||
s.Run(":8080")
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustLoad(path string) string {
|
|
||||||
dataBytes, err := os.ReadFile(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := string(dataBytes)
|
|
||||||
data = strings.ReplaceAll(data, "\t", "")
|
|
||||||
data = strings.ReplaceAll(data, "\n", "")
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,54 @@ th:empty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
main,
|
||||||
|
footer {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--max-width);
|
||||||
|
padding: var(--padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
max-width: calc(var(--max-width) + 4rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.75em;
|
||||||
|
color: var(--grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
list-style-type: none;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
color: var(--grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
time {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--grey-color);
|
||||||
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: var(--font-family-mono);
|
font-family: var(--font-family-mono);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="icon" href="/static/favicon.avif" type="image/avif" />
|
<link rel="icon" href="/static/favicon.avif" type="image/avif" />
|
||||||
%head%
|
{head}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
%body%
|
{body}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,56 +1,3 @@
|
|||||||
<style>
|
|
||||||
header,
|
|
||||||
main,
|
|
||||||
footer {
|
|
||||||
width: 100%;
|
|
||||||
max-width: var(--max-width);
|
|
||||||
padding: var(--padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
max-width: calc(var(--max-width) + 4rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 0.75em;
|
|
||||||
color: var(--grey-color);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
nav {
|
|
||||||
display: flex;
|
|
||||||
gap: 1rem;
|
|
||||||
list-style-type: none;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--grey-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 1.4rem;
|
|
||||||
font-weight: 700;
|
|
||||||
color: var(--main-color);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
time {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--grey-color);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/" class="nav-item title">akyoto.dev</a>
|
<a href="/" class="nav-item title">akyoto.dev</a>
|
||||||
@ -60,6 +7,5 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
Test.
|
{content}
|
||||||
</main>
|
</main>
|
||||||
<footer></footer>
|
|
Loading…
x
Reference in New Issue
Block a user