feat(templates): full bn chrome sync from cms + VersionedAssetURL hook

cms is now the authoring source for the bn chrome (head/toolbar/engagement);
this repo carries a mechanically-synced copy solely for guest-side plugin
templates (cms `make sync-templates`, drift gated by check-safety check 31).
head.templ picks up everything it had drifted behind on (RFG-parity favicon
head, analytics/web-vitals beacons, custom-scripts placement, bnApplyTheme)
and is now SDK-clean: asset versioning goes through the new
bn.VersionedAssetURL hook (identity default; the CMS host wires it to its
internal assets registry). HeadData is shape-compatible with existing plugin
usage; BrandingData/SiteSettingsData internals changed — plugins see that at
compile time on their next core bump.

Spec: cms docs/superpowers/specs/2026-07-07-bn-chrome-single-source-design.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-07-07 03:02:34 +08:00
parent 1ee9c280e2
commit 20c67b80ee
5 changed files with 1028 additions and 510 deletions

View File

@ -0,0 +1,11 @@
package bn
// VersionedAssetURL resolves an asset URL to a cache-versioned form. The
// default is the identity function; the CMS host wires it to
// internal/assets.VersionedURL at startup so plugin stylesheet links get
// content-hash ?v= params. Guest-side (wasm) renders keep the identity
// default — asset hashing is a host concern.
//
// This file is part of the cms→core template sync set (make sync-templates);
// it must stay SDK-clean (no cms imports).
var VersionedAssetURL = func(url string) string { return url }

View File

