v2 #43
|
@ -34,5 +34,16 @@ func (s *EntryService) FindAllByType(types *[]string) ([]model.Entry, error) {
|
|||
}
|
||||
|
||||
func (s *EntryService) FindAll() ([]model.Entry, error) {
|
||||
return s.EntryRepository.FindAll(nil)
|
||||
entries, err := s.EntryRepository.FindAll(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// filter unpublished entries
|
||||
publishedEntries := make([]model.Entry, 0)
|
||||
for _, entry := range entries {
|
||||
if entry.PublishedAt() != nil && !entry.PublishedAt().IsZero() {
|
||||
publishedEntries = append(publishedEntries, entry)
|
||||
}
|
||||
}
|
||||
return publishedEntries, nil
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100mm"
|
||||
height="100mm"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
||||
sodipodi:docname="owl.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="101.5,113.98198"
|
||||
end_point="101.5,177.55836"
|
||||
center_point="101.5,145.77017"
|
||||
id="path-effect4762"
|
||||
is_visible="true"
|
||||
mode="free"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="true"
|
||||
oposite_fuse="false" />
|
||||
<inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="101.6,77.962793"
|
||||
end_point="101.6,178.13471"
|
||||
center_point="101.6,128.04875"
|
||||
id="path-effect4630"
|
||||
is_visible="true"
|
||||
mode="free"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="true"
|
||||
oposite_fuse="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="-5.4384962"
|
||||
inkscape:cy="476.07169"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer5"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1391"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Body"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(0,-197)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="Front"
|
||||
transform="translate(0,-197)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="Ref"
|
||||
style="display:inline"
|
||||
transform="translate(0,-197)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="Feet"
|
||||
transform="translate(0,-197)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Nose"
|
||||
transform="translate(0,-197)" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Eyes"
|
||||
transform="translate(0,-197)">
|
||||
<path
|
||||
style="display:inline;opacity:1;fill:#686560;fill-opacity:1;stroke:#000000;stroke-width:1.46500003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 72.665922,98.468004 c -3.804657,-4.064063 -8.937651,-7.726186 -7.559523,-20.505208 1.511903,2.173362 6.898064,8.031993 12.095236,8.031993 7.291682,0 22.616673,0.08369 24.398365,0.09355 1.78169,-0.0099 17.10668,-0.09355 24.39836,-0.09355 5.19718,0 10.58334,-5.858631 12.09524,-8.031993 1.37813,12.779022 -3.75487,16.441145 -7.55952,20.505208 0,0 4.84169,14.668796 9.88119,20.229646 10.76577,11.87955 9.28012,38.96737 -13.7775,54.51257 -4.9083,3.30912 -14.73063,5.13452 -25.03777,4.90519 -10.307138,0.22933 -20.129467,-1.59607 -25.037771,-4.90519 -23.057616,-15.5452 -24.543272,-42.63302 -13.777496,-54.51257 5.039494,-5.56085 9.881189,-20.229646 9.881189,-20.229646 z"
|
||||
id="path46"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccssc"
|
||||
inkscape:path-effect="#path-effect4630"
|
||||
inkscape:original-d="m 72.665922,98.468004 c -3.804657,-4.064063 -8.937651,-7.726186 -7.559523,-20.505208 1.511903,2.173362 6.898064,8.031993 12.095236,8.031993 7.748513,0 24.568455,0.0945 24.568455,0.0945 9.17095,40.967981 -1.73329,86.382581 24.08866,86.819411 -14.73188,7.45015 -40.288984,6.3743 -49.296521,0.30152 -23.057616,-15.5452 -24.543272,-42.63302 -13.777496,-54.51257 5.039494,-5.56085 9.881189,-20.229646 9.881189,-20.229646 z"
|
||||
transform="matrix(0.89013051,0,0,0.89013051,-40.43726,131.70004)" />
|
||||
<path
|
||||
style="display:inline;fill:#fbe9c4;fill-opacity:1;stroke:#262626;stroke-width:4.06500006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 74.568197,129.95654 c -1.207452,8.188 -1.187282,34.70878 17.572973,44.03265 3.623482,1.36045 5.80487,3.13501 9.35883,3.62684 3.55396,-0.49183 5.73535,-2.26639 9.35883,-3.62684 18.76025,-9.32387 18.78042,-35.84465 17.57297,-44.03265 C 126.73222,117.4929 107.35585,115.8851 101.5,115.68436 95.644152,115.8851 76.267784,117.4929 74.568197,129.95654 Z"
|
||||
id="path4760"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccscc"
|
||||
inkscape:path-effect="#path-effect4762"
|
||||
inkscape:original-d="m 74.568197,129.95654 c -1.207452,8.188 -1.187282,34.70878 17.572973,44.03265 4.717147,1.77107 6.990299,4.24396 13.02939,3.67496 5.2517,-4.28707 -4.51571,-38.74118 3.27405,-50.98166 11.76071,-18.48023 -5.27857,-11.02487 -5.27857,-11.02487 0,0 -26.593322,-0.4009 -28.597843,14.29892 z"
|
||||
transform="matrix(0.89013051,0,0,0.89013051,-40.43726,131.70004)" />
|
||||
<rect
|
||||
style="opacity:1;fill:#674808;fill-opacity:1;stroke:#efc48c;stroke-width:2.72825003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4767"
|
||||
width="23.046696"
|
||||
height="2.0186887"
|
||||
x="39.805622"
|
||||
y="258.96619" />
|
||||
<rect
|
||||
style="opacity:1;fill:#674808;fill-opacity:1;stroke:#efc48c;stroke-width:2.72825003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4767-7"
|
||||
width="23.046698"
|
||||
height="2.0186887"
|
||||
x="39.805622"
|
||||
y="266.51617" />
|
||||
<rect
|
||||
style="opacity:1;fill:#674808;fill-opacity:1;stroke:#efc48c;stroke-width:2.72825003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect4767-7-0"
|
||||
width="23.046698"
|
||||
height="2.0186887"
|
||||
x="39.80563"
|
||||
y="274.1886" />
|
||||
<path
|
||||
style="display:inline;opacity:1;fill:#f1cd6b;fill-opacity:1;stroke:#000000;stroke-width:1.21502817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 37.113903,280.91958 a 11.943909,11.943909 0 0 0 -11.943581,11.94359 h 23.88762 A 11.943909,11.943909 0 0 0 37.113903,280.91958 Z"
|
||||
id="path4732"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="display:inline;opacity:1;fill:#f1cd6b;fill-opacity:1;stroke:#000000;stroke-width:1.21502817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 62.767977,281.00369 A 11.943909,11.943909 0 0 0 50.824392,292.94728 H 74.712015 A 11.943909,11.943909 0 0 0 62.767977,281.00369 Z"
|
||||
id="path4732-2" />
|
||||
<path
|
||||
style="fill:#dd9829;fill-opacity:1;stroke:#000000;stroke-width:1.21502817;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 45.440938,246.0794 c 0,0 2.139571,9.72892 5.947619,9.7541 3.839356,0.0254 6.126056,-9.7541 6.126056,-9.7541 l -6.140761,-8.69398 z"
|
||||
id="path4721"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="caccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#fedf89;fill-opacity:1;stroke:#000000;stroke-width:1.95828712;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 34.506691,216.30236 a 18.692076,18.692076 0 0 0 -18.692058,18.69205 18.692076,18.692076 0 0 0 18.692058,18.69206 18.692076,18.692076 0 0 0 16.928008,-10.81661 18.692078,18.692078 0 0 0 16.968945,10.90079 18.692078,18.692078 0 0 0 18.69206,-18.69206 18.692078,18.692078 0 0 0 -18.69206,-18.69252 18.692078,18.692078 0 0 0 -16.929847,10.81983 18.692076,18.692076 0 0 0 -16.967106,-10.90354 z"
|
||||
id="path4607"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:#fffefc;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 64.955116,221.31207 a 13.794374,13.429993 0 0 0 -13.301924,9.88009 13.794374,13.429993 0 0 0 -13.277543,-9.79636 13.794374,13.429993 0 0 0 -13.794111,13.43025 13.794374,13.429993 0 0 0 13.794111,13.4298 13.794374,13.429993 0 0 0 13.301003,-9.92837 13.794374,13.429993 0 0 0 13.278464,9.8442 13.794374,13.429993 0 0 0 13.794572,-13.4298 13.794374,13.429993 0 0 0 -13.794572,-13.42981 z"
|
||||
id="path4609"
|
||||
inkscape:connector-curvature="0" />
|
||||
<ellipse
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4611"
|
||||
cx="40.394402"
|
||||
cy="235.28864"
|
||||
rx="8.9999876"
|
||||
ry="8.8738194" />
|
||||
<circle
|
||||
style="opacity:1;fill:#fffefc;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4609-3"
|
||||
cy="230.89021"
|
||||
cx="35.68087"
|
||||
r="5.6899729" />
|
||||
<ellipse
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4611-9"
|
||||
cx="-63.020538"
|
||||
cy="235.37274"
|
||||
rx="8.9999876"
|
||||
ry="8.8738194"
|
||||
transform="scale(-1,1)" />
|
||||
<circle
|
||||
style="opacity:1;fill:#fffefc;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4609-3-1"
|
||||
cx="-67.734055"
|
||||
cy="230.97433"
|
||||
transform="scale(-1,1)"
|
||||
r="5.0387244" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -3,4 +3,6 @@ package model
|
|||
type Author struct {
|
||||
Name string
|
||||
PasswordHash string
|
||||
FullUrl string
|
||||
AvatarUrl string
|
||||
}
|
||||
|
|
|
@ -4,15 +4,18 @@
|
|||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>{{template "title" .}} - Owl Blog</title>
|
||||
<link rel='stylesheet' href='/static/pico.min.css'>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
Owl Blog
|
||||
<header class="container">
|
||||
<a href="/">Owl Blog</a>
|
||||
</header>
|
||||
<main>
|
||||
<main class="container">
|
||||
{{template "main" .}}
|
||||
</main>
|
||||
<footer>Powered by <a href='https://golang.org/'>Go</a></footer>
|
||||
<footer class="container">
|
||||
Powered by <a href='https://golang.org/'>Go</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
|
@ -1,7 +1,3 @@
|
|||
<h1>
|
||||
{{.MetaData.Title}}
|
||||
</h1>
|
||||
|
||||
<img src="/media/{{.MetaData.ImageId}}">
|
||||
|
||||
{{.MetaData.Content}}
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
{{define "title"}}{{.Title}}{{end}}
|
||||
{{define "title"}}{{.Entry.Title}}{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
|
||||
{{if .Title}}
|
||||
<h1>{{.Title}}</h1>
|
||||
{{end}}
|
||||
<p>
|
||||
Published: {{.PublishedAt}}
|
||||
</p>
|
||||
<div class="h-entry">
|
||||
<hgroup>
|
||||
{{if .Entry.Title}}
|
||||
<h1 class="p-name">{{.Entry.Title}}</h1>
|
||||
{{end}}
|
||||
<small>
|
||||
<a class="u-url" href="">#</a>
|
||||
Published:
|
||||
<time class="dt-published" datetime="{{.Entry.PublishedAt}}">
|
||||
{{.Entry.PublishedAt}}
|
||||
</time>
|
||||
{{ if .Author.Name }}
|
||||
by
|
||||
<a class="p-author h-card" href="{{.Author.FullUrl}}">
|
||||
{{ if .Author.AvatarUrl }}
|
||||
<img class="u-photo u-logo" style="height: 1em;" src="{{ .Author.AvatarUrl }}" alt="{{ .Author.Config.Title }}" />
|
||||
{{ end }}
|
||||
{{.Author.Name}}
|
||||
</a>
|
||||
{{ end }}
|
||||
</small>
|
||||
</hgroup>
|
||||
|
||||
{{.Entry.Content}}
|
||||
|
||||
{{.Content}}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{{end}}
|
||||
|
|
|
@ -2,21 +2,43 @@
|
|||
|
||||
{{define "main"}}
|
||||
|
||||
{{ range . }}
|
||||
<div>
|
||||
<h2>
|
||||
<a href="/posts/{{ .ID }}">
|
||||
{{if .Title}}
|
||||
{{ .Title }}
|
||||
{{else}}
|
||||
#
|
||||
{{end}}
|
||||
</a>
|
||||
</h2>
|
||||
<p>{{ .PublishedAt }}</p>
|
||||
<div class="h-feed">
|
||||
{{ range .Entries }}
|
||||
<div class="h-entry">
|
||||
<hgroup>
|
||||
<h3>
|
||||
<a class="u-url" href="/posts/{{ .ID }}">
|
||||
{{if .Title}}
|
||||
{{ .Title }}
|
||||
{{else}}
|
||||
#
|
||||
{{end}}
|
||||
</a>
|
||||
</h3>
|
||||
<small style="font-size: 0.75em;">
|
||||
<time class="dt-published" datetime="{{ .PublishedAt }}">{{ .PublishedAt }}</time>
|
||||
</small>
|
||||
</hgroup>
|
||||
{{ .Content }}
|
||||
</div>
|
||||
<hr>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<nav class="row">
|
||||
{{ if not .FirstPage }}
|
||||
<div>
|
||||
<a href="/?page={{ .PrevPage }}">Prev</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div>Page {{.Page}}</div>
|
||||
|
||||
{{ if not .LastPage }}
|
||||
<div>
|
||||
<a href="/?page={{ .NextPage }}">Next</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
{{end}}
|
15
web/app.go
15
web/app.go
|
@ -1,12 +1,18 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net/http"
|
||||
"owl-blogs/app"
|
||||
"owl-blogs/web/middleware"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
)
|
||||
|
||||
//go:embed static/*
|
||||
var embedDirStatic embed.FS
|
||||
|
||||
type WebApp struct {
|
||||
FiberApp *fiber.App
|
||||
EntryService *app.EntryService
|
||||
|
@ -25,7 +31,7 @@ func NewWebApp(
|
|||
|
||||
indexHandler := NewIndexHandler(entryService)
|
||||
listHandler := NewListHandler(entryService)
|
||||
entryHandler := NewEntryHandler(entryService, typeRegistry)
|
||||
entryHandler := NewEntryHandler(entryService, typeRegistry, authorService)
|
||||
mediaHandler := NewMediaHandler(binService)
|
||||
rssHandler := NewRSSHandler(entryService)
|
||||
loginHandler := NewLoginHandler(authorService)
|
||||
|
@ -43,7 +49,12 @@ func NewWebApp(
|
|||
editor.Get("/:editor/", editorHandler.HandleGet)
|
||||
editor.Post("/:editor/", editorHandler.HandlePost)
|
||||
|
||||
// app.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||
// app.Static("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||
app.Use("/static", filesystem.New(filesystem.Config{
|
||||
Root: http.FS(embedDirStatic),
|
||||
PathPrefix: "static",
|
||||
Browse: false,
|
||||
}))
|
||||
app.Get("/", indexHandler.Handle)
|
||||
app.Get("/lists/:list/", listHandler.Handle)
|
||||
// Media
|
||||
|
|
|
@ -2,18 +2,25 @@ package web
|
|||
|
||||
import (
|
||||
"owl-blogs/app"
|
||||
"owl-blogs/domain/model"
|
||||
"owl-blogs/render"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type EntryHandler struct {
|
||||
entrySvc *app.EntryService
|
||||
registry *app.EntryTypeRegistry
|
||||
entrySvc *app.EntryService
|
||||
authorSvc *app.AuthorService
|
||||
registry *app.EntryTypeRegistry
|
||||
}
|
||||
|
||||
func NewEntryHandler(entryService *app.EntryService, registry *app.EntryTypeRegistry) *EntryHandler {
|
||||
return &EntryHandler{entrySvc: entryService, registry: registry}
|
||||
type entryData struct {
|
||||
Entry model.Entry
|
||||
Author *model.Author
|
||||
}
|
||||
|
||||
func NewEntryHandler(entryService *app.EntryService, registry *app.EntryTypeRegistry, authorService *app.AuthorService) *EntryHandler {
|
||||
return &EntryHandler{entrySvc: entryService, authorSvc: authorService, registry: registry}
|
||||
}
|
||||
|
||||
func (h *EntryHandler) Handle(c *fiber.Ctx) error {
|
||||
|
@ -25,5 +32,10 @@ func (h *EntryHandler) Handle(c *fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return render.RenderTemplateWithBase(c, "views/entry", entry)
|
||||
author, err := h.authorSvc.FindByName("h4kor")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return render.RenderTemplateWithBase(c, "views/entry", entryData{Entry: entry, Author: author})
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ package web
|
|||
|
||||
import (
|
||||
"owl-blogs/app"
|
||||
"owl-blogs/domain/model"
|
||||
"owl-blogs/render"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
@ -16,19 +18,60 @@ func NewIndexHandler(entryService *app.EntryService) *IndexHandler {
|
|||
return &IndexHandler{entrySvc: entryService}
|
||||
}
|
||||
|
||||
type indexRenderData struct {
|
||||
Entries []model.Entry
|
||||
Page int
|
||||
NextPage int
|
||||
PrevPage int
|
||||
FirstPage bool
|
||||
LastPage bool
|
||||
}
|
||||
|
||||
func (h *IndexHandler) Handle(c *fiber.Ctx) error {
|
||||
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||
entries, err := h.entrySvc.FindAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// sort entries by date descending
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
return entries[i].PublishedAt().After(*entries[j].PublishedAt())
|
||||
})
|
||||
|
||||
// pagination
|
||||
page := c.Query("page")
|
||||
if page == "" {
|
||||
page = "1"
|
||||
}
|
||||
pageNum, err := strconv.Atoi(page)
|
||||
if err != nil {
|
||||
pageNum = 1
|
||||
}
|
||||
limit := 10
|
||||
offset := (pageNum - 1) * limit
|
||||
lastPage := false
|
||||
if offset > len(entries) {
|
||||
offset = len(entries)
|
||||
lastPage = true
|
||||
}
|
||||
if offset+limit > len(entries) {
|
||||
limit = len(entries) - offset
|
||||
lastPage = true
|
||||
}
|
||||
entries = entries[offset : offset+limit]
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return render.RenderTemplateWithBase(c, "views/index", entries)
|
||||
return render.RenderTemplateWithBase(c, "views/index", indexRenderData{
|
||||
Entries: entries,
|
||||
Page: pageNum,
|
||||
NextPage: pageNum + 1,
|
||||
PrevPage: pageNum - 1,
|
||||
FirstPage: pageNum == 1,
|
||||
LastPage: lastPage,
|
||||
})
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue