feat: metadata draft

This commit is contained in:
2026-02-03 09:04:11 +01:00
parent 7238d02a13
commit d6617cec02
7 changed files with 58 additions and 45 deletions

View File

@ -12,11 +12,10 @@ type Note struct {
Path string
Title string
Content string
Size int64
// HTMLContent string
ModTime time.Time
// Directly in Note
Tags []string
CreatedAt time.Time
UpdatedAt time.Time
Published bool
}
@ -25,8 +24,12 @@ func NewNote() *Note {
return &Note{}
}
func formatDateRep(date time.Time) string {
return date.Format("2006-01-02 15:04:05")
}
func (n *Note) GetUpdateDateRep() string {
return n.UpdatedAt.Format("2006-01-02 15:04:05")
return formatDateRep(n.UpdatedAt)
}
// ExtractTitle return the first level heading content ('# title')

View File

@ -67,7 +67,7 @@ func (tm *TemplateManager) GetTemplate(td *TemplateData) (*template.Template, er
return tmpl, nil
}
func (tm *TemplateManager) Render(w http.ResponseWriter, name string, data interface{}) error {
func (tm *TemplateManager) Render(w http.ResponseWriter, name string, data any) error {
// Build the template files - include all necessary templates
var files []string
@ -77,6 +77,9 @@ func (tm *TemplateManager) Render(w http.ResponseWriter, name string, data inter
// Include noteList template (used by index)
files = append(files, tm.buildTemplatePath("noteList"))
// Include metadata template
files = append(files, tm.buildTemplatePath("metadata"))
// Add the specific template
files = append(files, tm.buildTemplatePath(name))

View File

@ -100,6 +100,7 @@ func TestTemplateManagerRender(t *testing.T) {
writeTemplate(t, baseDir, "base.tmpl", `{{ define "base" }}<html>{{ template "content" . }}</html>{{ end }}`)
writeTemplate(t, baseDir, "noteList.tmpl", `{{ define "noteList" }}notes{{ end }}`)
writeTemplate(t, baseDir, "index.tmpl", `{{ define "content" }}hello{{ end }}`)
writeTemplate(t, baseDir, "metadata.tmpl", `{{ define "noteList" }}notes{{ end }}`)
tm := NewTemplateManager(baseDir)
rec := httptest.NewRecorder()
@ -126,6 +127,7 @@ func TestTemplateManagerRender_MissingTemplate(t *testing.T) {
baseDir := t.TempDir()
writeTemplate(t, baseDir, "base.tmpl", `{{ define "base" }}<html>{{ template "content" . }}</html>{{ end }}`)
writeTemplate(t, baseDir, "noteList.tmpl", `{{ define "noteList" }}notes{{ end }}`)
writeTemplate(t, baseDir, "metadata.tmpl", `{{ define "noteList" }}notes{{ end }}`)
tm := NewTemplateManager(baseDir)
rec := httptest.NewRecorder()

View File

@ -45,6 +45,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// ViewState is built per-request, not shared
type ViewState struct {
Notes []*note.Note
Note *note.Note
RenderedNote template.HTML
SortBy string
SearchTerm string
@ -153,6 +154,7 @@ func (h *Handler) handleNotes(w http.ResponseWriter, r *http.Request) {
}
// Add to state
state.Note = note
state.RenderedNote = htmlContent
state.LastActive = hash

View File

@ -5,44 +5,5 @@
<main>
{{ .RenderedNote }}
</main>
<aside class="metadata-panel">
<section class="meta-block">
<h3>Tags</h3>
<div class="meta-tags">
<span class="tag">emacs</span>
<span class="tag">tramp</span>
<span class="tag">editing</span>
</div>
</section>
<section class="meta-block">
<h3>File Info</h3>
<ul class="meta-list">
<li><strong>Created:</strong> 2024-01-21</li>
<li><strong>Last Modified:</strong> 2026-02-01</li>
<li><strong>Size:</strong> 4.2 KB</li>
<li><strong>Hash:</strong> 81b9fe8656</li>
</ul>
</section>
<section class="meta-block">
<h3>Category</h3>
<div class="meta-category">Software Engineering</div>
</section>
<section class="meta-block">
<h3>Document Stats</h3>
<ul class="meta-list">
<li><strong>Word Count:</strong> 542</li>
<li><strong>Reading Time:</strong> 3 min</li>
<li><strong>Unique Words:</strong> 211</li>
</ul>
<!-- Placeholder for future stats such as word cloud -->
<div class="meta-stats-placeholder">
<p>Word cloud / stats visualization<br>(future)</p>
</div>
</section>
</aside>
{{ template "metadata" . }}
{{ end }}

View File

@ -0,0 +1,43 @@
{{ define "metadata" }}
{{ if .RenderedNote }}
<aside class="metadata-panel">
<section class="meta-block">
<h3>Tags</h3>
<div class="meta-tags">
<span class="tag">emacs</span>
<span class="tag">tramp</span>
<span class="tag">editing</span>
</div>
</section>
<section class="meta-block">
<h3>File Info</h3>
<ul class="meta-list">
<li><strong>Last Modified:</strong>{{ .Note.GetUpdateDateRep }}</li>
<li><strong>Size:</strong> {{ .Note.Size }}</li>
<li><strong>Hash:</strong> {{ .Note.ID }}</li>
</ul>
</section>
<section class="meta-block">
<h3>Category</h3>
<div class="meta-category">Software Engineering</div>
</section>
<section class="meta-block">
<h3>Document Stats</h3>
<ul class="meta-list">
<li><strong>Word Count:</strong> 542</li>
<li><strong>Unique Words:</strong> 211</li>
</ul>
<!-- Placeholder for future stats such as word cloud -->
<div class="meta-stats-placeholder">
<p>Word cloud / stats visualization<br>(future)</p>
</div>
</section>
</aside>
{{ end }}
{{ end }}

View File

@ -27,7 +27,6 @@
{{ range .Notes }}
<li {{ if eq .ID $.LastActive }}class="active-note"{{ end }}>
<div class="note-title">
<input type="checkbox"/>
<a href="/notes/{{ .ID }}" data-hash="{{ .ID }}">{{ if ge (len .Title) 30 }}{{printf "%.30s" .Title }}[...]{{ else }} {{ .Title }}{{ end }}</a>
</div>
<span class="last-modified">{{ .GetUpdateDateRep }}</span>