diff --git a/assets/js/controllers/pagelist.js b/assets/js/controllers/pagelist.js deleted file mode 100644 index 7da6872..0000000 --- a/assets/js/controllers/pagelist.js +++ /dev/null @@ -1,63 +0,0 @@ -import { Controller } from "@hotwired/stimulus" -import { showToast } from "../services/toast"; - -export default class PagelistController extends Controller { - static values = { - siteId: Number, - }; - - static targets = ["list"]; - - dragStart(ev) { - this.draggedRow = ev.currentTarget; - ev.currentTarget.classList.add("opacity-50"); - ev.dataTransfer.effectAllowed = "move"; - } - - dragOver(ev) { - ev.preventDefault(); - ev.dataTransfer.dropEffect = "move"; - } - - drop(ev) { - ev.preventDefault(); - const targetRow = ev.currentTarget; - if (this.draggedRow && this.draggedRow !== targetRow) { - const rows = [...this.listTarget.children]; - const draggedIdx = rows.indexOf(this.draggedRow); - const targetIdx = rows.indexOf(targetRow); - if (draggedIdx < targetIdx) { - targetRow.after(this.draggedRow); - } else { - targetRow.before(this.draggedRow); - } - this.saveOrder(); - } - } - - dragEnd(ev) { - ev.currentTarget.classList.remove("opacity-50"); - this.draggedRow = null; - } - - async saveOrder() { - const rows = [...this.listTarget.children]; - const pageIds = rows.map(row => parseInt(row.dataset.pageId, 10)); - - try { - await fetch(`/sites/${this.siteIdValue}/pages/reorder`, { - method: "POST", - headers: { - "Content-Type": "application/json", - "Accept": "application/json", - }, - body: JSON.stringify({ page_ids: pageIds }), - }); - } catch (error) { - showToast({ - title: "Error", - body: "Failed to reorder pages.", - }); - } - } -} diff --git a/assets/js/main.js b/assets/js/main.js index 28451fb..d76c353 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -7,7 +7,6 @@ import LogoutController from "./controllers/logout"; import FirstRunController from "./controllers/firstrun"; import UploadController from "./controllers/upload"; import ShowUploadController from "./controllers/show_upload"; -import PagelistController from "./controllers/pagelist"; window.Stimulus = Application.start() Stimulus.register("toast", ToastController); @@ -16,5 +15,4 @@ Stimulus.register("postedit", PosteditController); Stimulus.register("logout", LogoutController); Stimulus.register("first-run", FirstRunController); Stimulus.register("upload", UploadController); -Stimulus.register("show-upload", ShowUploadController); -Stimulus.register("pagelist", PagelistController); \ No newline at end of file +Stimulus.register("show-upload", ShowUploadController); \ No newline at end of file diff --git a/cmds/server.go b/cmds/server.go index 89310bd..56517e7 100644 --- a/cmds/server.go +++ b/cmds/server.go @@ -113,7 +113,6 @@ Starting weiro without any arguments will start the server. uh := handlers.UploadsHandler{UploadsService: svcs.Uploads} ssh := handlers.SiteSettingsHandler{SiteService: svcs.Sites} ch := handlers.CategoriesHandler{CategoryService: svcs.Categories} - pgh := handlers.PagesHandler{PageService: svcs.Pages} app.Get("/login", lh.Login) app.Post("/login", lh.DoLogin) @@ -150,14 +149,6 @@ Starting weiro without any arguments will start the server. siteGroup.Post("/categories/:categoryID", ch.Update) siteGroup.Post("/categories/:categoryID/delete", ch.Delete) - siteGroup.Get("/pages", pgh.Index) - siteGroup.Get("/pages/new", pgh.New) - siteGroup.Get("/pages/:pageID", pgh.Edit) - siteGroup.Post("/pages", pgh.Create) - siteGroup.Post("/pages/reorder", pgh.Reorder) - siteGroup.Post("/pages/:pageID", pgh.Update) - siteGroup.Post("/pages/:pageID/delete", pgh.Delete) - app.Get("/", middleware.OptionalUser(svcs.Auth), ih.Index) app.Get("/first-run", ih.FirstRun) app.Post("/first-run", ih.FirstRunSubmit) diff --git a/handlers/pages.go b/handlers/pages.go deleted file mode 100644 index abefb41..0000000 --- a/handlers/pages.go +++ /dev/null @@ -1,118 +0,0 @@ -package handlers - -import ( - "fmt" - "strconv" - - "github.com/gofiber/fiber/v3" - "lmika.dev/lmika/weiro/models" - "lmika.dev/lmika/weiro/services/pages" -) - -type PagesHandler struct { - PageService *pages.Service -} - -func (ph PagesHandler) Index(c fiber.Ctx) error { - pagesList, err := ph.PageService.ListPages(c.Context()) - if err != nil { - return err - } - - return c.Render("pages/index", fiber.Map{ - "pages": pagesList, - }) -} - -func (ph PagesHandler) New(c fiber.Ctx) error { - page := models.Page{ - GUID: models.NewNanoID(), - } - return c.Render("pages/edit", fiber.Map{ - "page": page, - "isNew": true, - "bodyClass": "post-edit-page", - }) -} - -func (ph PagesHandler) Edit(c fiber.Ctx) error { - pageID, err := strconv.ParseInt(c.Params("pageID"), 10, 64) - if err != nil { - return fiber.ErrBadRequest - } - - page, err := ph.PageService.GetPage(c.Context(), pageID) - if err != nil { - return err - } - - return c.Render("pages/edit", fiber.Map{ - "page": page, - "isNew": false, - "bodyClass": "post-edit-page", - }) -} - -func (ph PagesHandler) Create(c fiber.Ctx) error { - var req pages.CreatePageParams - if err := c.Bind().Body(&req); err != nil { - return err - } - - _, err := ph.PageService.CreatePage(c.Context(), req) - if err != nil { - return err - } - - site := models.MustGetSite(c.Context()) - return c.Redirect().To(fmt.Sprintf("/sites/%v/pages", site.ID)) -} - -func (ph PagesHandler) Update(c fiber.Ctx) error { - pageID, err := strconv.ParseInt(c.Params("pageID"), 10, 64) - if err != nil { - return fiber.ErrBadRequest - } - - var req pages.CreatePageParams - if err := c.Bind().Body(&req); err != nil { - return err - } - - _, err = ph.PageService.UpdatePage(c.Context(), pageID, req) - if err != nil { - return err - } - - site := models.MustGetSite(c.Context()) - return c.Redirect().To(fmt.Sprintf("/sites/%v/pages", site.ID)) -} - -func (ph PagesHandler) Delete(c fiber.Ctx) error { - pageID, err := strconv.ParseInt(c.Params("pageID"), 10, 64) - if err != nil { - return fiber.ErrBadRequest - } - - if err := ph.PageService.DeletePage(c.Context(), pageID); err != nil { - return err - } - - site := models.MustGetSite(c.Context()) - return c.Redirect().To(fmt.Sprintf("/sites/%v/pages", site.ID)) -} - -func (ph PagesHandler) Reorder(c fiber.Ctx) error { - var req struct { - PageIDs []int64 `json:"page_ids"` - } - if err := c.Bind().Body(&req); err != nil { - return err - } - - if err := ph.PageService.ReorderPages(c.Context(), req.PageIDs); err != nil { - return err - } - - return c.JSON(fiber.Map{"ok": true}) -} diff --git a/layouts/simplecss/templates/categories_single.html b/layouts/simplecss/templates/categories_single.html index 133ad8d..e9e7116 100644 --- a/layouts/simplecss/templates/categories_single.html +++ b/layouts/simplecss/templates/categories_single.html @@ -11,7 +11,7 @@ {{ end }} {{ if or .PrevURL .NextURL }} {{ end }} diff --git a/layouts/simplecss/templates/pages_single.html b/layouts/simplecss/templates/pages_single.html deleted file mode 100644 index 6883c3e..0000000 --- a/layouts/simplecss/templates/pages_single.html +++ /dev/null @@ -1,2 +0,0 @@ -{{ if .Page.Title }}

