summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* feat: configure EditorJS ImageTool upload endpointmainivar11 days1-1/+6
|
* fix: check vips.Startup error and tidy go.mod indirect annotationivar11 days3-25/+6
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: wire MediaHandler routes and govips lifecycleivar11 days2-21/+17
| | | | | | | | | - Add RegisterUploadRoute to admin Server (POST /admin/upload/image, auth-protected) - Import govips/v2 and internal/media in main.go - Replace static /media/ file handler with mediaSrv.HandleServe for on-the-fly image conversion - Call vips.Startup/Shutdown around server lifetime Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: close error propagation, remove GIF, unexport storageDirivar11 days1-8/+11
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add MediaHandler for image upload and on-the-fly servingivar11 days2-0/+407
| | | | | | | | Implements HandleUpload (EditorJS-compatible multipart endpoint) and HandleServe (on-the-fly WebP/JPEG conversion with width-based resizing and file-system caching) backed by govips/ConvertAndResize. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: consolidate format validation into switch defaultivar11 days1-5/+2
|
* feat: add govips ConvertAndResize wrapperivar11 days2-0/+124
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: add govips/v2 dependencyivar11 days2-1/+6
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: add govips/v2 dependencyivar11 days2-0/+23
|
* fix: remove incorrect govips v1 dependencyivar11 days2-37/+14
|
* chore: add govips dependencyivar11 days2-0/+23
|
* fix: make slug rename and content update atomic via RenameAndUpsertPostivar11 days3-23/+121
| | | | | | | | Previously RenamePost + UpsertPost were two separate DB calls; a failure between them left the post at the new slug with stale content. The new RenameAndUpsertPost method does both in a single transaction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* .ivar11 days34-2052/+862
|
* fix: remove spurious os.IsNotExist check on DB error in handleDeleteivar11 days1-1/+1
|
* feat: support slug editing and rename in admin UI with redirect and cache ↵ivar11 days1-153/+231
| | | | | | invalidation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add editable slug field to admin form with JS auto-populationivar11 days1-25/+56
|
* docs: add image block implementation planivar11 days1-0/+902
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: serve drafts by direct link; add 301 redirect on renamed slugsivar11 days1-0/+190
|
* fix: guard RenamePost against self-rename (noop)ivar11 days1-0/+3
|
* feat: add RenamePost with transactional rename and redirect creationivar11 days2-0/+130
| | | | | | | | | | | | | | | Implement RenamePost method that atomically: 1. Fetches the post record by old slug 2. Inserts a new record with the new slug 3. Deletes the old slug post 4. Collapses redirect chains (updates any redirects pointing to oldSlug to point to newSlug) 5. Creates a redirect from oldSlug to newSlug All operations are transactional (all-or-nothing). Includes two comprehensive tests: - TestRenamePost: basic rename with redirect creation and old slug deletion - TestRenamePost_CollapsesChain: verifies redirect chains are collapsed correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add redirect DB methods (AddRedirect, GetRedirect, CollapseRedirects)ivar11 days2-0/+219
|
* feat: add redirects table to meta.db schemaivar11 days1-0/+16
|
* docs: add image block upload and serving design specivar11 days1-0/+114
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add spec and implementation plan for draft access and slug editingivar11 days4-98/+858
| | | | Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix: set HTML template on Gin engine for template renderingivar12 days1-0/+1
| | | | | | | | | | | | | The embedded templates were being parsed but not registered with the Gin engine's HTMLRender, causing 500 errors on admin UI requests. Now SetHTMLTemplate is called to register the parsed template set so Gin can render them properly. Verified: - Build succeeds with no errors - Binary contains embedded template strings - Admin UI pages load and render correctly - All template files (base, list, form, error) work as expected
* feat: embed admin templates into binary with //go:embedivar12 days5-3/+150
| | | | | | | | | | | | | Move admin templates from templates/admin/*.html to internal/admin/templates/*.html and embed them using //go:embed directive. This removes the runtime dependency on having template files on disk, allowing the templates to be compiled into the binary. Changes: - Add embed import and //go:embed directive for templates - Change ParseGlob() to ParseFS() to load from embedded filesystem - Copy templates to internal/admin/templates/ for embedding Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix: resolve Gin routing conflict with catch-all static files handlerivar12 days1-2/+7
|
* refactor: update cmdServe to use Gin engine directlyivar12 days1-9/+8
|
* refactor: convert admin handlers to Gin context-based signaturesivar12 days20-110/+1801
| | | | | | | | | | | | | | | | | - Remove old ServeHTTP method (no longer needed with Gin routing) - Update all 6 handler methods to use *gin.Context instead of http.ResponseWriter, *http.Request - Convert handler signatures: handleList, handleNew, handleNewPost, handleEdit, handleDelete - Remove render() helper (use c.HTML() directly) - Update renderError() to accept gin.Context instead of http.ResponseWriter - Update postFromForm() to extract form data from gin.Context using c.PostForm() - Update main.go to use adminSrv.NewServer() and adminSrv.Engine() - All handlers now use Gin methods: c.HTML(), c.PostForm(), c.Param(), c.Redirect() - Path parameters now extracted via c.Param("slug") instead of function arguments - HTTP status codes and error handling fully migrated to Gin patterns Build verified: go build ./cmd/nebbet succeeds Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* refactor: implement auth middleware for Ginivar12 days1-41/+30
| | | | | | | | | | | | | | | | Replace the old checkAuth() method with a Gin middleware function that validates Basic Auth credentials. The authMiddleware() now handles authentication at the middleware level rather than per-handler, supporting graceful degradation when no auth file is configured. The middleware: - Skips auth if AuthFile is empty or doesn't exist - Extracts Basic Auth credentials from the request - Verifies credentials using the auth package - Returns 401 with WWW-Authenticate header on failure - Calls c.Next() to pass control to handlers on success Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* refactor: add Gin routing infrastructure with NewServer constructorivar12 days1-183/+85
|
* chore: add gin dependencyivar12 days3-6/+104
|
* Fix modivar2026-03-312-4/+64
|
* Use sqlite packageivar2026-03-313-271/+1
|
* Use sqlite packageivar2026-03-313-266/+2
|
* Fault if not able to authenticate userivar2026-03-311-6/+6
|
* Merge pull request #2 from ivarlovlie/claude/add-post-management-rqIiOIvar Løvlie2026-03-3110-6/+987
|\
| * Add post management admin UI and switch to modernc.org/sqliteClaude2026-03-3110-6/+987
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | - Replace custom CGO sqlite driver with modernc.org/sqlite (registered as "sqlite3"); a local compat shim under compat/sqlite/ provides the same import path and WAL-mode behaviour using system libsqlite3 while network access is unavailable — swapping to the real pure-Go package later only requires removing the replace directive and running go get. - Add internal/admin/server.go: HTTP handler for /admin/ that serves a server-side-rendered post management UI (list, new, edit, delete). Posts are stored as Markdown files under content/posts/ and rebuilt via the existing Builder after every write. Basic auth is checked against the .passwords file when it exists. - Add cmd/nebbet/main.go: unified CLI with build, watch, serve (HTTP server with admin + file server + watch), and user subcommands. - Update builder.BuildAll to skip content/admin/ — admin pages are served dynamically and must never appear in the static output directory. - Mark content/admin/index.md as draft so the old static placeholder is not built even if the admin skip logic is bypassed. - Fix .gitignore: use /nebbet (root-only) so the pattern no longer accidentally ignores the cmd/nebbet/ source directory. https://claude.ai/code/session_01WLuSGxJhNs2cFM2zJzSsTx
* Merge pull request #1 from ivarlovlie/claude/static-site-sqlite-setup-mrcArIvar Løvlie2026-03-3121-0/+1468
|\
| * Add static site builder: SQLite-backed MD→HTML pipelineClaude2026-03-3121-0/+1468
|/ | | | | | | | | | | | | | | - cmd/nebbet: CLI with build [--watch] and user add/passwd/delete/list - internal/builder: markdown→HTML, component injection via HTML comments, auto importmap from lib/, fsnotify watch with 150ms debounce - internal/db: meta.db (page index, tag queries) + search.db (FTS5) - internal/sqlitedrv: minimal CGO database/sql driver for system libsqlite3 - internal/auth: htpasswd-compatible bcrypt password file management - templates/base.html + admin.html, styles/main.css + admin.css - nginx.conf with auth_basic for /admin, clean URLs, gzip - nebbet.service systemd unit for watch daemon - Example content/index.md and components/site-greeting.js https://claude.ai/code/session_01HTc1BCBCiMTEB54XQP1Wz9
* Create InitIvar Løvlie2026-03-311-0/+1