Add categories feature #3
|
|
@ -10,21 +10,7 @@ $container-max-widths: (
|
|||
|
||||
@import "bootstrap/scss/bootstrap.scss";
|
||||
|
||||
// Local classes
|
||||
|
||||
.post-form {
|
||||
display: grid;
|
||||
grid-template-rows: min-content auto min-content;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.post-form textarea {
|
||||
height: 100%;
|
||||
}
|
||||
// Post list
|
||||
|
||||
.postlist .post img {
|
||||
max-width: 300px;
|
||||
|
|
@ -32,6 +18,49 @@ $container-max-widths: (
|
|||
max-height: 300px;
|
||||
}
|
||||
|
||||
.postlist .post-date {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
// Post form
|
||||
|
||||
// Post edit page styling
|
||||
.post-edit-page {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.post-edit-page main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.post-edit-page .post-form {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.post-edit-page .post-form .row {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.post-edit-page .post-form .col-md-9 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.post-edit-page .post-form textarea {
|
||||
flex: 1;
|
||||
resize: vertical;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.show-upload figure img {
|
||||
max-width: 100vw;
|
||||
height: auto;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ func (ph PostsHandler) New(c fiber.Ctx) error {
|
|||
"post": p,
|
||||
"categories": cats,
|
||||
"selectedCategories": map[int64]bool{},
|
||||
"bodyClass": "post-edit-page",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +94,7 @@ func (ph PostsHandler) Edit(c fiber.Ctx) error {
|
|||
"post": post,
|
||||
"categories": cats,
|
||||
"selectedCategories": selectedCategories,
|
||||
"bodyClass": "post-edit-page",
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,10 +176,11 @@ func (b *Builder) renderFeeds(ctx buildContext, postIter iter.Seq[models.Maybe[*
|
|||
}
|
||||
|
||||
feed.Items = append(feed.Items, &feedhub.Item{
|
||||
Id: filepath.Join(b.site.BaseURL, post.GUID),
|
||||
Title: postTitle,
|
||||
Link: &feedhub.Link{Href: renderedPost.PostURL},
|
||||
Content: string(renderedPost.HTML),
|
||||
Id: filepath.Join(b.site.BaseURL, post.GUID),
|
||||
Title: postTitle,
|
||||
Link: &feedhub.Link{Href: renderedPost.PostURL},
|
||||
Content: string(renderedPost.HTML),
|
||||
// TO FIX: Why the heck does this only include the first category?
|
||||
Category: catName,
|
||||
// TO FIX: Created should be first published
|
||||
Created: post.PublishedAt,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<main class="container">
|
||||
<div class="my-4">
|
||||
<h4>{{ if .isNew }}New Category{{ else }}Edit Category{{ end }}</h4>
|
||||
<h5>{{ if .isNew }}New Category{{ else }}Edit Category{{ end }}</h5>
|
||||
</div>
|
||||
|
||||
{{ if .isNew }}
|
||||
|
|
@ -10,27 +10,27 @@
|
|||
{{ end }}
|
||||
<input type="hidden" name="guid" value="{{ .category.GUID }}">
|
||||
<div class="row mb-3">
|
||||
<label for="catName" class="col-sm-2 col-form-label">Name</label>
|
||||
<label for="catName" class="col-sm-3 col-form-label text-end">Name</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="catName" name="name" value="{{ .category.Name }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="catSlug" class="col-sm-2 col-form-label">Slug</label>
|
||||
<label for="catSlug" class="col-sm-3 col-form-label text-end">Slug</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="catSlug" name="slug" value="{{ .category.Slug }}">
|
||||
<div class="form-text">Auto-generated from name if left blank.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="catDesc" class="col-sm-2 col-form-label">Description</label>
|
||||
<label for="catDesc" class="col-sm-3 col-form-label text-end">Description</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea class="form-control" id="catDesc" name="description" rows="5">{{ .category.Description }}</textarea>
|
||||
<div class="form-text">Markdown supported. Displayed on the category archive page.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-3"></div>
|
||||
<div class="col-sm-9">
|
||||
<button type="submit" class="btn btn-primary">{{ if .isNew }}Create{{ else }}Save{{ end }}</button>
|
||||
{{ if not .isNew }}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,30 @@
|
|||
<main class="container">
|
||||
<div class="my-4 d-flex justify-content-between align-items-baseline">
|
||||
<h4>Categories</h4>
|
||||
<div>
|
||||
<a href="/sites/{{ .site.ID }}/categories/new" class="btn btn-success">New Category</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Slug</th>
|
||||
<th>Posts</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range .categories }}
|
||||
{{ range .categories }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Slug</th>
|
||||
<th>Posts</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="/sites/{{ $.site.ID }}/categories/{{ .ID }}">{{ .Name }}</a></td>
|
||||
<td><code>{{ .Slug }}</code></td>
|
||||
<td>{{ .PostCount }}</td>
|
||||
<td>
|
||||
<a href="/sites/{{ $.site.ID }}/categories/{{ .ID }}" class="btn btn-outline-secondary btn-sm">Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{ else }}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted py-4">No categories yet.</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
{{ else }}
|
||||
<div class="h4 m-3 text-center">
|
||||
<div class="position-absolute top-50 start-50 translate-middle">📚<br>No categories yet.</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<link rel="stylesheet" href="/static/assets/main.css">
|
||||
<script src="/static/assets/main.js" type="module"></script>
|
||||
</head>
|
||||
<body class="min-vh-100 d-flex flex-column">
|
||||
<body class="d-flex flex-column {{.bodyClass}}">
|
||||
{{ template "_common/nav" . }}
|
||||
|
||||
{{ embed }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{{ $isPublished := ne .post.State 1 }}
|
||||
<main class="flex-grow-1 position-relative">
|
||||
<form action="/sites/{{.site.ID}}/posts" method="post" class="container-fluid post-form p-2"
|
||||
<form action="/sites/{{.site.ID}}/posts" method="post" class="container-fluid post-form py-2"
|
||||
data-controller="postedit"
|
||||
data-action="keydown.meta+s->postedit#save keydown.meta+enter->postedit#publish"
|
||||
data-postedit-save-action-value="{{ if $isPublished }}Update{{ else }}Save Draft{{ end }}">
|
||||
|
|
@ -10,9 +10,7 @@
|
|||
<div class="mb-2">
|
||||
<input type="text" name="title" class="form-control" placeholder="Title" value="{{ .post.Title }}">
|
||||
</div>
|
||||
<div>
|
||||
<textarea data-postedit-target="bodyTextEdit" name="body" class="form-control" rows="3">{{.post.Body}}</textarea>
|
||||
</div>
|
||||
<textarea data-postedit-target="bodyTextEdit" name="body" class="form-control flex-grow-1" rows="3">{{.post.Body}}</textarea>
|
||||
<div>
|
||||
{{ if $isPublished }}
|
||||
<input type="submit" name="action" class="btn btn-primary mt-2" value="Update">
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@
|
|||
|
||||
<div class="mb-3 d-flex align-items-center flex-wrap gap-1">
|
||||
{{ if eq $p.State 1 }}
|
||||
<span class="text-muted">{{ $.user.FormatTime $p.UpdatedAt }}</span> <span class="ms-3 badge text-primary-emphasis bg-primary-subtle border border-primary-subtle">Draft</span>
|
||||
<span class="text-muted post-date">{{ $.user.FormatTime $p.UpdatedAt }}</span> <span class="ms-3 badge text-primary-emphasis bg-primary-subtle border border-primary-subtle">Draft</span>
|
||||
{{ else }}
|
||||
<span class="text-muted">{{ $.user.FormatTime $p.PublishedAt }}</span>
|
||||
{{ end }}
|
||||
{{ range $p.Categories }}
|
||||
<span class="ms-1 badge bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle">{{ .Name }}</span>
|
||||
<span class="text-muted post-date">{{ $.user.FormatTime $p.PublishedAt }}</span>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue