fix: unescape HTML entities in result titles
Wikipedia returns HTML entities like <span> which were being double-escaped by Go templates. Now using html.UnescapeString and template.HTML to render properly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
37420ae5a8
commit
23dcdef26f
2 changed files with 13 additions and 3 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{{define "result_item"}}
|
{{define "result_item"}}
|
||||||
<article class="result">
|
<article class="result">
|
||||||
<div class="result_header">
|
<div class="result_header">
|
||||||
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer">{{.Title}}</a>
|
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer">{{.SafeTitle}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="result_url">
|
<div class="result_url">
|
||||||
<img class="result-favicon" src="https://www.google.com/s2/favicons?domain={{.URL | urlquery}}&sz=32" alt="" loading="lazy" onerror="this.style.display='none'">
|
<img class="result-favicon" src="https://www.google.com/s2/favicons?domain={{.URL | urlquery}}&sz=32" alt="" loading="lazy" onerror="this.style.display='none'">
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<span class="engine-badge">{{.Engine}}</span>
|
<span class="engine-badge">{{.Engine}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{if .Content}}
|
{{if .Content}}
|
||||||
<p class="result_content">{{.Content}}</p>
|
<p class="result_content">{{.SafeContent}}</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</article>
|
</article>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package views
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -70,6 +71,10 @@ type ResultView struct {
|
||||||
// TemplateName is the actual template to dispatch to, computed from Template.
|
// TemplateName is the actual template to dispatch to, computed from Template.
|
||||||
// "videos" maps to "video_item", everything else maps to "result_item".
|
// "videos" maps to "video_item", everything else maps to "result_item".
|
||||||
TemplateName string
|
TemplateName string
|
||||||
|
// SafeTitle and SafeContent are HTML-unescaped versions for rendering.
|
||||||
|
// The API returns HTML entities which Go templates escape by default.
|
||||||
|
SafeTitle template.HTML
|
||||||
|
SafeContent template.HTML
|
||||||
}
|
}
|
||||||
|
|
||||||
// PageNumber represents a numbered pagination button.
|
// PageNumber represents a numbered pagination button.
|
||||||
|
|
@ -205,7 +210,12 @@ func FromResponse(resp contracts.SearchResponse, query string, pageno int, activ
|
||||||
r.URL = &safe
|
r.URL = &safe
|
||||||
}
|
}
|
||||||
r.Thumbnail = util.SanitizeResultURL(r.Thumbnail)
|
r.Thumbnail = util.SanitizeResultURL(r.Thumbnail)
|
||||||
pd.Results[i] = ResultView{MainResult: r, TemplateName: tmplName}
|
pd.Results[i] = ResultView{
|
||||||
|
MainResult: r,
|
||||||
|
TemplateName: tmplName,
|
||||||
|
SafeTitle: template.HTML(html.UnescapeString(r.Title)),
|
||||||
|
SafeContent: template.HTML(html.UnescapeString(r.Content)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert answers (they're map[string]any — extract string values).
|
// Convert answers (they're map[string]any — extract string values).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue