aboutsummaryrefslogtreecommitdiff
path: root/cmds/serve.go
diff options
context:
space:
mode:
authorSam Scholten2026-06-17 14:14:15 +1000
committerSam Scholten2026-06-17 14:14:15 +1000
commit2fc958c47142b5e1d5646e018e3c434e73dc71c3 (patch)
tree08f20679ed383de3b6a7c98c5d217a3b5d23e8a9 /cmds/serve.go
parentae38f7ee9cbe80bd2287c8ec5e6f74510a065e62 (diff)
downloadscholscan-2fc958c47142b5e1d5646e018e3c434e73dc71c3.tar.gz
scholscan-2fc958c47142b5e1d5646e018e3c434e73dc71c3.zip
Add --footer flag for custom HTML footer in web UI
Allows deploying with contextual links (e.g. blog post, homepage). Also adds links to live instance and blog post in README.
Diffstat (limited to 'cmds/serve.go')
-rw-r--r--cmds/serve.go19
1 files changed, 17 insertions, 2 deletions
diff --git a/cmds/serve.go b/cmds/serve.go
index 92aa64c..59ec14d 100644
--- a/cmds/serve.go
+++ b/cmds/serve.go
@@ -51,6 +51,7 @@ type ServeCommand struct {
RefreshInterval string
ModelPath string
Title string
+ Footer string
// Parsed interval
refreshInterval time.Duration
@@ -93,6 +94,7 @@ func (c *ServeCommand) Init(args []string) error {
fs.StringVar(&c.RefreshInterval, "refresh-interval", "24h", "Interval for background rescans (e.g., 24h, 1h)")
fs.StringVar(&c.ModelPath, "model", "model.json", "Path to trained model JSON file")
fs.StringVar(&c.Title, "title", "", "Custom title for the web interface")
+ fs.StringVar(&c.Footer, "footer", "", "Custom HTML footer for the web interface")
if err := fs.Parse(args); err != nil {
return err
@@ -552,6 +554,7 @@ func (c *ServeCommand) handleLiveFeed(w http.ResponseWriter, r *http.Request) {
"UpdatedAt": resultsTime.Format("2006-01-02 15:04:05"),
"Filter": filter,
"Title": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@@ -567,8 +570,9 @@ func (c *ServeCommand) handleTools(w http.ResponseWriter, r *http.Request) {
}
data := map[string]interface{}{
- "Page": "tools",
- "Title": displayTitle(c.Title),
+ "Page": "tools",
+ "Title": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@@ -636,6 +640,7 @@ func (c *ServeCommand) handleScore(w http.ResponseWriter, r *http.Request) {
"Score": score,
"Threshold": threshold,
"PageTitle": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@@ -701,6 +706,7 @@ func (c *ServeCommand) handleScan(w http.ResponseWriter, r *http.Request) {
"Articles": scored,
"Threshold": threshold,
"PageTitle": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@@ -860,6 +866,13 @@ func displayTitle(custom string) string {
return "ScholScan"
}
+func footerHTML(custom string) template.HTML {
+ if custom != "" {
+ return template.HTML(custom)
+ }
+ return ""
+}
+
// extractTitleFromURL fetches the content from a URL and extracts the title from the HTML.
// Designed to be resilient: tries multiple title sources, handles various URL formats,
// and provides meaningful error feedback if extraction fails.
@@ -966,6 +979,7 @@ func (c *ServeCommand) renderResultsError(w http.ResponseWriter, errMsg, title s
"Error": errMsg,
"Title": title,
"PageTitle": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := c.tmpl.ExecuteTemplate(w, "results", data); err != nil {
@@ -993,6 +1007,7 @@ func (c *ServeCommand) renderScanResultsError(w http.ResponseWriter, errMsg, fee
"Error": errMsg,
"FeedURL": feedURL,
"PageTitle": displayTitle(c.Title),
+ "Footer": footerHTML(c.Footer),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := c.tmpl.ExecuteTemplate(w, "results", data); err != nil {