feat: metadata draft
This commit is contained in:
@ -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')
|
||||
|
||||
@ -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))
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 }}
|
||||
|
||||
43
internal/web/templates/metadata.tmpl
Normal file
43
internal/web/templates/metadata.tmpl
Normal 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 }}
|
||||
@ -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>
|
||||
|
||||
Reference in New Issue
Block a user