{{ .Page.Title }}

{{ end }} -{{ .HTML }} diff --git a/layouts/simplecss/templates/posts_list.html b/layouts/simplecss/templates/posts_list.html index 6a71533..6a2eca6 100644 --- a/layouts/simplecss/templates/posts_list.html +++ b/layouts/simplecss/templates/posts_list.html @@ -8,7 +8,7 @@ {{ end }} {{ if or .PrevURL .NextURL }} {{ end }} diff --git a/models/errors.go b/models/errors.go index 3efadbc..eda780c 100644 --- a/models/errors.go +++ b/models/errors.go @@ -7,4 +7,4 @@ var PermissionError = errors.New("permission denied") var NotFoundError = errors.New("not found") var SiteRequiredError = errors.New("site required") var DeleteDebounceError = errors.New("permanent delete too soon, try again in a few seconds") -var SlugConflictError = errors.New("a record with this slug already exists") +var SlugConflictError = errors.New("a category with this slug already exists") diff --git a/models/pages.go b/models/pages.go deleted file mode 100644 index 1022120..0000000 --- a/models/pages.go +++ /dev/null @@ -1,45 +0,0 @@ -package models - -import ( - "strings" - "time" - "unicode" -) - -const ( - PageTypeNormal = 0 -) - -type Page struct { - ID int64 `json:"id"` - SiteID int64 `json:"site_id"` - GUID string `json:"guid"` - Title string `json:"title"` - Slug string `json:"slug"` - Body string `json:"body"` - PageType int `json:"page_type"` - ShowInNav bool `json:"show_in_nav"` - SortOrder int `json:"sort_order"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} - -// GeneratePageSlug creates a URL-safe slug from a page title. -// e.g. "About Me" -> "about-me" -func GeneratePageSlug(title string) string { - var sb strings.Builder - prevDash := false - for _, c := range strings.TrimSpace(title) { - if unicode.IsLetter(c) || unicode.IsNumber(c) { - sb.WriteRune(unicode.ToLower(c)) - prevDash = false - } else if unicode.IsSpace(c) || c == '-' || c == '_' { - if !prevDash && sb.Len() > 0 { - sb.WriteRune('-') - prevDash = true - } - } - } - result := sb.String() - return strings.TrimRight(result, "-") -} diff --git a/models/pages_test.go b/models/pages_test.go deleted file mode 100644 index 831b31f..0000000 --- a/models/pages_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package models_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "lmika.dev/lmika/weiro/models" -) - -func TestGeneratePageSlug(t *testing.T) { - tests := []struct { - title string - want string - }{ - {"About Me", "about-me"}, - {" Contact Us ", "contact-us"}, - {"Hello---World", "hello-world"}, - {"FAQ", "faq"}, - {"", ""}, - } - for _, tt := range tests { - t.Run(tt.title, func(t *testing.T) { - assert.Equal(t, tt.want, models.GeneratePageSlug(tt.title)) - }) - } -} diff --git a/models/pubmodel/sites.go b/models/pubmodel/sites.go index 38ba614..a8862c4 100644 --- a/models/pubmodel/sites.go +++ b/models/pubmodel/sites.go @@ -18,5 +18,4 @@ type Site struct { Categories []models.CategoryWithCount PostIterByCategory func(ctx context.Context, categoryID int64) iter.Seq[models.Maybe[*models.Post]] CategoriesOfPost func(ctx context.Context, postID int64) ([]*models.Category, error) - Pages []*models.Page } diff --git a/providers/db/gen/sqlgen/models.go b/providers/db/gen/sqlgen/models.go index 3df1193..ae58594 100644 --- a/providers/db/gen/sqlgen/models.go +++ b/providers/db/gen/sqlgen/models.go @@ -15,20 +15,6 @@ type Category struct { UpdatedAt int64 } -type Page struct { - ID int64 - SiteID int64 - Guid string - Title string - Slug string - Body string - PageType int64 - ShowInNav int64 - SortOrder int64 - CreatedAt int64 - UpdatedAt int64 -} - type PendingUpload struct { ID int64 SiteID int64 diff --git a/providers/db/gen/sqlgen/pages.sql.go b/providers/db/gen/sqlgen/pages.sql.go deleted file mode 100644 index 1d53291..0000000 --- a/providers/db/gen/sqlgen/pages.sql.go +++ /dev/null @@ -1,219 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.28.0 -// source: pages.sql - -package sqlgen - -import ( - "context" -) - -const deletePage = `-- name: DeletePage :exec -DELETE FROM pages WHERE id = ? -` - -func (q *Queries) DeletePage(ctx context.Context, id int64) error { - _, err := q.db.ExecContext(ctx, deletePage, id) - return err -} - -const insertPage = `-- name: InsertPage :one -INSERT INTO pages ( - site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at -) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) -RETURNING id -` - -type InsertPageParams struct { - SiteID int64 - Guid string - Title string - Slug string - Body string - PageType int64 - ShowInNav int64 - SortOrder int64 - CreatedAt int64 - UpdatedAt int64 -} - -func (q *Queries) InsertPage(ctx context.Context, arg InsertPageParams) (int64, error) { - row := q.db.QueryRowContext(ctx, insertPage, - arg.SiteID, - arg.Guid, - arg.Title, - arg.Slug, - arg.Body, - arg.PageType, - arg.ShowInNav, - arg.SortOrder, - arg.CreatedAt, - arg.UpdatedAt, - ) - var id int64 - err := row.Scan(&id) - return id, err -} - -const selectPage = `-- name: SelectPage :one -SELECT id, site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at FROM pages WHERE id = ? LIMIT 1 -` - -func (q *Queries) SelectPage(ctx context.Context, id int64) (Page, error) { - row := q.db.QueryRowContext(ctx, selectPage, id) - var i Page - err := row.Scan( - &i.ID, - &i.SiteID, - &i.Guid, - &i.Title, - &i.Slug, - &i.Body, - &i.PageType, - &i.ShowInNav, - &i.SortOrder, - &i.CreatedAt, - &i.UpdatedAt, - ) - return i, err -} - -const selectPageByGUID = `-- name: SelectPageByGUID :one -SELECT id, site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at FROM pages WHERE guid = ? LIMIT 1 -` - -func (q *Queries) SelectPageByGUID(ctx context.Context, guid string) (Page, error) { - row := q.db.QueryRowContext(ctx, selectPageByGUID, guid) - var i Page - err := row.Scan( - &i.ID, - &i.SiteID, - &i.Guid, - &i.Title, - &i.Slug, - &i.Body, - &i.PageType, - &i.ShowInNav, - &i.SortOrder, - &i.CreatedAt, - &i.UpdatedAt, - ) - return i, err -} - -const selectPageBySlugAndSite = `-- name: SelectPageBySlugAndSite :one -SELECT id, site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at FROM pages WHERE site_id = ? AND slug = ? LIMIT 1 -` - -type SelectPageBySlugAndSiteParams struct { - SiteID int64 - Slug string -} - -func (q *Queries) SelectPageBySlugAndSite(ctx context.Context, arg SelectPageBySlugAndSiteParams) (Page, error) { - row := q.db.QueryRowContext(ctx, selectPageBySlugAndSite, arg.SiteID, arg.Slug) - var i Page - err := row.Scan( - &i.ID, - &i.SiteID, - &i.Guid, - &i.Title, - &i.Slug, - &i.Body, - &i.PageType, - &i.ShowInNav, - &i.SortOrder, - &i.CreatedAt, - &i.UpdatedAt, - ) - return i, err -} - -const selectPagesOfSite = `-- name: SelectPagesOfSite :many -SELECT id, site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at FROM pages -WHERE site_id = ? ORDER BY sort_order ASC -` - -func (q *Queries) SelectPagesOfSite(ctx context.Context, siteID int64) ([]Page, error) { - rows, err := q.db.QueryContext(ctx, selectPagesOfSite, siteID) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Page - for rows.Next() { - var i Page - if err := rows.Scan( - &i.ID, - &i.SiteID, - &i.Guid, - &i.Title, - &i.Slug, - &i.Body, - &i.PageType, - &i.ShowInNav, - &i.SortOrder, - &i.CreatedAt, - &i.UpdatedAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const updatePage = `-- name: UpdatePage :exec -UPDATE pages SET - title = ?, - slug = ?, - body = ?, - page_type = ?, - show_in_nav = ?, - updated_at = ? -WHERE id = ? -` - -type UpdatePageParams struct { - Title string - Slug string - Body string - PageType int64 - ShowInNav int64 - UpdatedAt int64 - ID int64 -} - -func (q *Queries) UpdatePage(ctx context.Context, arg UpdatePageParams) error { - _, err := q.db.ExecContext(ctx, updatePage, - arg.Title, - arg.Slug, - arg.Body, - arg.PageType, - arg.ShowInNav, - arg.UpdatedAt, - arg.ID, - ) - return err -} - -const updatePageSortOrder = `-- name: UpdatePageSortOrder :exec -UPDATE pages SET sort_order = ? WHERE id = ? -` - -type UpdatePageSortOrderParams struct { - SortOrder int64 - ID int64 -} - -func (q *Queries) UpdatePageSortOrder(ctx context.Context, arg UpdatePageSortOrderParams) error { - _, err := q.db.ExecContext(ctx, updatePageSortOrder, arg.SortOrder, arg.ID) - return err -} diff --git a/providers/db/pages.go b/providers/db/pages.go deleted file mode 100644 index 1e5b9fc..0000000 --- a/providers/db/pages.go +++ /dev/null @@ -1,115 +0,0 @@ -package db - -import ( - "context" - "time" - - "lmika.dev/lmika/weiro/models" - "lmika.dev/lmika/weiro/providers/db/gen/sqlgen" -) - -func (db *Provider) SelectPagesOfSite(ctx context.Context, siteID int64) ([]*models.Page, error) { - rows, err := db.queries.SelectPagesOfSite(ctx, siteID) - if err != nil { - return nil, err - } - pages := make([]*models.Page, len(rows)) - for i, row := range rows { - pages[i] = dbPageToPage(row) - } - return pages, nil -} - -func (db *Provider) SelectPage(ctx context.Context, id int64) (*models.Page, error) { - row, err := db.queries.SelectPage(ctx, id) - if err != nil { - return nil, err - } - return dbPageToPage(row), nil -} - -func (db *Provider) SelectPageByGUID(ctx context.Context, guid string) (*models.Page, error) { - row, err := db.queries.SelectPageByGUID(ctx, guid) - if err != nil { - return nil, err - } - return dbPageToPage(row), nil -} - -func (db *Provider) SelectPageBySlugAndSite(ctx context.Context, siteID int64, slug string) (*models.Page, error) { - row, err := db.queries.SelectPageBySlugAndSite(ctx, sqlgen.SelectPageBySlugAndSiteParams{ - SiteID: siteID, - Slug: slug, - }) - if err != nil { - return nil, err - } - return dbPageToPage(row), nil -} - -func (db *Provider) SavePage(ctx context.Context, page *models.Page) error { - if page.ID == 0 { - showInNav := int64(0) - if page.ShowInNav { - showInNav = 1 - } - newID, err := db.queries.InsertPage(ctx, sqlgen.InsertPageParams{ - SiteID: page.SiteID, - Guid: page.GUID, - Title: page.Title, - Slug: page.Slug, - Body: page.Body, - PageType: int64(page.PageType), - ShowInNav: showInNav, - SortOrder: int64(page.SortOrder), - CreatedAt: timeToInt(page.CreatedAt), - UpdatedAt: timeToInt(page.UpdatedAt), - }) - if err != nil { - return err - } - page.ID = newID - return nil - } - - showInNav := int64(0) - if page.ShowInNav { - showInNav = 1 - } - return db.queries.UpdatePage(ctx, sqlgen.UpdatePageParams{ - Title: page.Title, - Slug: page.Slug, - Body: page.Body, - PageType: int64(page.PageType), - ShowInNav: showInNav, - UpdatedAt: timeToInt(page.UpdatedAt), - ID: page.ID, - }) -} - -func (db *Provider) UpdatePageSortOrder(ctx context.Context, id int64, sortOrder int) error { - return db.queries.UpdatePageSortOrder(ctx, sqlgen.UpdatePageSortOrderParams{ - SortOrder: int64(sortOrder), - ID: id, - }) -} - -func (db *Provider) DeletePage(ctx context.Context, id int64) error { - return db.queries.DeletePage(ctx, id) -} - -func dbPageToPage(row sqlgen.Page) *models.Page { - return &models.Page{ - ID: row.ID, - SiteID: row.SiteID, - GUID: row.Guid, - Title: row.Title, - Slug: row.Slug, - Body: row.Body, - PageType: int(row.PageType), - ShowInNav: row.ShowInNav != 0, - SortOrder: int(row.SortOrder), - CreatedAt: time.Unix(row.CreatedAt, 0).UTC(), - UpdatedAt: time.Unix(row.UpdatedAt, 0).UTC(), - } -} diff --git a/providers/sitebuilder/builder.go b/providers/sitebuilder/builder.go index 71ce926..9e5199d 100644 --- a/providers/sitebuilder/builder.go +++ b/providers/sitebuilder/builder.go @@ -118,12 +118,7 @@ func (b *Builder) BuildSite(outDir string) error { // Build static assets eg.Go(func() error { return b.writeStaticAssets(buildCtx) }) - if err := eg.Wait(); err != nil { - return err - } - - // Render pages last so they can override auto-generated content - return b.renderPages(buildCtx) + return eg.Wait() } func (b *Builder) renderPostListWithCategories(bctx buildContext, ctx context.Context) error { @@ -166,10 +161,14 @@ func (b *Builder) renderPostListWithCategories(bctx buildContext, ctx context.Co var prevURL, nextURL string if page > 1 { - prevURL = fmt.Sprintf("%v/%d", b.opts.BasePostList, page-1) + if page == 2 { + prevURL = "/posts/" + } else { + prevURL = fmt.Sprintf("/posts/%d/", page-1) + } } if page < totalPages { - nextURL = fmt.Sprintf("%v/%d", b.opts.BasePostList, page+1) + nextURL = fmt.Sprintf("/posts/%d/", page+1) } pl := postListData{ @@ -183,9 +182,9 @@ func (b *Builder) renderPostListWithCategories(bctx buildContext, ctx context.Co // Page 1 renders at both root and /posts/ var paths []string if page == 1 { - paths = []string{"", fmt.Sprintf("%v/1", b.opts.BasePostList)} + paths = []string{"", "/posts"} } else { - paths = []string{fmt.Sprintf("%v/%d", b.opts.BasePostList, page)} + paths = []string{fmt.Sprintf("/posts/%d", page)} } for _, path := range paths { diff --git a/providers/sitebuilder/builder_test.go b/providers/sitebuilder/builder_test.go index 3fec74f..a5a9bbf 100644 --- a/providers/sitebuilder/builder_test.go +++ b/providers/sitebuilder/builder_test.go @@ -22,7 +22,6 @@ func TestBuilder_BuildSite(t *testing.T) { "layout_main.html": {Data: []byte(`{{ .Body }}`)}, "categories_list.html": {Data: []byte(`{{ range .Categories}}{{.Name}},{{ end }}`)}, "categories_single.html": {Data: []byte(`

