начал писать систему постов
parent
174ae82d3a
commit
d0162ffa33
2
main.go
2
main.go
|
@ -60,6 +60,8 @@ func setupRoutes(a *models.App) *http.ServeMux {
|
||||||
router.Handle("/ru/", m(controllers_pages.MainRuPageHandler(a)))
|
router.Handle("/ru/", m(controllers_pages.MainRuPageHandler(a)))
|
||||||
// Обработка главной страницы
|
// Обработка главной страницы
|
||||||
router.Handle("/", m(controllers_pages.MainPageHandler(a)))
|
router.Handle("/", m(controllers_pages.MainPageHandler(a)))
|
||||||
|
// Обработка страницы со списком постов
|
||||||
|
router.Handle("/posts/", m(controllers_pages.PostsPageHandler(a)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"main/mvc/models"
|
||||||
|
models_pages "main/mvc/models/pages"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Обработчик главной страницы
|
||||||
|
func PostsPageHandler(a *models.App) http.HandlerFunc {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Страничка рендерится только если ее нет в кэше
|
||||||
|
pageData, ok := a.Cache.Get(models_pages.PostsPageTmplName)
|
||||||
|
if !ok {
|
||||||
|
pageData, err = models_pages.RenderPostsPage(a.Templates, a.Version)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.Cache.Set(models_pages.PostsPageTmplName, pageData)
|
||||||
|
}
|
||||||
|
|
||||||
|
SendPostsPage(w, pageData.([]byte))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляет страницу
|
||||||
|
func SendPostsPage(w http.ResponseWriter, data []byte) {
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(data)
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PostName string
|
||||||
|
|
||||||
|
type Post struct {
|
||||||
|
Name PostName // имя поста
|
||||||
|
Link string // ссылка на пост
|
||||||
|
Preview string // превью поста
|
||||||
|
Data string // содержание
|
||||||
|
CreateTimestamp int64 // время создания
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPost создает новый пост
|
||||||
|
func NewPost(name, link, data string) *Post {
|
||||||
|
// preview - первые 500 символов содержания
|
||||||
|
var preview string
|
||||||
|
if len(data) > 500 {
|
||||||
|
preview = data[:500] + "..."
|
||||||
|
} else {
|
||||||
|
preview = data
|
||||||
|
}
|
||||||
|
|
||||||
|
post := &Post{
|
||||||
|
Name: PostName(name),
|
||||||
|
Link: link,
|
||||||
|
Preview: preview,
|
||||||
|
Data: data,
|
||||||
|
CreateTimestamp: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return post
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"html/template"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Имя соответствующего шаблона
|
||||||
|
PostsPageTmplName = "posts.gohtml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Posts map[PostName]Post
|
||||||
|
|
||||||
|
func RenderPostsPage(templates *template.Template, version int64) ([]byte, error) {
|
||||||
|
var pageData bytes.Buffer
|
||||||
|
|
||||||
|
posts := Posts{
|
||||||
|
"post 1": *NewPost(
|
||||||
|
"post 1",
|
||||||
|
"post-1",
|
||||||
|
"full content 1 with more than 100 characters Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod...",
|
||||||
|
),
|
||||||
|
"post 2": *NewPost(
|
||||||
|
"post 2",
|
||||||
|
"post-2",
|
||||||
|
"full content 2",
|
||||||
|
),
|
||||||
|
"post 3": *NewPost(
|
||||||
|
"post 3",
|
||||||
|
"post-3",
|
||||||
|
strings.Repeat("This is post 3 content. ", 30),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
context := map[string]any{
|
||||||
|
"version": version,
|
||||||
|
"renderingTimestamp": time.Now().Unix(),
|
||||||
|
"posts": posts,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := templates.ExecuteTemplate(&pageData, PostsPageTmplName, context); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pageData.Bytes(), nil
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{ define "footer" }}
|
||||||
|
<footer>
|
||||||
|
<div>
|
||||||
|
<img src="/assets/pic/footer.webp?v={{ .version }}" width="100%" height="100%">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
and also you can subscribe to my Telegram channel with pictures!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://t.me/lolistack" target="_blank">digital countryside</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
_some system information_
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>unix timestamp of page rendering - <strong>{{ .renderingTimestamp }}</strong></li>
|
||||||
|
<li><code>curl -X COUNT https://hikan.ru</code> - 24-hour server request count</li>
|
||||||
|
<li><code>curl -X LIMINAL https://hikan.ru</code> - what do you know about liminal spaces?</li>
|
||||||
|
<li>this site code repository - <a href="https://git.hikan.ru/serr/hikan.ru" target="_blank">git.hikan.ru/serr/hikan.ru</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
this site is written in Go without using frameworks, hosting is <a href="https://htk.ge" target="_blank">hostetski</a>, domain bought for the price of a can of beer
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>2024 - now</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{ define "footer_ru" }}
|
||||||
|
<footer>
|
||||||
|
<div>
|
||||||
|
<img src="/assets/pic/footer.webp?v={{ .version }}" width="100%" height="100%">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
а ещё можно подписаться на мой телеграм-канал с картинками!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://t.me/lolistack" target="_blank">цифровая деревня</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
_немного системной информации_
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>unix-время генерации страницы - <strong>{{ .renderingTimestamp }}</strong></li>
|
||||||
|
<li><code>curl -X COUNT https://hikan.ru</code> - количество завпросов, обработанных сервером за 24ч</li>
|
||||||
|
<li><code>curl -X LIMINAL https://hikan.ru</code> - что ты знаешь о лиминальных пространствах?</li>
|
||||||
|
<li>репозиторий с кодом этого сайта - <a href="https://git.hikan.ru/serr/hikan.ru" target="_blank">git.hikan.ru/serr/hikan.ru</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
этот сайт написан на Go без использования фреймворков, хостинг - <a href="https://htk.ge" target="_blank">hostetski</a>, домен куплен по цене банки пива
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>2024 - настоящее время</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{{ define "head" }}
|
||||||
|
<head>
|
||||||
|
<title>hikan.ru</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="shortcut icon" href="/assets/pic/favicon.webp?v={{ .version }}" type="image/x-icon">
|
||||||
|
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
||||||
|
</head>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{{ define "header" }}
|
||||||
|
<header>
|
||||||
|
<div>
|
||||||
|
<img src="/assets/pic/header.webp?v={{ .version }}" width="100%" height="100%">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
contacts
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
you can message me on <a href="https://t.me/semaphoreslover" target="_blank">telegram</a> or <a href="https://mastodon.ml/@serr" target="_blank">mastodon</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/ru">switch to ru version (AI translation)</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{{ end }}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{{ define "header_ru" }}
|
||||||
|
<header>
|
||||||
|
<div>
|
||||||
|
<img src="/assets/pic/header.webp?v={{ .version }}" width="100%" height="100%">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
контакты
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
вы можете написать мне в <a href="https://t.me/semaphoreslover" target="_blank">telegram</a> или <a href="https://mastodon.ml/@serr" target="_blank">mastodon</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">английская версия</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{{ end }}
|
|
@ -1,31 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
{{ template "head" . }}
|
||||||
<title>hikan.ru</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="shortcut icon" href="/assets/pic/favicon.webp?v={{ .version }}" type="image/x-icon">
|
|
||||||
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
{{ template "header" . }}
|
||||||
<div>
|
|
||||||
<img src="/assets/pic/header.webp?v={{ .version }}" width="100%" height="100%">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
contacts
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
you can message me on <a href="https://t.me/semaphoreslover" target="_blank">telegram</a> or <a href="https://mastodon.ml/@serr" target="_blank">mastodon</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/ru">switch to ru version (AI translation)</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<main>
|
<main>
|
||||||
<div>
|
<div>
|
||||||
<h1>
|
<h1>
|
||||||
|
@ -89,37 +66,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
{{ template "footer" . }}
|
||||||
<div>
|
|
||||||
<img src="/assets/pic/footer.webp?v={{ .version }}" width="100%" height="100%">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
and also you can subscribe to my Telegram channel with pictures!
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://t.me/lolistack" target="_blank">digital countryside</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
_some system information_
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>unix timestamp of page rendering - <strong>{{ .renderingTimestamp }}</strong></li>
|
|
||||||
<li><code>curl -X COUNT https://hikan.ru</code> - 24-hour server request count</li>
|
|
||||||
<li><code>curl -X LIMINAL https://hikan.ru</code> - what do you know about liminal spaces?</li>
|
|
||||||
<li>this site code repository - <a href="https://git.hikan.ru/serr/hikan.ru" target="_blank">git.hikan.ru/serr/hikan.ru</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
this site is written in Go without using frameworks, hosting is <a href="https://htk.ge" target="_blank">hostetski</a>, domain bought for the price of a can of beer
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code>2024 - now</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,31 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="ru">
|
<html lang="ru">
|
||||||
<head>
|
{{ template "head" . }}
|
||||||
<title>hikan.ru</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="shortcut icon" href="/assets/pic/favicon.webp?v={{ .version }}" type="image/x-icon">
|
|
||||||
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
{{ template "header_ru" . }}
|
||||||
<div>
|
|
||||||
<img src="/assets/pic/header.webp?v={{ .version }}" width="100%" height="100%">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
контакты
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
вы можете написать мне в <a href="https://t.me/semaphoreslover" target="_blank">telegram</a> или <a href="https://mastodon.ml/@serr" target="_blank">mastodon</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">английская версия</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<main>
|
<main>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
|
@ -96,37 +73,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
{{ template "footer_ru" . }}
|
||||||
<div>
|
|
||||||
<img src="/assets/pic/footer.webp?v={{ .version }}" width="100%" height="100%">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
а ещё можно подписаться на мой телеграм-канал с картинками!
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://t.me/lolistack" target="_blank">цифровая деревня</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
_немного системной информации_
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>unix-время генерации страницы - <strong>{{ .renderingTimestamp }}</strong></li>
|
|
||||||
<li><code>curl -X COUNT https://hikan.ru</code> - количество завпросов, обработанных сервером за 24ч</li>
|
|
||||||
<li><code>curl -X LIMINAL https://hikan.ru</code> - что ты знаешь о лиминальных пространствах?</li>
|
|
||||||
<li>репозиторий с кодом этого сайта - <a href="https://git.hikan.ru/serr/hikan.ru" target="_blank">git.hikan.ru/serr/hikan.ru</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
этот сайт написан на Go без использования фреймворков, хостинг - <a href="https://htk.ge" target="_blank">hostetski</a>, домен куплен по цене банки пива
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code>2024 - настоящее время</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "head" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "header" . }}
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{{ range $key, $post := .posts }}
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
{{ $post.Name }}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
{{ $post.Preview }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="/{{ $post.Link }}">read more</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>created at: {{ $post.CreateTimestamp }}</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
{{ template "footer" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue