158 lines
4.5 KiB
Plaintext

/*
Template that grew in complexity recently. It's was first template that supports JS.
1. Template contains local templ blocks their names starting with lowercase to make it DRY
2. JS script is seperated and should be called *after* page construction.
3. Templ ShowBlogPage contains some math to dynamicly reduce post size
TODO - make it more DRY and modular in general
*/
package templates
import "github.com/dixxe/personal-website/web/static/styling"
import "github.com/dixxe/personal-website/iternal/pkg/repositories"
import "fmt"
import "strings"
import "math"
var markedHandle = templ.NewOnceHandle()
templ runMarked(markdown string) {
@templ.JSONScript("md", markdown)
@markedHandle.Once() {
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script type="text/javascript">
const markdown = JSON.parse(document.getElementById('md').textContent);
marked.use({
pedantic: false,
breaks: true,
gfm: true,
});
document.getElementById('post-content').innerHTML =
marked.parse( markdown );
</script>
}
}
templ blogHeader() {
<div class={ styling.BlogHeading() }>
<div class={styling.BubbleContainer(), styling.BlogHeadingLeft()}>
<p class={ styling.Header()} style="font-family: Disket-Mono;">
Блог нуля
</p>
</div>
<div></div>
<div></div>
<div class={styling.BubbleContainer(), styling.BlogHeadingRight()}>
<p class={ styling.Header() }> Вернуться <a href="/">Домой</a> </p>
</div>
</div>
}
templ postBlockSeo(post repositories.Post) {
<!DOCTYPE HTML>
<html style="background-color: #272727; ">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="/static/icon.png" />
@LoadFontsBlock()
{{
// It's probably awfull practice, but here I calculate
// post size and make it smaller.. In frontend! Magic!
// Doing it again because seo!!
postWords := strings.Fields(post.Content)
postCap := int(math.Sqrt(float64(len(postWords))*5))
if postCap > 150 {postCap = 150}
shortStr := postWords[:postCap]
}}
<meta name="description" content={strings.Join(shortStr, " ")}>
<meta http-equiv="Content-Language" content="ru">
<meta name="robots" content="index, follow">
<title>{post.Header}</title>
</head>
</html>
}
templ blogBlockSeo() {
<!DOCTYPE HTML>
<html style="background-color: #272727; ">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="/static/icon.png" />
@LoadFontsBlock()
<meta name="description" content="Блог nullmax17">
<meta http-equiv="Content-Language" content="ru">
<meta name="robots" content="index, follow">
<title>nullmax17's blog</title>
</head>
</html>
}
templ ShowPost(post repositories.Post) {
@blogHeader()
@postBlockSeo(post)
<div style="margin: 2%;">
<h1 style="font-family: Disket-Mono" class={ styling.FileHeader(), styling.HighlightText() }>
{post.Header}
</h1>
</div>
<div class={ styling.BlogContainer() }>
<div class={} id="post-content"></div>
</div>
@runMarked(post.Content)
}
templ ShowBlogPage(posts []repositories.Post) {
@blogBlockSeo()
@blogHeader()
for i := len(posts) - 1; i>=0; i-- {
<div class={ styling.Textcontainer(), styling.BlogContainer() }>
<h1 class={ styling.Header() } style="font-family: Disket-Mono;">
{posts[i].Header}
</h1>
{{
// It's probably awfull practice, but here I calculate
// post size and make it smaller.. In frontend! Magic!
postWords := strings.Fields(posts[i].Content)
postCap := int(math.Sqrt(float64(len(postWords))*5))
shortStr := postWords[:postCap]
}}
<p id="post-content"> {strings.Join(shortStr, " ")}... </p>
<a class={ styling.HighlightText() } href={ templ.URL(fmt.Sprintf("/post/%v", posts[i].Id)) }>
Читать полностью...
</a>
</div>
}
@UsefulLinks()
}