{{.Category.Name}}

`)}, - "pages_single.html": {Data: []byte(`{{ if .Page.Title }}

{{ .Page.Title }}

{{ end }}{{ .HTML }}`)}, } posts := []*models.Post{ @@ -50,15 +49,11 @@ func TestBuilder_BuildSite(t *testing.T) { } } }, - Pages: []*models.Page{ - {Title: "About", Slug: "about", Body: "About this site"}, - }, } wantFiles := map[string]string{ "2026/02/18/test-post/index.html": "

This is a test post

\n", "2026/02/20/another-post/index.html": "

This is another test post

\n", "index.html": "Test Post,Another Post,", - "about/index.html": "

About

About this site

\n", } outDir := t.TempDir() diff --git a/providers/sitebuilder/render_pages.go b/providers/sitebuilder/render_pages.go deleted file mode 100644 index 6183088..0000000 --- a/providers/sitebuilder/render_pages.go +++ /dev/null @@ -1,31 +0,0 @@ -package sitebuilder - -import ( - "bytes" - "context" - "html/template" - "io" -) - -func (b *Builder) renderPages(bctx buildContext) error { - for _, page := range b.site.Pages { - var md bytes.Buffer - if err := b.mdRenderer.RenderTo(context.Background(), &md, page.Body); err != nil { - return err - } - - data := pageSingleData{ - commonData: commonData{Site: b.site}, - Page: page, - HTML: template.HTML(md.String()), - } - - path := "/" + page.Slug - if err := b.createAtPath(bctx, path, func(f io.Writer) error { - return b.renderTemplate(f, tmplNamePageSingle, data) - }); err != nil { - return err - } - } - return nil -} diff --git a/providers/sitebuilder/tmpls.go b/providers/sitebuilder/tmpls.go index 029cab0..e0ece37 100644 --- a/providers/sitebuilder/tmpls.go +++ b/providers/sitebuilder/tmpls.go @@ -26,16 +26,12 @@ const ( // tmplNameCategorySingle is the template for a single category page tmplNameCategorySingle = "categories_single.html" - - // tmplNamePageSingle is the template for a single page (pageSingleData) - tmplNamePageSingle = "pages_single.html" ) type Options struct { - BasePosts string // BasePosts is the base path for posts. - BasePostList string // BasePostList is the base path for post lists. - BaseUploads string // BaseUploads is the base path for uploads. - BaseStatic string // BaseStatic is the base path for static assets. + BasePosts string // BasePosts is the base path for posts. + BaseUploads string // BaseUploads is the base path for uploads. + BaseStatic string // BaseStatic is the base path for static assets. // TemplatesFS provides the raw templates for rendering the site. TemplatesFS fs.FS @@ -96,9 +92,3 @@ type categorySingleData struct { PrevURL string NextURL string } - -type pageSingleData struct { - commonData - Page *models.Page - HTML template.HTML -} diff --git a/services/pages/service.go b/services/pages/service.go deleted file mode 100644 index 8a82bc0..0000000 --- a/services/pages/service.go +++ /dev/null @@ -1,198 +0,0 @@ -package pages - -import ( - "context" - "strings" - "time" - - "lmika.dev/lmika/weiro/models" - "lmika.dev/lmika/weiro/providers/db" - "lmika.dev/lmika/weiro/services/publisher" -) - -type CreatePageParams struct { - GUID string `form:"guid" json:"guid"` - Title string `form:"title" json:"title"` - Slug string `form:"slug" json:"slug"` - Body string `form:"body" json:"body"` - PageType int `form:"page_type" json:"page_type"` - ShowInNav bool `form:"show_in_nav" json:"show_in_nav"` -} - -type Service struct { - db *db.Provider - publisher *publisher.Queue -} - -func New(db *db.Provider, publisher *publisher.Queue) *Service { - return &Service{db: db, publisher: publisher} -} - -func (s *Service) ListPages(ctx context.Context) ([]*models.Page, error) { - site, ok := models.GetSite(ctx) - if !ok { - return nil, models.SiteRequiredError - } - return s.db.SelectPagesOfSite(ctx, site.ID) -} - -func (s *Service) GetPage(ctx context.Context, id int64) (*models.Page, error) { - site, ok := models.GetSite(ctx) - if !ok { - return nil, models.SiteRequiredError - } - - page, err := s.db.SelectPage(ctx, id) - if err != nil { - return nil, err - } - if page.SiteID != site.ID { - return nil, models.NotFoundError - } - return page, nil -} - -func (s *Service) CreatePage(ctx context.Context, params CreatePageParams) (*models.Page, error) { - site, ok := models.GetSite(ctx) - if !ok { - return nil, models.SiteRequiredError - } - - now := time.Now() - slug := params.Slug - if slug == "" { - slug = models.GeneratePageSlug(params.Title) - } - - if !strings.HasPrefix(slug, "/") { - slug = "/" + slug - } - - // Check slug collision - if _, err := s.db.SelectPageBySlugAndSite(ctx, site.ID, slug); err == nil { - return nil, models.SlugConflictError - } else if !db.ErrorIsNoRows(err) { - return nil, err - } - - // Determine sort order: place at end - existingPages, err := s.db.SelectPagesOfSite(ctx, site.ID) - if err != nil { - return nil, err - } - sortOrder := len(existingPages) - - page := &models.Page{ - SiteID: site.ID, - GUID: params.GUID, - Title: params.Title, - Slug: slug, - Body: params.Body, - PageType: params.PageType, - ShowInNav: params.ShowInNav, - SortOrder: sortOrder, - CreatedAt: now, - UpdatedAt: now, - } - if page.GUID == "" { - page.GUID = models.NewNanoID() - } - - if err := s.db.SavePage(ctx, page); err != nil { - return nil, err - } - - s.publisher.Queue(site) - return page, nil -} - -func (s *Service) UpdatePage(ctx context.Context, id int64, params CreatePageParams) (*models.Page, error) { - site, ok := models.GetSite(ctx) - if !ok { - return nil, models.SiteRequiredError - } - - page, err := s.db.SelectPage(ctx, id) - if err != nil { - return nil, err - } - if page.SiteID != site.ID { - return nil, models.NotFoundError - } - - slug := params.Slug - if slug == "" { - slug = models.GeneratePageSlug(params.Title) - } - - if !strings.HasPrefix(slug, "/") { - slug = "/" + slug - } - - // Check slug collision (exclude self) - if existing, err := s.db.SelectPageBySlugAndSite(ctx, site.ID, slug); err == nil && existing.ID != page.ID { - return nil, models.SlugConflictError - } else if err != nil && !db.ErrorIsNoRows(err) { - return nil, err - } - - page.Title = params.Title - page.Slug = slug - page.Body = params.Body - page.PageType = params.PageType - page.ShowInNav = params.ShowInNav - page.UpdatedAt = time.Now() - - if err := s.db.SavePage(ctx, page); err != nil { - return nil, err - } - - s.publisher.Queue(site) - return page, nil -} - -func (s *Service) DeletePage(ctx context.Context, id int64) error { - site, ok := models.GetSite(ctx) - if !ok { - return models.SiteRequiredError - } - - page, err := s.db.SelectPage(ctx, id) - if err != nil { - return err - } - if page.SiteID != site.ID { - return models.NotFoundError - } - - if err := s.db.DeletePage(ctx, id); err != nil { - return err - } - - s.publisher.Queue(site) - return nil -} - -func (s *Service) ReorderPages(ctx context.Context, pageIDs []int64) error { - site, ok := models.GetSite(ctx) - if !ok { - return models.SiteRequiredError - } - - // Verify all pages belong to this site - for i, id := range pageIDs { - page, err := s.db.SelectPage(ctx, id) - if err != nil { - return err - } - if page.SiteID != site.ID { - return models.NotFoundError - } - if err := s.db.UpdatePageSortOrder(ctx, id, i); err != nil { - return err - } - } - - s.publisher.Queue(site) - return nil -} diff --git a/services/publisher/service.go b/services/publisher/service.go index adfcdd7..939817a 100644 --- a/services/publisher/service.go +++ b/services/publisher/service.go @@ -65,12 +65,6 @@ func (p *Publisher) Publish(ctx context.Context, site models.Site) error { }) } - // Fetch pages - sitePages, err := p.db.SelectPagesOfSite(ctx, site.ID) - if err != nil { - return err - } - for _, target := range targets { if !target.Enabled { continue @@ -90,7 +84,6 @@ func (p *Publisher) Publish(ctx context.Context, site models.Site) error { CategoriesOfPost: func(ctx context.Context, postID int64) ([]*models.Category, error) { return p.db.SelectCategoriesOfPost(ctx, postID) }, - Pages: sitePages, OpenUpload: func(u models.Upload) (io.ReadCloser, error) { return p.up.OpenUpload(site, u) }, @@ -121,14 +114,13 @@ func (p *Publisher) publishSite(ctx context.Context, pubSite pubmodel.Site, targ } sb, err := sitebuilder.New(pubSite, sitebuilder.Options{ - BasePosts: "/posts", - BasePostList: "/pages", - BaseUploads: "/uploads", - BaseStatic: "/static", - TemplatesFS: templateFS, - StaticFS: staticFS, - FeedItems: 30, - RenderTZ: renderTZ, + BasePosts: "/posts", + BaseUploads: "/uploads", + BaseStatic: "/static", + TemplatesFS: templateFS, + StaticFS: staticFS, + FeedItems: 30, + RenderTZ: renderTZ, }) if err != nil { return err diff --git a/services/services.go b/services/services.go index 852dea3..beb6727 100644 --- a/services/services.go +++ b/services/services.go @@ -8,7 +8,6 @@ import ( "lmika.dev/lmika/weiro/providers/uploadfiles" "lmika.dev/lmika/weiro/services/auth" "lmika.dev/lmika/weiro/services/categories" - "lmika.dev/lmika/weiro/services/pages" "lmika.dev/lmika/weiro/services/posts" "lmika.dev/lmika/weiro/services/publisher" "lmika.dev/lmika/weiro/services/sites" @@ -24,7 +23,6 @@ type Services struct { Sites *sites.Service Uploads *uploads.Service Categories *categories.Service - Pages *pages.Service } func New(cfg config.Config) (*Services, error) { @@ -42,7 +40,6 @@ func New(cfg config.Config) (*Services, error) { siteService := sites.New(dbp) uploadService := uploads.New(dbp, ufp, filepath.Join(cfg.ScratchDir, "uploads", "pending")) categoriesService := categories.New(dbp, publisherQueue) - pagesService := pages.New(dbp, publisherQueue) return &Services{ DB: dbp, @@ -53,7 +50,6 @@ func New(cfg config.Config) (*Services, error) { Sites: siteService, Uploads: uploadService, Categories: categoriesService, - Pages: pagesService, }, nil } diff --git a/sql/queries/pages.sql b/sql/queries/pages.sql deleted file mode 100644 index 0df22ff..0000000 --- a/sql/queries/pages.sql +++ /dev/null @@ -1,34 +0,0 @@ --- name: SelectPagesOfSite :many -SELECT * FROM pages -WHERE site_id = ? ORDER BY sort_order ASC; - --- name: SelectPage :one -SELECT * FROM pages WHERE id = ? LIMIT 1; - --- name: SelectPageByGUID :one -SELECT * FROM pages WHERE guid = ? LIMIT 1; - --- name: SelectPageBySlugAndSite :one -SELECT * FROM pages WHERE site_id = ? AND slug = ? LIMIT 1; - --- name: InsertPage :one -INSERT INTO pages ( - site_id, guid, title, slug, body, page_type, show_in_nav, sort_order, created_at, updated_at -) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) -RETURNING id; - --- name: UpdatePage :exec -UPDATE pages SET - title = ?, - slug = ?, - body = ?, - page_type = ?, - show_in_nav = ?, - updated_at = ? -WHERE id = ?; - --- name: UpdatePageSortOrder :exec -UPDATE pages SET sort_order = ? WHERE id = ?; - --- name: DeletePage :exec -DELETE FROM pages WHERE id = ?; diff --git a/sql/schema/06_pages.up.sql b/sql/schema/06_pages.up.sql deleted file mode 100644 index 5090456..0000000 --- a/sql/schema/06_pages.up.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE pages ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - site_id INTEGER NOT NULL, - guid TEXT NOT NULL, - title TEXT NOT NULL, - slug TEXT NOT NULL, - body TEXT NOT NULL, - page_type INTEGER NOT NULL DEFAULT 0, - show_in_nav INTEGER NOT NULL DEFAULT 0, - sort_order INTEGER NOT NULL DEFAULT 0, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - FOREIGN KEY (site_id) REFERENCES sites (id) ON DELETE CASCADE -); -CREATE INDEX idx_pages_site ON pages (site_id); -CREATE UNIQUE INDEX idx_pages_guid ON pages (guid); -CREATE UNIQUE INDEX idx_pages_site_slug ON pages (site_id, slug); diff --git a/views/_common/nav.html b/views/_common/nav.html index e9c0de7..e8bce30 100644 --- a/views/_common/nav.html +++ b/views/_common/nav.html @@ -11,14 +11,11 @@ Posts - diff --git a/views/pages/edit.html b/views/pages/edit.html deleted file mode 100644 index d534b80..0000000 --- a/views/pages/edit.html +++ /dev/null @@ -1,55 +0,0 @@ -
- {{ if .isNew }} -
- {{ else }} - - {{ end }} - -
-
-
- -
- -
- - {{ if not .isNew }} - - {{ end }} -
-
-
-
-
Navigation
-
-
- - -
-
- - -
-
-
-
-
Page Settings
-
-
- - -
-
-
-
-
-
- - {{ if not .isNew }} - - {{ end }} -
diff --git a/views/pages/index.html b/views/pages/index.html deleted file mode 100644 index 3011c64..0000000 --- a/views/pages/index.html +++ /dev/null @@ -1,35 +0,0 @@ -
-
-
- New Page -
-
- - {{ if .pages }} - - - - - - - - - - - {{ range .pages }} - - - - - - - {{ end }} - -
TitleSlugNav
{{ .Title }}{{ .Slug }}{{ if .ShowInNav }}Yes{{ end }}
- {{ else }} -
-
No pages yet.
-
- {{ end }} -
diff --git a/views/posts/edit.html b/views/posts/edit.html index b9f5ea7..d162788 100644 --- a/views/posts/edit.html +++ b/views/posts/edit.html @@ -11,12 +11,12 @@ -
+
{{ if $isPublished }} - + {{ else }} - - + + {{ end }}