@ -62,7 +62,7 @@ func EngagementScript(config EngagementConfig) templ.Component {
var templ_7745c5c3_Var2 string var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.ResolveAttributeValue(engagementConfigJSON(config)) templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.ResolveAttributeValue(engagementConfigJSON(config))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/engagement.templ`, Line: 30, Col: 63} return templ.Error{Err: templ_7745c5c3_Err, FileName: `engagement.templ`, Line: 30, Col: 63}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {

View File

@ -16,22 +16,56 @@ func resolveMediaURL(url string) string {
return url return url
} }
// canonicalURL resolves the canonical link. An admin-set value wins (made absolute
// against the page's own origin when it is root-relative); otherwise the page's own
// absolute URL is used as a self-referencing canonical. Returns "" only when neither
// is available.
func canonicalURL(canonical, pageURL string) string {
if canonical == "" {
return pageURL
}
if strings.HasPrefix(canonical, "http://") || strings.HasPrefix(canonical, "https://") {
return canonical
}
if strings.HasPrefix(canonical, "/") && pageURL != "" {
if i := strings.Index(pageURL, "://"); i >= 0 {
if j := strings.IndexByte(pageURL[i+3:], '/'); j >= 0 {
return pageURL[:i+3+j] + canonical
}
return pageURL + canonical
}
}
return canonical
}
// BrandingData contains generated favicon/icon URLs // BrandingData contains generated favicon/icon URLs
type BrandingData struct { type BrandingData struct {
FaviconICO string // /brand/{id}/favicon.ico FaviconICO string // /.brand/{id}/favicon.ico
Favicon16 string // /brand/{id}/favicon-16x16.png Favicon16 string // /.brand/{id}/favicon-16x16.png
Favicon32 string // /brand/{id}/favicon-32x32.png Favicon32 string // /.brand/{id}/favicon-32x32.png
AppleTouchIcon string // /brand/{id}/apple-touch-icon.png (180x180) Favicon96 string // /.brand/{id}/favicon-96x96.png
Android192 string // /brand/{id}/android-chrome-192x192.png AppleTouchIcon string // /.brand/{id}/apple-touch-icon.png (180x180)
Android512 string // /brand/{id}/android-chrome-512x512.png Android192 string // /.brand/{id}/android-chrome-192x192.png
Maskable512 string // /brand/{id}/maskable-512x512.png Android512 string // /.brand/{id}/android-chrome-512x512.png
Master1024 string // /brand/{id}/icon-1024x1024.png Maskable512 string // /.brand/{id}/maskable-512x512.png
ManifestURL string // /brand/{id}/site.webmanifest Master1024 string // /.brand/{id}/icon-1024x1024.png
ManifestURL string // /.brand/{id}/site.webmanifest
MaskIcon string // /.brand/{id}/mask-icon.svg
MSTile150 string // /.brand/{id}/mstile-150x150.png
BrowserConfig string // /.brand/{id}/browserconfig.xml
ThemeColor string ThemeColor string
SVG string // Optional SVG pass-through SVG string // Optional SVG pass-through
IsGenerated bool IsGenerated bool
} }
// CustomScriptEntry represents a single custom script with placement control
type CustomScriptEntry struct {
Name string
Placement string // "head" or "body"
Code string
Enabled bool
}
// SiteSettingsData contains site-wide settings for head injection // SiteSettingsData contains site-wide settings for head injection
type SiteSettingsData struct { type SiteSettingsData struct {
Title string Title string
@ -41,8 +75,9 @@ type SiteSettingsData struct {
LogoAlt string LogoAlt string
AppleTouchIcon string AppleTouchIcon string
GoogleAnalyticsID string GoogleAnalyticsID string
CustomHeadScripts string CustomScripts []CustomScriptEntry
CustomBodyScripts string GoogleAnalyticsEnabled bool
GoogleAnalyticsExplicitlySet bool // true if the enabled flag was explicitly set in JSON (not nil)
MetaDescription string MetaDescription string
DefaultOGImage string DefaultOGImage string
TwitterHandle string TwitterHandle string
@ -67,6 +102,10 @@ type PageMeta struct {
TwitterImage string // Twitter card image URL TwitterImage string // Twitter card image URL
CanonicalURL string // Canonical URL for this page CanonicalURL string // Canonical URL for this page
RobotsDirective string // Robots directive (e.g., "noindex, nofollow") RobotsDirective string // Robots directive (e.g., "noindex, nofollow")
OGType string // Open Graph type ("article" for posts, else "website")
PageURL string // Absolute URL of this page (og:url + auto-canonical)
ArticlePublishedTime string // ISO 8601 published time (articles only)
ArticleAuthor string // Author name (articles only)
} }
// HeadData contains all data needed to render the <head> element // HeadData contains all data needed to render the <head> element
@ -159,15 +198,75 @@ func ParseSiteSettings(doc map[string]any) SiteSettingsData {
} }
// Analytics // Analytics
var legacyHeadScripts, legacyBodyScripts string
if analyticsData, ok := siteData["analytics"].(map[string]any); ok { if analyticsData, ok := siteData["analytics"].(map[string]any); ok {
if v, ok := analyticsData["google_analytics_id"].(string); ok { if v, ok := analyticsData["google_analytics_id"].(string); ok {
settings.GoogleAnalyticsID = v settings.GoogleAnalyticsID = v
} }
// Read GA enabled flag — if present, use it; if absent but ID is set, default to enabled (backward compat)
if v, ok := analyticsData["google_analytics_enabled"].(bool); ok {
settings.GoogleAnalyticsEnabled = v
settings.GoogleAnalyticsExplicitlySet = true
} else if settings.GoogleAnalyticsID != "" {
settings.GoogleAnalyticsEnabled = true
}
// Preserve legacy flat fields for fallback
if v, ok := analyticsData["custom_head_scripts"].(string); ok { if v, ok := analyticsData["custom_head_scripts"].(string); ok {
settings.CustomHeadScripts = v legacyHeadScripts = v
} }
if v, ok := analyticsData["custom_body_scripts"].(string); ok { if v, ok := analyticsData["custom_body_scripts"].(string); ok {
settings.CustomBodyScripts = v legacyBodyScripts = v
}
}
// Structured custom scripts
if scriptsArr, ok := siteData["custom_scripts"].([]any); ok && len(scriptsArr) > 0 {
for _, item := range scriptsArr {
entry, ok := item.(map[string]any)
if !ok {
continue
}
cs := CustomScriptEntry{}
if v, ok := entry["name"].(string); ok {
cs.Name = v
}
// Placement: proto enum stored as float64 (1=head, 2=body) or string
switch p := entry["placement"].(type) {
case float64:
if p == 1 {
cs.Placement = "head"
} else if p == 2 {
cs.Placement = "body"
}
case string:
cs.Placement = p
}
if v, ok := entry["code"].(string); ok {
cs.Code = v
}
if v, ok := entry["enabled"].(bool); ok {
cs.Enabled = v
}
settings.CustomScripts = append(settings.CustomScripts, cs)
}
}
// Fallback: if no structured scripts, migrate old flat fields
if len(settings.CustomScripts) == 0 {
if legacyHeadScripts != "" {
settings.CustomScripts = append(settings.CustomScripts, CustomScriptEntry{
Name: "Legacy Head Scripts",
Placement: "head",
Code: legacyHeadScripts,
Enabled: true,
})
}
if legacyBodyScripts != "" {
settings.CustomScripts = append(settings.CustomScripts, CustomScriptEntry{
Name: "Legacy Body Scripts",
Placement: "body",
Code: legacyBodyScripts,
Enabled: true,
})
} }
} }
@ -209,6 +308,18 @@ func ParseSiteSettings(doc map[string]any) SiteSettingsData {
if v, ok := brandingData["svg"].(string); ok { if v, ok := brandingData["svg"].(string); ok {
settings.Branding.SVG = v settings.Branding.SVG = v
} }
if v, ok := brandingData["favicon_96"].(string); ok {
settings.Branding.Favicon96 = v
}
if v, ok := brandingData["mask_icon"].(string); ok {
settings.Branding.MaskIcon = v
}
if v, ok := brandingData["mstile_150"].(string); ok {
settings.Branding.MSTile150 = v
}
if v, ok := brandingData["browserconfig"].(string); ok {
settings.Branding.BrowserConfig = v
}
} }
// Admin bypass mode (for showing banner when admin bypasses maintenance/coming_soon) // Admin bypass mode (for showing banner when admin bypasses maintenance/coming_soon)
@ -276,6 +387,18 @@ func ParsePageMeta(doc map[string]any) PageMeta {
if v, ok := doc["robotsDirective"].(string); ok { if v, ok := doc["robotsDirective"].(string); ok {
meta.RobotsDirective = v meta.RobotsDirective = v
} }
if v, ok := doc["ogType"].(string); ok {
meta.OGType = v
}
if v, ok := doc["pageUrl"].(string); ok {
meta.PageURL = v
}
if v, ok := doc["articlePublishedTime"].(string); ok {
meta.ArticlePublishedTime = v
}
if v, ok := doc["articleAuthor"].(string); ok {
meta.ArticleAuthor = v
}
return meta return meta
} }
@ -310,6 +433,12 @@ func ParseToolbarData(data map[string]any) ToolbarData {
if v, ok := data["preview_mode"].(string); ok { if v, ok := data["preview_mode"].(string); ok {
toolbar.PreviewMode = v toolbar.PreviewMode = v
} }
if v, ok := data["hide_preview_toggle"].(bool); ok {
toolbar.HidePreviewToggle = v
}
if v, ok := data["animate"].(bool); ok {
toolbar.Animate = v
}
if v, ok := data["position"].(string); ok { if v, ok := data["position"].(string); ok {
toolbar.Position = v toolbar.Position = v
} }
@ -390,15 +519,30 @@ templ Head(data HeadData) {
@themeInitScript(data.ThemeMode) @themeInitScript(data.ThemeMode)
<script src="https://unpkg.com/htmx.org@2.0.4"></script> <script src="https://unpkg.com/htmx.org@2.0.4"></script>
if data.Settings.Branding.IsGenerated { if data.Settings.Branding.IsGenerated {
// Use generated brand assets // Use generated brand assets (modern RFG-parity set; SVG first)
<link rel="icon" type="image/x-icon" href={ data.Settings.Branding.FaviconICO }/> if data.Settings.Branding.SVG != "" {
<link rel="icon" type="image/png" sizes="16x16" href={ data.Settings.Branding.Favicon16 }/> <link rel="icon" type="image/svg+xml" href={ data.Settings.Branding.SVG }/>
}
if data.Settings.Branding.Favicon96 != "" {
<link rel="icon" type="image/png" sizes="96x96" href={ data.Settings.Branding.Favicon96 }/>
}
<link rel="icon" type="image/png" sizes="32x32" href={ data.Settings.Branding.Favicon32 }/> <link rel="icon" type="image/png" sizes="32x32" href={ data.Settings.Branding.Favicon32 }/>
<link rel="icon" type="image/png" sizes="16x16" href={ data.Settings.Branding.Favicon16 }/>
<link rel="icon" type="image/x-icon" href={ data.Settings.Branding.FaviconICO }/>
<link rel="apple-touch-icon" sizes="180x180" href={ data.Settings.Branding.AppleTouchIcon }/> <link rel="apple-touch-icon" sizes="180x180" href={ data.Settings.Branding.AppleTouchIcon }/>
if data.Settings.Branding.MaskIcon != "" {
<link rel="mask-icon" href={ data.Settings.Branding.MaskIcon } color={ data.Settings.Branding.ThemeColor }/>
}
<link rel="manifest" href={ data.Settings.Branding.ManifestURL }/> <link rel="manifest" href={ data.Settings.Branding.ManifestURL }/>
if data.Settings.Branding.ThemeColor != "" { if data.Settings.Branding.ThemeColor != "" {
<meta name="theme-color" content={ data.Settings.Branding.ThemeColor }/> <meta name="theme-color" content={ data.Settings.Branding.ThemeColor }/>
} }
if data.Settings.Branding.BrowserConfig != "" {
<meta name="msapplication-config" content={ data.Settings.Branding.BrowserConfig }/>
}
if data.Title != "" {
<meta name="apple-mobile-web-app-title" content={ data.Title }/>
}
} else { } else {
// Legacy fallback - manual favicon uploads // Legacy fallback - manual favicon uploads
if data.Settings.Favicon != "" { if data.Settings.Favicon != "" {
@ -418,9 +562,9 @@ templ Head(data HeadData) {
<meta name="description" content={ data.Settings.MetaDescription }/> <meta name="description" content={ data.Settings.MetaDescription }/>
} }
// Canonical URL (page-level only, no site default) // Canonical URL: admin override (resolved to absolute) → auto self-canonical (M8)
if data.PageMeta.CanonicalURL != "" { if canonical := canonicalURL(data.PageMeta.CanonicalURL, data.PageMeta.PageURL); canonical != "" {
<link rel="canonical" href={ data.PageMeta.CanonicalURL }/> <link rel="canonical" href={ canonical }/>
} }
// Robots directive (page-level only - defaults to index,follow if not set) // Robots directive (page-level only - defaults to index,follow if not set)
@ -459,8 +603,25 @@ templ Head(data HeadData) {
<meta property="og:image" content={ resolveMediaURL(data.Settings.DefaultOGImage) }/> <meta property="og:image" content={ resolveMediaURL(data.Settings.DefaultOGImage) }/>
} }
// og:type - default to website // og:type: article for posts, website otherwise (M5)
if data.PageMeta.OGType != "" {
<meta property="og:type" content={ data.PageMeta.OGType }/>
} else {
<meta property="og:type" content="website"/> <meta property="og:type" content="website"/>
}
// og:url: absolute URL of this page (M6)
if data.PageMeta.PageURL != "" {
<meta property="og:url" content={ data.PageMeta.PageURL }/>
}
// article:* metadata for posts (M5)
if data.PageMeta.OGType == "article" {
if data.PageMeta.ArticlePublishedTime != "" {
<meta property="article:published_time" content={ data.PageMeta.ArticlePublishedTime }/>
}
if data.PageMeta.ArticleAuthor != "" {
<meta property="article:author" content={ data.PageMeta.ArticleAuthor }/>
}
}
// === TWITTER CARD META TAGS === // === TWITTER CARD META TAGS ===
if data.Settings.TwitterHandle != "" { if data.Settings.TwitterHandle != "" {
@ -512,7 +673,7 @@ templ Head(data HeadData) {
<link rel="alternate" type="application/atom+xml" title={ data.Settings.RSSFeedTitle + " (Atom)" } href={ data.Settings.RSSFeedURL + "/atom" }/> <link rel="alternate" type="application/atom+xml" title={ data.Settings.RSSFeedTitle + " (Atom)" } href={ data.Settings.RSSFeedURL + "/atom" }/>
} }
if data.Settings.GoogleAnalyticsID != "" { if data.Settings.GoogleAnalyticsID != "" && (data.Settings.GoogleAnalyticsEnabled || !data.Settings.GoogleAnalyticsExplicitlySet) {
<script async src={ "https://www.googletagmanager.com/gtag/js?id=" + data.Settings.GoogleAnalyticsID }></script> <script async src={ "https://www.googletagmanager.com/gtag/js?id=" + data.Settings.GoogleAnalyticsID }></script>
@googleAnalyticsScript(data.Settings.GoogleAnalyticsID) @googleAnalyticsScript(data.Settings.GoogleAnalyticsID)
} }
@ -521,14 +682,16 @@ templ Head(data HeadData) {
// Blog post engagement tracking (only rendered for posts with engagement config) // Blog post engagement tracking (only rendered for posts with engagement config)
@EngagementScript(data.EngagementConfig) @EngagementScript(data.EngagementConfig)
for _, style := range data.PluginStyles { for _, style := range data.PluginStyles {
<link rel="stylesheet" href={ style }/> <link rel="stylesheet" href={ VersionedAssetURL(style) }/>
} }
// Theme CSS injected AFTER plugin styles to take precedence // Theme CSS injected AFTER plugin styles to take precedence
if data.ThemeCSS != "" { if data.ThemeCSS != "" {
@themeStyle(data.ThemeCSS) @themeStyle(data.ThemeCSS)
} }
if data.Settings.CustomHeadScripts != "" { for _, script := range data.Settings.CustomScripts {
@templ.Raw(data.Settings.CustomHeadScripts) if script.Enabled && script.Placement == "head" {
@templ.Raw(script.Code)
}
} }
if data.StructuredData != "" { if data.StructuredData != "" {
@structuredDataScript(data.StructuredData) @structuredDataScript(data.StructuredData)
@ -570,8 +733,10 @@ templ AdminBypassBanner(settings SiteSettingsData) {
// BodyEnd renders custom scripts and admin toolbar before </body> // BodyEnd renders custom scripts and admin toolbar before </body>
templ BodyEnd(settings SiteSettingsData) { templ BodyEnd(settings SiteSettingsData) {
@recordValidationCall(ctx, "BodyEnd") @recordValidationCall(ctx, "BodyEnd")
if settings.CustomBodyScripts != "" { for _, script := range settings.CustomScripts {
@templ.Raw(settings.CustomBodyScripts) if script.Enabled && script.Placement == "body" {
@templ.Raw(script.Code)
}
} }
// Render admin editor toolbar if enabled (auto-injects for all templates) // Render admin editor toolbar if enabled (auto-injects for all templates)
@AdminEditorToolbar(settings.Toolbar) @AdminEditorToolbar(settings.Toolbar)
@ -779,7 +944,6 @@ func themeInitScript(themeMode string) templ.Component {
// preference (bn-theme cookie/localStorage) → site default → system. // preference (bn-theme cookie/localStorage) → site default → system.
// Exposed as window.bnApplyTheme so the toolbar theme tester can re-apply // Exposed as window.bnApplyTheme so the toolbar theme tester can re-apply
// after changing the override without duplicating this resolution. // after changing the override without duplicating this resolution.
// KEEP IN SYNC with cms backend/templates/bn/head.templ.
return templ.Raw(`<script> return templ.Raw(`<script>
window.bnApplyTheme=function(){ window.bnApplyTheme=function(){
var t=null;try{t=sessionStorage.getItem('bn-theme-override')}catch(e){} var t=null;try{t=sessionStorage.getItem('bn-theme-override')}catch(e){}

File diff suppressed because one or more lines are too long

View File

@ -242,7 +242,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var3 string var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var2).String()) templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -255,7 +255,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var4 templ.SafeURL var templ_7745c5c3_Var4 templ.SafeURL
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.EditURL)) templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.EditURL))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 301, Col: 38} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 301, Col: 38}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -268,7 +268,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var5 string var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.StatusLabel()) templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.StatusLabel())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 311, Col: 73} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 311, Col: 73}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -290,7 +290,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var7 string var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var6).String()) templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -303,7 +303,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var8 string var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(data.StatusLabel()) templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(data.StatusLabel())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 313, Col: 80} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 313, Col: 80}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -334,7 +334,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var10 string var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var9).String()) templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var9).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var10) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var10)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -362,7 +362,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
} }
}()) }())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 323, Col: 170} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 323, Col: 170}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var12) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var12)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -400,7 +400,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var13 string var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min", data.ReadingTime)) templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min", data.ReadingTime))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 435, Col: 46} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 435, Col: 46}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -423,7 +423,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var14 string var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/publish/%s", data.PageID)) templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/publish/%s", data.PageID))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 443, Col: 62} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 443, Col: 62}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -441,7 +441,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var15 string var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/page-info/%s", data.PageID)) templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/page-info/%s", data.PageID))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 460, Col: 63} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 460, Col: 63}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var15) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var15)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -454,7 +454,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var16 string var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.DropdownDirection()) templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.DropdownDirection())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 473, Col: 46} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 473, Col: 46}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var16) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var16)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -467,7 +467,7 @@ func AdminEditorToolbar(data ToolbarData) templ.Component {
var templ_7745c5c3_Var17 string var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.DropdownAlign()) templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.DropdownAlign())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 474, Col: 38} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 474, Col: 38}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var17) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var17)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -516,7 +516,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var19 string var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TodayPageviews)) templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TodayPageviews))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 515, Col: 91} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 515, Col: 91}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -539,7 +539,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var21 string var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var20).String()) templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var20).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var21) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var21)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -552,7 +552,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var22 string var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(data.TrendIcon()) templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(data.TrendIcon())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 519, Col: 25} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 519, Col: 25}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -565,7 +565,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var23 string var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d%%", abs(data.TrendPercent))) templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d%%", abs(data.TrendPercent)))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 519, Col: 73} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 519, Col: 73}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -603,7 +603,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var24 templ.SafeURL var templ_7745c5c3_Var24 templ.SafeURL
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("/author/" + data.AuthorSlug)) templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("/author/" + data.AuthorSlug))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 535, Col: 61} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 535, Col: 61}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -616,7 +616,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var25 string var templ_7745c5c3_Var25 string
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName) templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 535, Col: 100} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 535, Col: 100}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -634,7 +634,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var26 string var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName) templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 537, Col: 50} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 537, Col: 50}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -658,7 +658,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var27 string var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min read", data.ReadingTime)) templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min read", data.ReadingTime))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 542, Col: 86} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 542, Col: 86}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -681,7 +681,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var28 string var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d words", data.WordCount)) templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d words", data.WordCount))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 546, Col: 84} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 546, Col: 84}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -704,7 +704,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var29 string var templ_7745c5c3_Var29 string
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(data.TemplateName) templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(data.TemplateName)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 554, Col: 48} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 554, Col: 48}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -717,7 +717,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var30 string var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastModifiedFormatted()) templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastModifiedFormatted())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 558, Col: 59} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 558, Col: 59}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -730,7 +730,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var31 templ.SafeURL var templ_7745c5c3_Var31 templ.SafeURL
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.SettingsURL)) templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.SettingsURL))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 563, Col: 44} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 563, Col: 44}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -743,7 +743,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var32 templ.SafeURL var templ_7745c5c3_Var32 templ.SafeURL
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.HistoryURL)) templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.HistoryURL))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 569, Col: 43} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 569, Col: 43}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -756,7 +756,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var33 templ.SafeURL var templ_7745c5c3_Var33 templ.SafeURL
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.AnalyticsURL)) templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.AnalyticsURL))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 575, Col: 45} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 575, Col: 45}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -786,7 +786,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var35 string var templ_7745c5c3_Var35 string
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/share-preview/%s", data.PageID)) templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/share-preview/%s", data.PageID))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 597, Col: 67} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 597, Col: 67}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -832,7 +832,7 @@ func PageInfoDropdown(data ToolbarData) templ.Component {
var templ_7745c5c3_Var36 string var templ_7745c5c3_Var36 string
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/discard/%s", data.PageID)) templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/discard/%s", data.PageID))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 625, Col: 62} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 625, Col: 62}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -886,7 +886,7 @@ func positionButton(pageID uuid.UUID, pos string, currentPos string, label strin
var templ_7745c5c3_Var39 string var templ_7745c5c3_Var39 string
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var38).String()) templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var38).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -899,7 +899,7 @@ func positionButton(pageID uuid.UUID, pos string, currentPos string, label strin
var templ_7745c5c3_Var40 string var templ_7745c5c3_Var40 string
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/set-position/%s?pos=%s", pageID, pos)) templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(fmt.Sprintf("/toolbar/set-position/%s?pos=%s", pageID, pos))
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 646, Col: 71} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 646, Col: 71}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -912,7 +912,7 @@ func positionButton(pageID uuid.UUID, pos string, currentPos string, label strin
var templ_7745c5c3_Var41 string var templ_7745c5c3_Var41 string
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.ResolveAttributeValue(label) templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.ResolveAttributeValue(label)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 649, Col: 15} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 649, Col: 15}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var41) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var41)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
@ -934,7 +934,7 @@ func positionButton(pageID uuid.UUID, pos string, currentPos string, label strin
var templ_7745c5c3_Var43 string var templ_7745c5c3_Var43 string
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var42).String()) templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var42).String())
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/toolbar.templ`, Line: 1, Col: 0} return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {