diff --git a/pkg/server/tmpl/app.go b/pkg/server/tmpl/app.go
deleted file mode 100644
index 7f084a85..00000000
--- a/pkg/server/tmpl/app.go
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
- *
- * This file is part of Dnote.
- *
- * Dnote is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Dnote. If not, see .
- */
-
-package tmpl
-
-import (
- "bytes"
- "html/template"
- "net/http"
- "regexp"
-
- "gorm.io/gorm"
- "github.com/pkg/errors"
-)
-
-// routes
-var notesPathRegex = regexp.MustCompile("^/notes/([^/]+)$")
-
-// template names
-var templateIndex = "index"
-var templateNoteMetaTags = "note_metatags"
-
-// AppShell represents the application in HTML
-type AppShell struct {
- DB *gorm.DB
- T *template.Template
-}
-
-// ErrNotFound is an error indicating that a resource was not found
-var ErrNotFound = errors.New("not found")
-
-// NewAppShell parses the templates for the application
-func NewAppShell(db *gorm.DB, content []byte) (AppShell, error) {
- t, err := template.New(templateIndex).Parse(string(content))
- if err != nil {
- return AppShell{}, errors.Wrap(err, "parsing the index template")
- }
-
- _, err = t.New(templateNoteMetaTags).Parse(noteMetaTags)
- if err != nil {
- return AppShell{}, errors.Wrap(err, "parsing the note meta tags template")
- }
-
- return AppShell{DB: db, T: t}, nil
-}
-
-// Execute executes the index template
-func (a AppShell) Execute(r *http.Request) ([]byte, error) {
- data, err := a.getData(r)
- if err != nil {
- return nil, errors.Wrap(err, "getting data")
- }
-
- var buf bytes.Buffer
- if err := a.T.ExecuteTemplate(&buf, templateIndex, data); err != nil {
- return nil, errors.Wrap(err, "executing template")
- }
-
- return buf.Bytes(), nil
-}
-
-func (a AppShell) getData(r *http.Request) (tmplData, error) {
- path := r.URL.Path
-
- if ok, params := matchPath(path, notesPathRegex); ok {
- p, err := a.newNotePage(r, params[0])
- if err != nil {
- return tmplData{}, errors.Wrap(err, "instantiating note page")
- }
-
- return p.getData()
- }
-
- p := defaultPage{}
- return p.getData(), nil
-}
-
-// matchPath checks if the given path matches the given regular expressions
-// and returns a boolean as well as any parameters from regex capture groups.
-func matchPath(p string, reg *regexp.Regexp) (bool, []string) {
- match := notesPathRegex.FindStringSubmatch(p)
-
- if len(match) > 0 {
- return true, match[1:]
- }
-
- return false, nil
-}
diff --git a/pkg/server/tmpl/app_test.go b/pkg/server/tmpl/app_test.go
deleted file mode 100644
index 8772bf92..00000000
--- a/pkg/server/tmpl/app_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
- *
- * This file is part of Dnote.
- *
- * Dnote is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Dnote. If not, see .
- */
-
-package tmpl
-
-import (
- "net/http"
- "testing"
-
- "github.com/dnote/dnote/pkg/assert"
- "github.com/dnote/dnote/pkg/server/testutils"
- "github.com/pkg/errors"
-)
-
-func TestAppShellExecute(t *testing.T) {
- t.Run("home", func(t *testing.T) {
- db := testutils.InitMemoryDB(t)
-
- a, err := NewAppShell(db, []byte("
{{ .Title }}{{ .MetaTags }}"))
- if err != nil {
- t.Fatal(errors.Wrap(err, "preparing app shell"))
- }
-
- r, err := http.NewRequest("GET", "http://mock.url/", nil)
- if err != nil {
- t.Fatal(errors.Wrap(err, "preparing request"))
- }
-
- b, err := a.Execute(r)
- if err != nil {
- t.Fatal(errors.Wrap(err, "executing"))
- }
-
- assert.Equal(t, string(b), "Dnote", "result mismatch")
- })
-}
diff --git a/pkg/server/tmpl/data.go b/pkg/server/tmpl/data.go
deleted file mode 100644
index 186c1467..00000000
--- a/pkg/server/tmpl/data.go
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
- *
- * This file is part of Dnote.
- *
- * Dnote is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Dnote. If not, see .
- */
-
-package tmpl
-
-import (
- "bytes"
- "fmt"
- "html/template"
- "net/http"
- "regexp"
- "strings"
- "time"
-
- "github.com/dnote/dnote/pkg/server/database"
- "github.com/dnote/dnote/pkg/server/middleware"
- "github.com/dnote/dnote/pkg/server/operations"
- "github.com/pkg/errors"
-)
-
-var newlineRegexp = regexp.MustCompile(`\r?\n`)
-
-// tmplData is the data to be passed to the app shell template
-type tmplData struct {
- Title string
- MetaTags template.HTML
-}
-
-type noteMetaTagsData struct {
- Title string
- Description string
-}
-
-type notePage struct {
- Note database.Note
- T *template.Template
-}
-
-func (a AppShell) newNotePage(r *http.Request, noteUUID string) (notePage, error) {
- user, _, err := middleware.AuthWithSession(a.DB, r)
- if err != nil {
- return notePage{}, errors.Wrap(err, "authenticating with session")
- }
-
- note, ok, err := operations.GetNote(a.DB, noteUUID, &user)
-
- if !ok {
- return notePage{}, ErrNotFound
- }
- if err != nil {
- return notePage{}, errors.Wrap(err, "getting note")
- }
-
- return notePage{note, a.T}, nil
-}
-
-func (p notePage) getTitle() string {
- note := p.Note
- date := time.Unix(0, note.AddedOn).Format("Jan 2 2006")
-
- return fmt.Sprintf("Note: %s (%s)", note.Book.Label, date)
-}
-
-func excerpt(s string, maxLen int) string {
- if len(s) > maxLen {
-
- var lastIdx int
- if maxLen > 3 {
- lastIdx = maxLen - 3
- } else {
- lastIdx = maxLen
- }
-
- return s[:lastIdx] + "..."
- }
-
- return s
-}
-
-func formatMetaDescContent(s string) string {
- desc := excerpt(s, 200)
- desc = strings.Trim(desc, " ")
-
- return newlineRegexp.ReplaceAllString(desc, " ")
-}
-
-func (p notePage) getMetaTags() (template.HTML, error) {
- title := p.getTitle()
- desc := formatMetaDescContent(p.Note.Body)
-
- data := noteMetaTagsData{
- Title: title,
- Description: desc,
- }
-
- var buf bytes.Buffer
- if err := p.T.ExecuteTemplate(&buf, templateNoteMetaTags, data); err != nil {
- return "", errors.Wrap(err, "executing template")
- }
-
- return template.HTML(buf.String()), nil
-}
-
-func (p notePage) getData() (tmplData, error) {
- mt, err := p.getMetaTags()
- if err != nil {
- return tmplData{}, errors.Wrap(err, "getting meta tags")
- }
-
- dat := tmplData{
- Title: p.getTitle(),
- MetaTags: mt,
- }
-
- return dat, nil
-}
-
-type defaultPage struct {
-}
-
-func (p defaultPage) getData() tmplData {
- return tmplData{
- Title: "Dnote",
- MetaTags: "",
- }
-}
diff --git a/pkg/server/tmpl/data_test.go b/pkg/server/tmpl/data_test.go
deleted file mode 100644
index c072d12e..00000000
--- a/pkg/server/tmpl/data_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
- *
- * This file is part of Dnote.
- *
- * Dnote is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Dnote. If not, see .
- */
-
-package tmpl
-
-import (
- "html/template"
- "testing"
- "time"
-
- "github.com/dnote/dnote/pkg/assert"
- "github.com/dnote/dnote/pkg/server/database"
- "github.com/dnote/dnote/pkg/server/testutils"
- "github.com/pkg/errors"
-)
-
-func TestDefaultPageGetData(t *testing.T) {
- p := defaultPage{}
-
- result := p.getData()
-
- assert.Equal(t, result.MetaTags, template.HTML(""), "MetaTags mismatch")
- assert.Equal(t, result.Title, "Dnote", "Title mismatch")
-}
-
-func TestNotePageGetData(t *testing.T) {
- // Set time.Local to UTC for deterministic test
- time.Local = time.UTC
-
- db := testutils.InitMemoryDB(t)
- a, err := NewAppShell(db, nil)
- if err != nil {
- t.Fatal(errors.Wrap(err, "preparing app shell"))
- }
-
- p := notePage{
- Note: database.Note{
- Book: database.Book{
- Label: "vocabulary",
- },
- AddedOn: time.Date(2019, time.January, 2, 0, 0, 0, 0, time.UTC).UnixNano(),
- },
- T: a.T,
- }
-
- result, err := p.getData()
- if err != nil {
- t.Fatal(errors.Wrap(err, "executing"))
- }
-
- assert.NotEqual(t, result.MetaTags, template.HTML(""), "MetaTags should not be empty")
- assert.Equal(t, result.Title, "Note: vocabulary (Jan 2 2019)", "Title mismatch")
-}
diff --git a/pkg/server/tmpl/tmpl.go b/pkg/server/tmpl/tmpl.go
deleted file mode 100644
index fbc13398..00000000
--- a/pkg/server/tmpl/tmpl.go
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2019, 2020, 2021, 2022, 2023, 2024, 2025 Dnote contributors
- *
- * This file is part of Dnote.
- *
- * Dnote is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with Dnote. If not, see .
- */
-
-package tmpl
-
-var noteMetaTags = `
-
-
-
-
-
-
-
-`
diff --git a/pkg/server/views/templates/books/index.gohtml b/pkg/server/views/templates/books/index.gohtml
deleted file mode 100644
index 46ebbecc..00000000
--- a/pkg/server/views/templates/books/index.gohtml
+++ /dev/null
@@ -1,20 +0,0 @@
-{{define "yield"}}
-