aboutsummaryrefslogtreecommitdiff
path: root/cmds
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
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')
-rw-r--r--cmds/serve.go19
-rw-r--r--cmds/templates/live-feed.html5
-rw-r--r--cmds/templates/results.html5
-rw-r--r--cmds/templates/tools.html5
4 files changed, 32 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 {
diff --git a/cmds/templates/live-feed.html b/cmds/templates/live-feed.html
index 1529ee1..2974c4b 100644
--- a/cmds/templates/live-feed.html
+++ b/cmds/templates/live-feed.html
@@ -153,6 +153,11 @@
<p>No articles to display</p>
{{end}}
</div>
+{{if .Footer}}
+ <footer style="margin-top: 30px; border-top: 1px solid #000; padding-top: 10px; font-size: 0.9em; color: #666;">
+ {{.Footer}}
+ </footer>
+{{end}}
</body>
</html>
{{end}}
diff --git a/cmds/templates/results.html b/cmds/templates/results.html
index 13f68e0..1cc6250 100644
--- a/cmds/templates/results.html
+++ b/cmds/templates/results.html
@@ -274,6 +274,11 @@
</div>
{{end}}
</div>
+{{if .Footer}}
+ <footer style="margin-top: 30px; border-top: 1px solid #000; padding-top: 10px; font-size: 0.9em; color: #666;">
+ {{.Footer}}
+ </footer>
+{{end}}
</body>
</html>
{{end}}
diff --git a/cmds/templates/tools.html b/cmds/templates/tools.html
index def04fe..994acac 100644
--- a/cmds/templates/tools.html
+++ b/cmds/templates/tools.html
@@ -197,6 +197,11 @@
</form>
</div>
</div>
+{{if .Footer}}
+ <footer style="margin-top: 30px; border-top: 1px solid #000; padding-top: 10px; font-size: 0.9em; color: #666;">
+ {{.Footer}}
+ </footer>
+{{end}}
</body>
</html>
{{end}}