сделал ajax с использованием htmx
parent
0540bdf1d2
commit
2d4a6c77a5
|
@ -1,2 +1,3 @@
|
|||
config.json
|
||||
hikan.ru
|
||||
*.server*
|
|
@ -69,6 +69,7 @@ h1::before { top: 0; }
|
|||
h1::after { bottom: 0; }
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
background-color: #77abbb;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
|
|
File diff suppressed because one or more lines are too long
2
eye.sh
2
eye.sh
|
@ -4,7 +4,7 @@ stty -echoctl # Отключает вывод управляющих симво
|
|||
# НАСТРОЙКА СКРИПТА ТУТ ###########################################################
|
||||
DURATION=1 # Задержка между проверками в секундах
|
||||
WATCH_TARGETS=("assets" "mvc" "posts" "tools" "main.go" "config.json") # Массив целей для наблюдения (директории и файлы)
|
||||
BINARY_PATH="./main" # Путь до бинарного файла
|
||||
BINARY_PATH="./main.server" # Путь до бинарного файла
|
||||
BUILD_CMD="go build -o $BINARY_PATH main.go" # Команда для сборки
|
||||
###################################################################################
|
||||
|
||||
|
|
|
@ -14,7 +14,10 @@ import (
|
|||
func MainPageHandler(app *models.App) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var err error
|
||||
var (
|
||||
pageData []byte
|
||||
err error
|
||||
)
|
||||
|
||||
// Количество запросов, обработанных сервером за 24ч
|
||||
if r.Method == "COUNT" {
|
||||
|
@ -38,16 +41,23 @@ func MainPageHandler(app *models.App) http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
// Страничка рендерится только если ее нет в кэше
|
||||
pageData, ok := app.PagesCache.Get(models_pages.MainPageTmplName)
|
||||
if !ok {
|
||||
pageData, err = models_pages.RenderMainPage(app.Templates, app.Version)
|
||||
cacheKey := models_pages.MainPageTmplName
|
||||
ajax := r.URL.Query().Get("ajax") == "true"
|
||||
if ajax {
|
||||
cacheKey += "?ajax=true"
|
||||
}
|
||||
|
||||
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||
sendMainPage(w, pageData)
|
||||
return
|
||||
}
|
||||
|
||||
pageData, err = models_pages.RenderMainPage(app.Templates, app.Version, ajax)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
app.PagesCache.Set(models_pages.MainPageTmplName, pageData)
|
||||
}
|
||||
app.PagesCache.Set(cacheKey, pageData)
|
||||
|
||||
sendMainPage(w, pageData)
|
||||
})
|
||||
|
|
|
@ -6,27 +6,34 @@ import (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
// Обработчик главной страницы
|
||||
// Обработчик страницы поста
|
||||
func PostPageHandler(app *models.App) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
|
||||
// Ссылка вида /postname
|
||||
link := r.URL.Path
|
||||
cacheKey := link
|
||||
ajax := r.URL.Query().Get("ajax") == "true"
|
||||
if ajax {
|
||||
cacheKey += "?ajax=true"
|
||||
}
|
||||
|
||||
// Страничка рендерится только если ее нет в кэше
|
||||
pageData, ok := app.PagesCache.Get(link)
|
||||
if !ok {
|
||||
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||
sendPostPage(w, pageData)
|
||||
return
|
||||
}
|
||||
|
||||
post := app.PostsMap[models_pages.PostLink(link)]
|
||||
|
||||
pageData, err = post.RenderPostPage(app.Templates, app.Version)
|
||||
var (
|
||||
pageData []byte
|
||||
err error
|
||||
)
|
||||
|
||||
pageData, err = post.RenderPostPage(app.Templates, app.Version, ajax)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
app.PagesCache.Set(link, pageData)
|
||||
}
|
||||
app.PagesCache.Set(cacheKey, pageData)
|
||||
|
||||
sendPostPage(w, pageData)
|
||||
})
|
||||
|
|
|
@ -10,37 +10,39 @@ import (
|
|||
|
||||
// Обработчик странички со списком постов
|
||||
func PostsPageHandler(app *models.App) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
|
||||
// Ссылка вида /posts/0
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
link := r.URL.Path
|
||||
cacheKey := link
|
||||
|
||||
// Страничка рендерится только если ее нет в кэше
|
||||
pageData, ok := app.PagesCache.Get(link)
|
||||
if !ok {
|
||||
ajax := r.URL.Query().Get("ajax") == "true"
|
||||
if ajax {
|
||||
cacheKey += "?ajax=true"
|
||||
}
|
||||
|
||||
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||
sendPostsPage(w, pageData)
|
||||
return
|
||||
}
|
||||
|
||||
// Из мапы формирую отсортированный список всех постов (сначала новые)
|
||||
postsList := app.PostsMap.PostsList()
|
||||
|
||||
// Ошибки тут быть не может, так как этот обработчик настроен
|
||||
// на только существующие реально pageNumber и в случае
|
||||
// какого то не существующего номера страницы он просто
|
||||
// не сработает (в главном main настроены маршруты)
|
||||
pageNumber, _ := strconv.Atoi(path.Base(link))
|
||||
|
||||
page := models_pages.CreatePostsPage(postsList, pageNumber, app.Cfg.PostsMaxCountOnPage)
|
||||
|
||||
pageData, err = page.RenderPostsPage(app.Templates, app.Version)
|
||||
var (
|
||||
pageData []byte
|
||||
err error
|
||||
)
|
||||
|
||||
pageData, err = page.RenderPostsPage(app.Templates, app.Version, ajax)
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
app.PagesCache.Set(link, pageData)
|
||||
}
|
||||
|
||||
app.PagesCache.Set(cacheKey, pageData)
|
||||
sendPostsPage(w, pageData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Отправляет страницу
|
||||
|
|
|
@ -9,9 +9,10 @@ import (
|
|||
const (
|
||||
// Имя соответствующего шаблона
|
||||
MainPageTmplName = "main.gohtml"
|
||||
MainPageTmplNameAjax = "main_ajax.gohtml"
|
||||
)
|
||||
|
||||
func RenderMainPage(templates *template.Template, version int64) ([]byte, error) {
|
||||
func RenderMainPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||
var pageData bytes.Buffer
|
||||
|
||||
context := map[string]any{
|
||||
|
@ -19,7 +20,12 @@ func RenderMainPage(templates *template.Template, version int64) ([]byte, error)
|
|||
"renderingTimestamp": time.Now().Unix(),
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, MainPageTmplName, context); err != nil {
|
||||
templateName := MainPageTmplName
|
||||
if ajax {
|
||||
templateName = MainPageTmplNameAjax
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
const (
|
||||
// Имя соответствующего шаблона
|
||||
PostPageTmplName = "post.gohtml"
|
||||
PostPageTmplNameAjax = "post_ajax.gohtml"
|
||||
)
|
||||
|
||||
type PostLink string
|
||||
|
@ -19,7 +20,7 @@ type Post struct {
|
|||
Timestamp int64
|
||||
}
|
||||
|
||||
func (p *Post) RenderPostPage(templates *template.Template, version int64) ([]byte, error) {
|
||||
func (p *Post) RenderPostPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||
var pageData bytes.Buffer
|
||||
|
||||
context := map[string]any{
|
||||
|
@ -29,7 +30,12 @@ func (p *Post) RenderPostPage(templates *template.Template, version int64) ([]by
|
|||
"modTimestamp": p.Timestamp,
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, PostPageTmplName, context); err != nil {
|
||||
templateName := PostPageTmplName
|
||||
if ajax {
|
||||
templateName = PostPageTmplNameAjax
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
const (
|
||||
// Имя соответствующего шаблона
|
||||
PostsPageTmplName = "posts.gohtml"
|
||||
PostsPageTmplNameAjax = "posts_ajax.gohtml"
|
||||
)
|
||||
|
||||
type PostsMap map[PostLink]*Post
|
||||
|
@ -101,7 +102,7 @@ func CreatePostsPage(postsList PostsList, pageNumber, postsMaxCountOnPage int) *
|
|||
}
|
||||
}
|
||||
|
||||
func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64) ([]byte, error) {
|
||||
func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||
var pageData bytes.Buffer
|
||||
|
||||
var prevPageNumber, nextPageNumber int
|
||||
|
@ -114,22 +115,22 @@ func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64)
|
|||
|
||||
nextPageNumber = (p.PageNumber + 1) % p.PagesCount
|
||||
|
||||
pagi := fmt.Sprintf(
|
||||
`<a href="/posts/%d"><-</a> %d/%d <a href="/posts/%d">-></a>`,
|
||||
prevPageNumber,
|
||||
p.PageNumber+1,
|
||||
p.PagesCount,
|
||||
nextPageNumber,
|
||||
)
|
||||
|
||||
context := map[string]any{
|
||||
"pagi": template.HTML(pagi),
|
||||
"prevPageNumber": prevPageNumber,
|
||||
"pageNumberInc": p.PageNumber + 1,
|
||||
"pagesCount": p.PagesCount,
|
||||
"nextPageNumber": nextPageNumber,
|
||||
"version": version,
|
||||
"renderingTimestamp": time.Now().Unix(),
|
||||
"posts": p.PostsListOnPage,
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, PostsPageTmplName, context); err != nil {
|
||||
templateName := PostsPageTmplName
|
||||
if ajax {
|
||||
templateName = PostsPageTmplNameAjax
|
||||
}
|
||||
|
||||
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="/assets/pic/favicon.ico?v={{ .version }}" type="image/x-icon">
|
||||
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
||||
<script src="/assets/scripts/htmx.js?v={{ .version }}"></script>
|
||||
<script>document.addEventListener('htmx:afterSwap', function() {window.scrollTo(0, 0);});</script>
|
||||
</head>
|
||||
{{ end }}
|
|
@ -19,7 +19,19 @@
|
|||
</div>
|
||||
<div>
|
||||
<p>
|
||||
see <a href="/">main page</a> or go to <a href="/posts/0">posts section</a>
|
||||
see <a href="/"
|
||||
hx-get="/?ajax=true"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="/">
|
||||
main page</a> or go to
|
||||
<a href="/posts/0"
|
||||
hx-get="/posts/0?ajax=true"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="/posts/0">
|
||||
posts section
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
<main>
|
||||
<div>
|
||||
<p>
|
||||
<code>welcome to my little site</code>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
$whoami
|
||||
</h1>
|
||||
<p>
|
||||
my name is serr (you can easily guess my real name if you speak Russian :d), and i didn't come up with that nickname, i just started being called it
|
||||
</p>
|
||||
<p>
|
||||
i was born in 2003, i'm currently a cybersecurity major at university
|
||||
</p>
|
||||
<p>
|
||||
<code>pronouns: he/him</code>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
what do i do?
|
||||
</h1>
|
||||
<p>
|
||||
programming is my lifestyle
|
||||
</p>
|
||||
<p>
|
||||
i love growing in all areas of programming - i am literally interested in everything: web development, low-level programming, formal grammars and a lot more!
|
||||
</p>
|
||||
<p>
|
||||
i like the idea of <a href="https://en.wikipedia.org/wiki/Symbolic_execution" target="_blank">symbolic</a>/concolic execution and virtual code execution in general
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
things i love
|
||||
</h1>
|
||||
<p>
|
||||
<strong>> coffee</strong>. i REALLY love coffee. almost any. and a lot of<br/>
|
||||
<strong>> movies and TV series</strong> (especially TV series). i watch something almost every day<br/>
|
||||
<strong>> true crime</strong>. i'm obsessed with serial killer cases, mysterious disappearances, unsolved murders - all that dark stuff<br/>
|
||||
<strong>> russian underground rap</strong> like Slava KPSS, Zamay, MB Packet, Ovsyankin etc.<br/>
|
||||
<strong>> simple and extensible code</strong>. i think if your code is overly complex, it means you are doing something wrong. most things are simpler than they seem
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
projects
|
||||
</h1>
|
||||
<p>
|
||||
> <a href="https://git.hikan.ru/serr/candycache" target="_blank">git.hikan.ru/serr/candycache</a> - simple and efficient Go cache<br/>
|
||||
> <a href="https://git.hikan.ru/serr/eye-hot-reloader" target="_blank">git.hikan.ru/serr/eye-hot-reloader</a> - lightweight directories monitor with automatic rebuild and restart functionality for any project type<br/>
|
||||
> <del>telegram bot with schedule for SPBPU - <a href="https://t.me/polysched_bot" target="_blank">polysched_bot</a></del> (transferred to a more proactive owner)<br/>
|
||||
> <del>telegram bot with schedule for SPMI - <a href="https://t.me/gornischedule_bot" target="_blank">gornischedule_bot</a></del> (closed)<br/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
nice links
|
||||
</h1>
|
||||
<p>
|
||||
> huge collection of Xakep issues - <a href="https://図書館.きく.コム/" target="_blank">図書館.きく.コム</a><br/>
|
||||
> i like to surf here - <a href="https://neocities.org/browse" target="_blank">neocities.org/browse</a><br/>
|
||||
> very atmospheric forum about black metal - <a href="https://www.lycanthropia.net/" target="_blank">lycanthropia</a><br/>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
{{ template "main_ajax" . }}
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
{{ template "main_ajax" . }}
|
||||
|
||||
{{ define "main_ajax" }}
|
||||
<main>
|
||||
<div>
|
||||
<p>
|
||||
<code>welcome to my little site</code>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
$whoami
|
||||
</h1>
|
||||
<p>
|
||||
my name is serr (you can easily guess my real name if you speak Russian :d), and i didn't come up with that nickname, i just started being called it
|
||||
</p>
|
||||
<p>
|
||||
i was born in 2003, i'm currently a cybersecurity major at university
|
||||
</p>
|
||||
<p>
|
||||
<code>pronouns: he/him</code>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
what do i do?
|
||||
</h1>
|
||||
<p>
|
||||
programming is my lifestyle
|
||||
</p>
|
||||
<p>
|
||||
i love growing in all areas of programming - i am literally interested in everything: web development, low-level programming, formal grammars and a lot more!
|
||||
</p>
|
||||
<p>
|
||||
i like the idea of <a href="https://en.wikipedia.org/wiki/Symbolic_execution" target="_blank">symbolic</a>/concolic execution and virtual code execution in general
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
things i love
|
||||
</h1>
|
||||
<p>
|
||||
<strong>> coffee</strong>. i REALLY love coffee. almost any. and a lot of<br/>
|
||||
<strong>> movies and TV series</strong> (especially TV series). i watch something almost every day<br/>
|
||||
<strong>> true crime</strong>. i'm obsessed with serial killer cases, mysterious disappearances, unsolved murders - all that dark stuff<br/>
|
||||
<strong>> russian underground rap</strong> like Slava KPSS, Zamay, MB Packet, Ovsyankin etc.<br/>
|
||||
<strong>> simple and extensible code</strong>. i think if your code is overly complex, it means you are doing something wrong. most things are simpler than they seem
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
projects
|
||||
</h1>
|
||||
<p>
|
||||
> <a href="https://git.hikan.ru/serr/candycache" target="_blank">git.hikan.ru/serr/candycache</a> - simple and efficient Go cache<br/>
|
||||
> <a href="https://git.hikan.ru/serr/eye-hot-reloader" target="_blank">git.hikan.ru/serr/eye-hot-reloader</a> - lightweight directories monitor with automatic rebuild and restart functionality for any project type<br/>
|
||||
> <del>telegram bot with schedule for SPBPU - <a href="https://t.me/polysched_bot" target="_blank">polysched_bot</a></del> (transferred to a more proactive owner)<br/>
|
||||
> <del>telegram bot with schedule for SPMI - <a href="https://t.me/gornischedule_bot" target="_blank">gornischedule_bot</a></del> (closed)<br/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h1>
|
||||
nice links
|
||||
</h1>
|
||||
<p>
|
||||
> huge collection of Xakep issues - <a href="https://図書館.きく.コム/" target="_blank">図書館.きく.コム</a><br/>
|
||||
> i like to surf here - <a href="https://neocities.org/browse" target="_blank">neocities.org/browse</a><br/>
|
||||
> very atmospheric forum about black metal - <a href="https://www.lycanthropia.net/" target="_blank">lycanthropia</a><br/>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
{{ end }}
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
<main>
|
||||
<div>
|
||||
{{ .data }}
|
||||
<p>
|
||||
<code>create time: {{ .modTimestamp }}</code>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
{{ template "post_ajax" . }}
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
{{ template "post_ajax" . }}
|
||||
|
||||
{{ define "post_ajax" }}
|
||||
<main>
|
||||
<div>
|
||||
{{ .data }}
|
||||
<p>
|
||||
<code>create time: {{ .modTimestamp }}</code>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
{{ end }}
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
<main>
|
||||
<div>
|
||||
<p>
|
||||
<code>posts sorted by create time</code>
|
||||
</p>
|
||||
</div>
|
||||
{{ range $ind, $post := .posts }}
|
||||
<div>
|
||||
<p>
|
||||
{{ $post.Preview }}
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ $post.Link }}">read more</a>
|
||||
</p>
|
||||
<p>
|
||||
<code>create time: {{ $post.Timestamp }}</code>
|
||||
</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="pagi">{{ .pagi }}</div>
|
||||
</main>
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{ template "head" . }}
|
||||
<body>
|
||||
{{ template "header" . }}
|
||||
{{ template "posts_ajax" . }}
|
||||
{{ template "footer" . }}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,41 @@
|
|||
{{ template "posts_ajax" . }}
|
||||
|
||||
{{ define "posts_ajax" }}
|
||||
<main>
|
||||
<div>
|
||||
<p>
|
||||
<code>posts sorted by create time</code>
|
||||
</p>
|
||||
</div>
|
||||
{{ range $ind, $post := .posts }}
|
||||
<div>
|
||||
<p>
|
||||
{{ $post.Preview }}
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{ $post.Link }}"
|
||||
hx-get="{{ $post.Link }}?ajax=true"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="{{ $post.Link }}">read more</a>
|
||||
</p>
|
||||
<p>
|
||||
<code>create time: {{ $post.Timestamp }}</code>
|
||||
</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="pagi">
|
||||
<a href="/posts/{{ .prevPageNumber }}"
|
||||
hx-get="/posts/{{ .prevPageNumber }}?ajax=true"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="/posts/{{ .prevPageNumber }}"><-</a>
|
||||
{{ .pageNumberInc }}/{{ .pagesCount }}
|
||||
<a href="/posts/{{ .nextPageNumber }}"
|
||||
hx-get="/posts/{{ .nextPageNumber }}?ajax=true"
|
||||
hx-target="main"
|
||||
hx-swap="outerHTML"
|
||||
hx-push-url="/posts/{{ .nextPageNumber }}">-></a>
|
||||
</div>
|
||||
</main>
|
||||
{{ end }}
|
Loading…
Reference in New Issue