Bootstrap the plugin-facing SDK module so the fleet migration (P2) becomes a mechanical block/core/X -> block/pluginsdk/X import rewrite. - abi/proto/v1: the single source-of-truth ABI proto tree, copied from the cms authoring source (cms/backend/abi/proto/v1) with go_package retargeted to git.dev.alexdunmow.com/block/pluginsdk/abi/v1;abiv1. Kills the hand-kept cms/core proto duplication (audit gap 4). - abi/v1: generated Go bindings (buf generate); byte-identical to core's abi/v1 save the embedded go_package path. - plugin/ (registration + DI surface), plugin/wasmguest/** (transport shim, caps stubs, bnwasm db driver, testdata fixtures + golden .pb), and the guest-facing type packages: blocks (+builtin/shared/tags), templates (+pongo/bn), auth, settings, content, gating, crypto, rbac, video, ai, subscriptions, menus, datasources. Internal imports rewritten core -> pluginsdk; zero block/core references remain. - README/AGENTS(+CLAUDE symlink)/Makefile: proto is the contract, Go is one binding; no replace directives; templates/bn is a synced copy authored in cms. Spec: cms docs/superpowers/specs/2026-07-07-proto-first-plugin-sdk-design.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1762 lines
76 KiB
Go
1762 lines
76 KiB
Go
// Code generated by templ - DO NOT EDIT.
|
|
|
|
// templ: version: v0.3.1020
|
|
package bn
|
|
|
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
|
|
|
import "github.com/a-h/templ"
|
|
import templruntime "github.com/a-h/templ/runtime"
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// resolveMediaURL converts media: prefixed URLs to proper /media/ paths
|
|
// e.g., "media:abc/image.webp" → "/media/abc/image.webp"
|
|
func resolveMediaURL(url string) string {
|
|
if strings.HasPrefix(url, "media:") {
|
|
return "/media/" + strings.TrimPrefix(url, "media:")
|
|
}
|
|
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
|
|
type BrandingData struct {
|
|
FaviconICO string // /.brand/{id}/favicon.ico
|
|
Favicon16 string // /.brand/{id}/favicon-16x16.png
|
|
Favicon32 string // /.brand/{id}/favicon-32x32.png
|
|
Favicon96 string // /.brand/{id}/favicon-96x96.png
|
|
AppleTouchIcon string // /.brand/{id}/apple-touch-icon.png (180x180)
|
|
Android192 string // /.brand/{id}/android-chrome-192x192.png
|
|
Android512 string // /.brand/{id}/android-chrome-512x512.png
|
|
Maskable512 string // /.brand/{id}/maskable-512x512.png
|
|
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
|
|
SVG string // Optional SVG pass-through
|
|
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
|
|
type SiteSettingsData struct {
|
|
Title string
|
|
Description string
|
|
Favicon string
|
|
Logo string
|
|
LogoAlt string
|
|
AppleTouchIcon string
|
|
GoogleAnalyticsID string
|
|
CustomScripts []CustomScriptEntry
|
|
GoogleAnalyticsEnabled bool
|
|
GoogleAnalyticsExplicitlySet bool // true if the enabled flag was explicitly set in JSON (not nil)
|
|
MetaDescription string
|
|
DefaultOGImage string
|
|
TwitterHandle string
|
|
OGSiteName string
|
|
Branding BrandingData
|
|
AdminBypassMode string // "maintenance", "coming_soon", or "" if not bypassing
|
|
Toolbar ToolbarData
|
|
LLMsTxtEnabled bool // Whether llms.txt is enabled for AI content discovery
|
|
RSSFeedURL string // URL to the RSS feed (e.g., "/rss"), empty to disable
|
|
RSSFeedTitle string // Feed title for discovery link
|
|
}
|
|
|
|
// PageMeta contains page-level SEO meta data (overrides site defaults)
|
|
type PageMeta struct {
|
|
MetaTitle string // Custom SEO title (overrides page title)
|
|
MetaDescription string // Page-specific meta description
|
|
OGTitle string // Open Graph title
|
|
OGDescription string // Open Graph description
|
|
OGImage string // Open Graph image URL
|
|
TwitterTitle string // Twitter card title
|
|
TwitterDescription string // Twitter card description
|
|
TwitterImage string // Twitter card image URL
|
|
CanonicalURL string // Canonical URL for this page
|
|
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
|
|
type HeadData struct {
|
|
Title string
|
|
Settings SiteSettingsData
|
|
PageMeta PageMeta // Page-level SEO overrides
|
|
ThemeCSS string
|
|
ThemeMode string // "light", "dark", or "system"
|
|
PluginStyles []string // Additional stylesheet URLs
|
|
StructuredData string // JSON-LD structured data
|
|
CSSHash string // Cache-busting hash for styles.css
|
|
PageviewNonce string // Unique nonce for pageview deduplication
|
|
EngagementConfig EngagementConfig // Engagement tracking config (for blog posts)
|
|
}
|
|
|
|
// ParseEngagementConfig extracts engagement config from the document map
|
|
func ParseEngagementConfig(doc map[string]any) EngagementConfig {
|
|
config := EngagementConfig{}
|
|
|
|
engData, ok := doc["engagement_config"].(map[string]any)
|
|
if !ok {
|
|
return config
|
|
}
|
|
|
|
if v, ok := engData["page_path"].(string); ok {
|
|
config.PagePath = v
|
|
}
|
|
if v, ok := engData["page_id"].(string); ok {
|
|
config.PageID = v
|
|
}
|
|
if v, ok := engData["post_word_count"].(int); ok {
|
|
config.PostWordCount = v
|
|
}
|
|
if v, ok := engData["session_id"].(string); ok {
|
|
config.SessionID = v
|
|
}
|
|
if v, ok := engData["visitor_hash"].(string); ok {
|
|
config.VisitorHash = v
|
|
}
|
|
if v, ok := engData["is_post"].(bool); ok {
|
|
config.IsPost = v
|
|
}
|
|
|
|
return config
|
|
}
|
|
|
|
// ParseSiteSettings extracts site settings from the document map
|
|
func ParseSiteSettings(doc map[string]any) SiteSettingsData {
|
|
settings := SiteSettingsData{}
|
|
|
|
siteData, ok := doc["site_settings"].(map[string]any)
|
|
if !ok {
|
|
return settings
|
|
}
|
|
|
|
if v, ok := siteData["title"].(string); ok {
|
|
settings.Title = v
|
|
}
|
|
if v, ok := siteData["description"].(string); ok {
|
|
settings.Description = v
|
|
}
|
|
if v, ok := siteData["favicon"].(string); ok {
|
|
settings.Favicon = v
|
|
}
|
|
if v, ok := siteData["logo"].(string); ok {
|
|
settings.Logo = v
|
|
}
|
|
if v, ok := siteData["logo_alt"].(string); ok {
|
|
settings.LogoAlt = v
|
|
}
|
|
if v, ok := siteData["apple_touch_icon"].(string); ok {
|
|
settings.AppleTouchIcon = v
|
|
}
|
|
|
|
// SEO defaults
|
|
if seoData, ok := siteData["seo_defaults"].(map[string]any); ok {
|
|
if v, ok := seoData["meta_description"].(string); ok {
|
|
settings.MetaDescription = v
|
|
}
|
|
if v, ok := seoData["default_og_image"].(string); ok {
|
|
settings.DefaultOGImage = v
|
|
}
|
|
if v, ok := seoData["twitter_handle"].(string); ok {
|
|
settings.TwitterHandle = v
|
|
}
|
|
if v, ok := seoData["og_site_name"].(string); ok {
|
|
settings.OGSiteName = v
|
|
}
|
|
}
|
|
|
|
// Analytics
|
|
var legacyHeadScripts, legacyBodyScripts string
|
|
if analyticsData, ok := siteData["analytics"].(map[string]any); ok {
|
|
if v, ok := analyticsData["google_analytics_id"].(string); ok {
|
|
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 {
|
|
legacyHeadScripts = v
|
|
}
|
|
if v, ok := analyticsData["custom_body_scripts"].(string); ok {
|
|
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,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Branding (generated favicons)
|
|
if brandingData, ok := siteData["branding"].(map[string]any); ok {
|
|
if v, ok := brandingData["is_generated"].(bool); ok {
|
|
settings.Branding.IsGenerated = v
|
|
}
|
|
if v, ok := brandingData["favicon_ico"].(string); ok {
|
|
settings.Branding.FaviconICO = v
|
|
}
|
|
if v, ok := brandingData["favicon_16"].(string); ok {
|
|
settings.Branding.Favicon16 = v
|
|
}
|
|
if v, ok := brandingData["favicon_32"].(string); ok {
|
|
settings.Branding.Favicon32 = v
|
|
}
|
|
if v, ok := brandingData["apple_touch_icon"].(string); ok {
|
|
settings.Branding.AppleTouchIcon = v
|
|
}
|
|
if v, ok := brandingData["android_192"].(string); ok {
|
|
settings.Branding.Android192 = v
|
|
}
|
|
if v, ok := brandingData["android_512"].(string); ok {
|
|
settings.Branding.Android512 = v
|
|
}
|
|
if v, ok := brandingData["maskable_512"].(string); ok {
|
|
settings.Branding.Maskable512 = v
|
|
}
|
|
if v, ok := brandingData["master_1024"].(string); ok {
|
|
settings.Branding.Master1024 = v
|
|
}
|
|
if v, ok := brandingData["manifest_url"].(string); ok {
|
|
settings.Branding.ManifestURL = v
|
|
}
|
|
if v, ok := brandingData["theme_color"].(string); ok {
|
|
settings.Branding.ThemeColor = v
|
|
}
|
|
if v, ok := brandingData["svg"].(string); ok {
|
|
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)
|
|
if v, ok := siteData["admin_bypass_mode"].(string); ok {
|
|
settings.AdminBypassMode = v
|
|
}
|
|
|
|
// Admin editor toolbar
|
|
if toolbarData, ok := siteData["toolbar"].(map[string]any); ok {
|
|
settings.Toolbar = ParseToolbarData(toolbarData)
|
|
}
|
|
|
|
// AI Optimization settings
|
|
if aiOpt, ok := siteData["aiOptimization"].(map[string]any); ok {
|
|
if v, ok := aiOpt["llmsTxtEnabled"].(bool); ok {
|
|
settings.LLMsTxtEnabled = v
|
|
}
|
|
}
|
|
|
|
// RSS feed auto-discovery (injected by page handler from system page)
|
|
if v, ok := siteData["rss_feed_url"].(string); ok {
|
|
settings.RSSFeedURL = v
|
|
}
|
|
if v, ok := siteData["rss_feed_title"].(string); ok {
|
|
settings.RSSFeedTitle = v
|
|
}
|
|
|
|
return settings
|
|
}
|
|
|
|
// ParsePageMeta extracts page-level SEO metadata from the document map
|
|
// These fields override site-level defaults when set
|
|
func ParsePageMeta(doc map[string]any) PageMeta {
|
|
meta := PageMeta{}
|
|
|
|
// Page-level SEO fields are stored directly in the document root
|
|
// (matching frontend PageInfo type in web/src/store/editor.ts)
|
|
if v, ok := doc["metaTitle"].(string); ok {
|
|
meta.MetaTitle = v
|
|
}
|
|
if v, ok := doc["metaDescription"].(string); ok {
|
|
meta.MetaDescription = v
|
|
}
|
|
if v, ok := doc["ogTitle"].(string); ok {
|
|
meta.OGTitle = v
|
|
}
|
|
if v, ok := doc["ogDescription"].(string); ok {
|
|
meta.OGDescription = v
|
|
}
|
|
if v, ok := doc["ogImage"].(string); ok {
|
|
meta.OGImage = v
|
|
}
|
|
if v, ok := doc["twitterTitle"].(string); ok {
|
|
meta.TwitterTitle = v
|
|
}
|
|
if v, ok := doc["twitterDescription"].(string); ok {
|
|
meta.TwitterDescription = v
|
|
}
|
|
if v, ok := doc["twitterImage"].(string); ok {
|
|
meta.TwitterImage = v
|
|
}
|
|
if v, ok := doc["canonicalUrl"].(string); ok {
|
|
meta.CanonicalURL = v
|
|
}
|
|
if v, ok := doc["robotsDirective"].(string); ok {
|
|
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
|
|
}
|
|
|
|
// ParseToolbarData extracts toolbar data from the document map
|
|
func ParseToolbarData(data map[string]any) ToolbarData {
|
|
toolbar := ToolbarData{}
|
|
|
|
if v, ok := data["enabled"].(bool); ok {
|
|
toolbar.Enabled = v
|
|
}
|
|
if v, ok := data["page_id"].(string); ok {
|
|
if id, err := uuid.Parse(v); err == nil {
|
|
toolbar.PageID = id
|
|
}
|
|
}
|
|
if v, ok := data["page_slug"].(string); ok {
|
|
toolbar.PageSlug = v
|
|
}
|
|
if v, ok := data["page_title"].(string); ok {
|
|
toolbar.PageTitle = v
|
|
}
|
|
if v, ok := data["post_type"].(string); ok {
|
|
toolbar.PostType = v
|
|
}
|
|
if v, ok := data["status"].(string); ok {
|
|
toolbar.Status = v
|
|
}
|
|
if v, ok := data["has_unpublished_changes"].(bool); ok {
|
|
toolbar.HasUnpublishedChanges = v
|
|
}
|
|
if v, ok := data["preview_mode"].(string); ok {
|
|
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 {
|
|
toolbar.Position = v
|
|
}
|
|
if v, ok := data["template_name"].(string); ok {
|
|
toolbar.TemplateName = v
|
|
}
|
|
if v, ok := data["author_name"].(string); ok {
|
|
toolbar.AuthorName = v
|
|
}
|
|
if v, ok := data["author_slug"].(string); ok {
|
|
toolbar.AuthorSlug = v
|
|
}
|
|
if v, ok := data["last_modified"].(time.Time); ok {
|
|
toolbar.LastModified = v
|
|
}
|
|
if v, ok := data["edit_url"].(string); ok {
|
|
toolbar.EditURL = v
|
|
}
|
|
if v, ok := data["settings_url"].(string); ok {
|
|
toolbar.SettingsURL = v
|
|
}
|
|
if v, ok := data["history_url"].(string); ok {
|
|
toolbar.HistoryURL = v
|
|
}
|
|
if v, ok := data["analytics_url"].(string); ok {
|
|
toolbar.AnalyticsURL = v
|
|
}
|
|
|
|
// Analytics snapshot
|
|
if v, ok := data["today_pageviews"].(int64); ok {
|
|
toolbar.TodayPageviews = v
|
|
}
|
|
if v, ok := data["pageviews_trend"].(string); ok {
|
|
toolbar.PageviewsTrend = v
|
|
}
|
|
if v, ok := data["trend_percent"].(int); ok {
|
|
toolbar.TrendPercent = v
|
|
}
|
|
|
|
// Blog-specific fields
|
|
if v, ok := data["reading_time"].(int); ok {
|
|
toolbar.ReadingTime = v
|
|
}
|
|
if v, ok := data["word_count"].(int); ok {
|
|
toolbar.WordCount = v
|
|
}
|
|
if v, ok := data["category_count"].(int); ok {
|
|
toolbar.CategoryCount = v
|
|
}
|
|
|
|
return toolbar
|
|
}
|
|
|
|
// EffectiveTitle returns the title to use in the <title> tag.
|
|
// Priority: PageMeta.MetaTitle → Page Title | Site Name → Page Title
|
|
func (d HeadData) EffectiveTitle() string {
|
|
if d.PageMeta.MetaTitle != "" {
|
|
return d.PageMeta.MetaTitle
|
|
}
|
|
if d.Settings.OGSiteName != "" && d.Title != "" {
|
|
return d.Title + " | " + d.Settings.OGSiteName
|
|
}
|
|
return d.Title
|
|
}
|
|
|
|
// Head renders the complete <head> element with site settings and plugin extensions.
|
|
func Head(data HeadData) templ.Component {
|
|
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
|
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
|
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
|
return templ_7745c5c3_CtxErr
|
|
}
|
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
|
if !templ_7745c5c3_IsBuffer {
|
|
defer func() {
|
|
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err == nil {
|
|
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
|
}
|
|
}()
|
|
}
|
|
ctx = templ.InitializeContext(ctx)
|
|
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
|
if templ_7745c5c3_Var1 == nil {
|
|
templ_7745c5c3_Var1 = templ.NopComponent
|
|
}
|
|
ctx = templ.ClearChildren(ctx)
|
|
templ_7745c5c3_Err = recordValidationCall(ctx, "Head").Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var2 string
|
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.EffectiveTitle())
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 513, Col: 32}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</title>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.CSSHash != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<link rel=\"stylesheet\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var3 templ.SafeURL
|
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs("/data/styles/styles.css?v=" + data.CSSHash)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 515, Col: 76}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<link rel=\"stylesheet\" href=\"/data/styles/styles.css\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = themeInitScript(data.ThemeMode).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<script src=\"https://unpkg.com/htmx.org@2.0.4\"></script>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.IsGenerated {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.SVG != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<link rel=\"icon\" type=\"image/svg+xml\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var4 templ.SafeURL
|
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.SVG)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 524, Col: 75}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.Favicon96 != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<link rel=\"icon\" type=\"image/png\" sizes=\"96x96\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var5 templ.SafeURL
|
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.Favicon96)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 527, Col: 91}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var6 templ.SafeURL
|
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.Favicon32)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 529, Col: 90}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\"><link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var7 templ.SafeURL
|
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.Favicon16)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 530, Col: 90}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"><link rel=\"icon\" type=\"image/x-icon\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var8 templ.SafeURL
|
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.FaviconICO)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 531, Col: 80}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"><link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var9 templ.SafeURL
|
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.AppleTouchIcon)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 532, Col: 92}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.MaskIcon != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<link rel=\"mask-icon\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var10 templ.SafeURL
|
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.MaskIcon)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 534, Col: 64}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\" color=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var11 string
|
|
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.Branding.ThemeColor)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 534, Col: 108}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " <link rel=\"manifest\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var12 templ.SafeURL
|
|
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Branding.ManifestURL)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 536, Col: 65}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.ThemeColor != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<meta name=\"theme-color\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var13 string
|
|
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.Branding.ThemeColor)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 538, Col: 72}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var13)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Branding.BrowserConfig != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<meta name=\"msapplication-config\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var14 string
|
|
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.Branding.BrowserConfig)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 541, Col: 84}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Title != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<meta name=\"apple-mobile-web-app-title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var15 string
|
|
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Title)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 544, Col: 64}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var15)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
} else {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.Favicon != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<link rel=\"icon\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var16 templ.SafeURL
|
|
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.Favicon)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 549, Col: 49}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.Settings.AppleTouchIcon != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<link rel=\"apple-touch-icon\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var17 templ.SafeURL
|
|
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.AppleTouchIcon)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 552, Col: 68}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
}
|
|
if data.PageMeta.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<meta name=\"description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var18 string
|
|
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 560, Col: 67}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var18)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Settings.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<meta name=\"description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var19 string
|
|
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 562, Col: 67}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var19)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if canonical := canonicalURL(data.PageMeta.CanonicalURL, data.PageMeta.PageURL); canonical != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<link rel=\"canonical\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var20 templ.SafeURL
|
|
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinURLErrs(canonical)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 567, Col: 41}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.RobotsDirective != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<meta name=\"robots\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var21 string
|
|
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.RobotsDirective)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 572, Col: 62}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var21)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.Settings.OGSiteName != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<meta property=\"og:site_name\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var22 string
|
|
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.OGSiteName)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 578, Col: 67}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var22)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.OGTitle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<meta property=\"og:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var23 string
|
|
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.OGTitle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 583, Col: 60}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var23)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.MetaTitle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<meta property=\"og:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var24 string
|
|
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.MetaTitle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 585, Col: 62}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var24)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Title != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<meta property=\"og:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var25 string
|
|
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Title)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 587, Col: 49}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var25)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.OGDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "<meta property=\"og:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var26 string
|
|
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.OGDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 592, Col: 72}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var26)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "<meta property=\"og:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var27 string
|
|
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 594, Col: 74}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var27)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Settings.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<meta property=\"og:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var28 string
|
|
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 596, Col: 74}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var28)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.OGImage != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<meta property=\"og:image\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var29 string
|
|
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.ResolveAttributeValue(resolveMediaURL(data.PageMeta.OGImage))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 601, Col: 77}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var29)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Settings.DefaultOGImage != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "<meta property=\"og:image\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var30 string
|
|
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.ResolveAttributeValue(resolveMediaURL(data.Settings.DefaultOGImage))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 603, Col: 84}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.OGType != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "<meta property=\"og:type\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var31 string
|
|
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.OGType)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 608, Col: 58}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "<meta property=\"og:type\" content=\"website\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.PageURL != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<meta property=\"og:url\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var32 string
|
|
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.PageURL)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 614, Col: 58}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var32)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.OGType == "article" {
|
|
if data.PageMeta.ArticlePublishedTime != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<meta property=\"article:published_time\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var33 string
|
|
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.ArticlePublishedTime)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 619, Col: 88}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var33)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, " ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.PageMeta.ArticleAuthor != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<meta property=\"article:author\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var34 string
|
|
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.ArticleAuthor)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 622, Col: 73}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var34)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
}
|
|
if data.Settings.TwitterHandle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<meta name=\"twitter:site\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var35 string
|
|
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.TwitterHandle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 628, Col: 66}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "<meta name=\"twitter:card\" content=\"summary_large_image\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if data.PageMeta.TwitterTitle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<meta name=\"twitter:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var36 string
|
|
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.TwitterTitle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 634, Col: 66}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.OGTitle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "<meta name=\"twitter:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var37 string
|
|
templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.OGTitle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 636, Col: 61}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var37)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.MetaTitle != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<meta name=\"twitter:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var38 string
|
|
templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.MetaTitle)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 638, Col: 63}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var38)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Title != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "<meta name=\"twitter:title\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var39 string
|
|
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Title)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 640, Col: 50}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.TwitterDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "<meta name=\"twitter:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var40 string
|
|
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.TwitterDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 645, Col: 78}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.OGDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<meta name=\"twitter:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var41 string
|
|
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.OGDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 647, Col: 73}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var41)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<meta name=\"twitter:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var42 string
|
|
templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.PageMeta.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 649, Col: 75}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var42)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Settings.MetaDescription != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<meta name=\"twitter:description\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var43 string
|
|
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.MetaDescription)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 651, Col: 75}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.PageMeta.TwitterImage != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<meta name=\"twitter:image\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var44 string
|
|
templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.ResolveAttributeValue(resolveMediaURL(data.PageMeta.TwitterImage))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 656, Col: 83}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var44)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.PageMeta.OGImage != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<meta name=\"twitter:image\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var45 string
|
|
templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.ResolveAttributeValue(resolveMediaURL(data.PageMeta.OGImage))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 658, Col: 78}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var45)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if data.Settings.DefaultOGImage != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<meta name=\"twitter:image\" content=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var46 string
|
|
templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.ResolveAttributeValue(resolveMediaURL(data.Settings.DefaultOGImage))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 660, Col: 85}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var46)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.Settings.LLMsTxtEnabled {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<link rel=\"ai-content\" type=\"text/plain\" href=\"/llms.txt\"><meta name=\"llms\" content=\"/llms.txt\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.Settings.RSSFeedURL != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var47 string
|
|
templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.RSSFeedTitle + " (RSS)")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 672, Col: 97}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var47)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var48 templ.SafeURL
|
|
templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.RSSFeedURL)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 672, Col: 131}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "\"><link rel=\"alternate\" type=\"application/atom+xml\" title=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var49 string
|
|
templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.ResolveAttributeValue(data.Settings.RSSFeedTitle + " (Atom)")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 673, Col: 99}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var49)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var50 templ.SafeURL
|
|
templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinURLErrs(data.Settings.RSSFeedURL + "/atom")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 673, Col: 143}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.Settings.GoogleAnalyticsID != "" && (data.Settings.GoogleAnalyticsEnabled || !data.Settings.GoogleAnalyticsExplicitlySet) {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<script async src=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var51 string
|
|
templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.ResolveAttributeValue("https://www.googletagmanager.com/gtag/js?id=" + data.Settings.GoogleAnalyticsID)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 677, Col: 103}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var51)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\"></script> ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = googleAnalyticsScript(data.Settings.GoogleAnalyticsID).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = analyticsScript(data.PageviewNonce).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = EngagementScript(data.EngagementConfig).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
for _, style := range data.PluginStyles {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "<link rel=\"stylesheet\" href=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var52 templ.SafeURL
|
|
templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinURLErrs(VersionedAssetURL(style))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 685, Col: 57}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "\">")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
if data.ThemeCSS != "" {
|
|
templ_7745c5c3_Err = themeStyle(data.ThemeCSS).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
for _, script := range data.Settings.CustomScripts {
|
|
if script.Enabled && script.Placement == "head" {
|
|
templ_7745c5c3_Err = templ.Raw(script.Code).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
}
|
|
if data.StructuredData != "" {
|
|
templ_7745c5c3_Err = structuredDataScript(data.StructuredData).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</head>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// structuredDataScript renders JSON-LD structured data
|
|
func structuredDataScript(jsonLD string) templ.Component {
|
|
return templ.Raw(`<script type="application/ld+json">` + jsonLD + `</script>`)
|
|
}
|
|
|
|
// AdminBypassBanner renders a banner when admin is bypassing maintenance/coming_soon mode
|
|
// This should be rendered at the very start of the <body> to push down all content
|
|
func AdminBypassBanner(settings SiteSettingsData) templ.Component {
|
|
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
|
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
|
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
|
return templ_7745c5c3_CtxErr
|
|
}
|
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
|
if !templ_7745c5c3_IsBuffer {
|
|
defer func() {
|
|
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err == nil {
|
|
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
|
}
|
|
}()
|
|
}
|
|
ctx = templ.InitializeContext(ctx)
|
|
templ_7745c5c3_Var53 := templ.GetChildren(ctx)
|
|
if templ_7745c5c3_Var53 == nil {
|
|
templ_7745c5c3_Var53 = templ.NopComponent
|
|
}
|
|
ctx = templ.ClearChildren(ctx)
|
|
if settings.AdminBypassMode != "" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "<div class=\"bg-warning text-warning-foreground px-4 py-2 text-center text-sm font-medium relative z-[9999]\"><div class=\"max-w-7xl mx-auto flex items-center justify-center gap-2\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"></path></svg> ")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
if settings.AdminBypassMode == "maintenance" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "<span><strong>Maintenance Mode Active</strong> — You're seeing the normal site because you're logged in as admin. <a href=\"/admin/settings?tab=status\" class=\"underline hover:no-underline\">Manage</a></span>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
} else if settings.AdminBypassMode == "coming_soon" {
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "<span><strong>Coming Soon Mode Active</strong> — You're seeing the normal site because you're logged in as admin. <a href=\"/admin/settings?tab=status\" class=\"underline hover:no-underline\">Manage</a></span>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "</div></div>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// BodyEnd renders custom scripts and admin toolbar before </body>
|
|
func BodyEnd(settings SiteSettingsData) templ.Component {
|
|
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
|
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
|
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
|
return templ_7745c5c3_CtxErr
|
|
}
|
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
|
if !templ_7745c5c3_IsBuffer {
|
|
defer func() {
|
|
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err == nil {
|
|
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
|
}
|
|
}()
|
|
}
|
|
ctx = templ.InitializeContext(ctx)
|
|
templ_7745c5c3_Var54 := templ.GetChildren(ctx)
|
|
if templ_7745c5c3_Var54 == nil {
|
|
templ_7745c5c3_Var54 = templ.NopComponent
|
|
}
|
|
ctx = templ.ClearChildren(ctx)
|
|
templ_7745c5c3_Err = recordValidationCall(ctx, "BodyEnd").Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
for _, script := range settings.CustomScripts {
|
|
if script.Enabled && script.Placement == "body" {
|
|
templ_7745c5c3_Err = templ.Raw(script.Code).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
}
|
|
}
|
|
templ_7745c5c3_Err = AdminEditorToolbar(settings.Toolbar).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templ_7745c5c3_Var54.Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// themeStyle renders the theme CSS variables
|
|
func themeStyleComponent(css string) templ.Component {
|
|
return templ.Raw(`<style id="theme-variables">` + css + `</style>`)
|
|
}
|
|
|
|
func themeStyle(css string) templ.Component {
|
|
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
|
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
|
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
|
return templ_7745c5c3_CtxErr
|
|
}
|
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
|
if !templ_7745c5c3_IsBuffer {
|
|
defer func() {
|
|
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err == nil {
|
|
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
|
}
|
|
}()
|
|
}
|
|
ctx = templ.InitializeContext(ctx)
|
|
templ_7745c5c3_Var55 := templ.GetChildren(ctx)
|
|
if templ_7745c5c3_Var55 == nil {
|
|
templ_7745c5c3_Var55 = templ.NopComponent
|
|
}
|
|
ctx = templ.ClearChildren(ctx)
|
|
templ_7745c5c3_Err = themeStyleComponent(css).Render(ctx, templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// googleAnalyticsScript renders the GA4 inline script
|
|
func googleAnalyticsScript(gaID string) templ.Component {
|
|
return templ.Raw(`<script>window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', '` + gaID + `');</script>`)
|
|
}
|
|
|
|
// analyticsScript renders the built-in analytics tracking script (cookie-less)
|
|
// nonce is used for deduplication with server-side tracking
|
|
func analyticsScript(nonce string) templ.Component {
|
|
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
|
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
|
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
|
return templ_7745c5c3_CtxErr
|
|
}
|
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
|
if !templ_7745c5c3_IsBuffer {
|
|
defer func() {
|
|
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
if templ_7745c5c3_Err == nil {
|
|
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
|
}
|
|
}()
|
|
}
|
|
ctx = templ.InitializeContext(ctx)
|
|
templ_7745c5c3_Var56 := templ.GetChildren(ctx)
|
|
if templ_7745c5c3_Var56 == nil {
|
|
templ_7745c5c3_Var56 = templ.NopComponent
|
|
}
|
|
ctx = templ.ClearChildren(ctx)
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "<script data-nonce=\"")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
var templ_7745c5c3_Var57 string
|
|
templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.ResolveAttributeValue(nonce)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `head.templ`, Line: 763, Col: 27}
|
|
}
|
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var57)
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "\">\n\t\t(function(){\n\t\t\t// Don't track admin pages\n\t\t\tif(location.pathname.startsWith('/admin'))return;\n\n\t\t\t// CRITICAL: Capture nonce immediately while document.currentScript is valid\n\t\t\t// document.currentScript is only available during script parsing, not later\n\t\t\tvar _nonce = document.currentScript ? document.currentScript.getAttribute('data-nonce') : '';\n\n\t\t\t// Persistent session ID (survives page navigation within session)\n\t\t\tvar sid=sessionStorage.getItem('_bn_sid');\n\t\t\tif(!sid){sid=crypto.randomUUID();sessionStorage.setItem('_bn_sid',sid);}\n\n\t\t\t// ============================================================\n\t\t\t// Advanced Bot Detection - Client-Side Signals\n\t\t\t// See docs/BOT_DETECTION.md for full documentation\n\t\t\t// ============================================================\n\t\t\tvar botSignals={},botScore=0;\n\t\t\ttry{\n\t\t\t\t// 1. WebDriver property (30 points) - automation frameworks set this\n\t\t\t\tbotSignals.webdriver=!!navigator.webdriver;\n\t\t\t\tif(botSignals.webdriver)botScore+=30;\n\n\t\t\t\t// 2. CDP Detection (25 points) - detects Puppeteer/Playwright/Selenium\n\t\t\t\tbotSignals.cdp=false;\n\t\t\t\ttry{\n\t\t\t\t\tvar e=new Error();\n\t\t\t\t\tObject.defineProperty(e,'stack',{get:function(){botSignals.cdp=true;}});\n\t\t\t\t\tconsole.debug(e);\n\t\t\t\t\tif(botSignals.cdp)botScore+=25;\n\t\t\t\t}catch(x){}\n\n\t\t\t\t// 3. Plugin count (15 points) - headless often has no plugins\n\t\t\t\tbotSignals.plugins=navigator.plugins?navigator.plugins.length:0;\n\t\t\t\tif(botSignals.plugins===0)botScore+=15;\n\n\t\t\t\t// 4. Languages (15 points) - headless often has empty languages\n\t\t\t\tbotSignals.languages=navigator.languages?navigator.languages.length:0;\n\t\t\t\tif(botSignals.languages===0)botScore+=15;\n\n\t\t\t\t// 5. Chrome runtime (10 points) - real Chrome has chrome.runtime\n\t\t\t\tbotSignals.chromeRuntime=!!(window.chrome&&window.chrome.runtime);\n\t\t\t\tif(window.chrome&&!window.chrome.runtime)botScore+=10;\n\n\t\t\t\t// 6. WebGL renderer (20 points) - headless uses SwiftShader/llvmpipe\n\t\t\t\ttry{\n\t\t\t\t\tvar c=document.createElement('canvas');\n\t\t\t\t\tvar gl=c.getContext('webgl')||c.getContext('experimental-webgl');\n\t\t\t\t\tif(gl){\n\t\t\t\t\t\tvar dbg=gl.getExtension('WEBGL_debug_renderer_info');\n\t\t\t\t\t\tif(dbg){\n\t\t\t\t\t\t\tbotSignals.webglRenderer=gl.getParameter(dbg.UNMASKED_RENDERER_WEBGL)||'';\n\t\t\t\t\t\t\tvar r=botSignals.webglRenderer.toLowerCase();\n\t\t\t\t\t\t\tif(r.includes('swiftshader')||r.includes('llvmpipe')||r.includes('software'))botScore+=20;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}catch(x){}\n\n\t\t\t\t// 7. Permission anomalies (15 points) - inconsistent API states\n\t\t\t\tif(window.Notification&&navigator.permissions){\n\t\t\t\t\tnavigator.permissions.query({name:'notifications'}).then(function(p){\n\t\t\t\t\t\tif(p.state==='denied'&&Notification.permission==='default'){\n\t\t\t\t\t\t\tbotSignals.permissionAnomaly=true;\n\t\t\t\t\t\t\tbotScore+=15;\n\t\t\t\t\t\t}\n\t\t\t\t\t}).catch(function(){});\n\t\t\t\t}\n\n\t\t\t\t// 8. Headless in Client Hints (20 points)\n\t\t\t\tif(navigator.userAgentData&&navigator.userAgentData.getHighEntropyValues){\n\t\t\t\t\tnavigator.userAgentData.getHighEntropyValues(['fullVersionList','platform']).then(function(h){\n\t\t\t\t\t\tif(h.brands&&h.brands.some(function(b){return b.brand.toLowerCase().includes('headless');})){\n\t\t\t\t\t\t\tbotSignals.headlessHints=true;\n\t\t\t\t\t\t\tbotScore+=20;\n\t\t\t\t\t\t}\n\t\t\t\t\t}).catch(function(){});\n\t\t\t\t}\n\n\t\t\t\t// 9. Automation variables (10 points each)\n\t\t\t\tif(window._phantom||window.__nightmare||window.callPhantom){botSignals.phantomjs=true;botScore+=10;}\n\t\t\t\tif(window.__selenium_unwrapped||window.__webdriver_evaluate||document.__selenium_evaluate){botSignals.selenium=true;botScore+=10;}\n\t\t\t\tif(window.__fxdriver_evaluate||window.__webdriver_script_fn){botSignals.selenium=true;botScore+=10;}\n\n\t\t\t\t// 10. Broken image dimensions (10 points) - headless often fails to render\n\t\t\t\ttry{\n\t\t\t\t\tvar img=new Image();\n\t\t\t\t\timg.src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\t\t\t\t\tif(img.height===0){botSignals.brokenImage=true;botScore+=10;}\n\t\t\t\t}catch(x){}\n\n\t\t\t\t// Cap at 100\n\t\t\t\tbotScore=Math.min(botScore,100);\n\t\t\t\tbotSignals.score=botScore;\n\t\t\t}catch(x){botSignals.error=x.message;}\n\n\t\t\t// ============================================================\n\t\t\t// Web Vitals collection\n\t\t\t// ============================================================\n\t\t\tvar _lcp=0,_fcp=0,_cls=0,_ttfb=0;\n\t\t\tif('PerformanceObserver'in window){\n\t\t\t\ttry{\n\t\t\t\t\tnew PerformanceObserver(function(l){var e=l.getEntries().pop();if(e)_lcp=Math.round(e.startTime);}).observe({type:'largest-contentful-paint',buffered:true});\n\t\t\t\t\tnew PerformanceObserver(function(l){l.getEntries().forEach(function(e){if(e.name==='first-contentful-paint')_fcp=Math.round(e.startTime);});}).observe({type:'paint',buffered:true});\n\t\t\t\t\tnew PerformanceObserver(function(l){l.getEntries().forEach(function(e){if(!e.hadRecentInput)_cls+=e.value;});}).observe({type:'layout-shift',buffered:true});\n\t\t\t\t}catch(e){}\n\t\t\t}\n\t\t\ttry{var nav=performance.getEntriesByType('navigation')[0];if(nav)_ttfb=Math.round(nav.responseStart);}catch(e){}\n\n\t\t\t// Scroll depth tracking\n\t\t\tvar _maxScroll=0;\n\t\t\tfunction updateScroll(){\n\t\t\t\tvar h=document.documentElement.scrollHeight-window.innerHeight;\n\t\t\t\tif(h>0){var pct=Math.round((window.scrollY/h)*100);if(pct>_maxScroll)_maxScroll=pct;}\n\t\t\t}\n\t\t\twindow.addEventListener('scroll',updateScroll,{passive:true});\n\n\t\t\t// Send beacon with fallback to fetch\n\t\t\tfunction send(url,data){\n\t\t\t\tvar payload=JSON.stringify(data);\n\t\t\t\tif(!navigator.sendBeacon(url,payload)){\n\t\t\t\t\tfetch(url,{method:'POST',body:payload,keepalive:true}).catch(function(){});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Track pageview with server-side deduplication nonce\n\t\t\tfunction t(){\n\t\t\t\tvar d={\n\t\t\t\t\tp:location.pathname+location.search,\n\t\t\t\t\tr:document.referrer,\n\t\t\t\t\tsw:screen.width,\n\t\t\t\t\tsh:screen.height,\n\t\t\t\t\tvw:window.innerWidth,\n\t\t\t\t\tvh:window.innerHeight,\n\t\t\t\t\tpr:window.devicePixelRatio||1,\n\t\t\t\t\ttz:new Date().getTimezoneOffset(),\n\t\t\t\t\tcs:window.matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light',\n\t\t\t\t\t// Bot detection signals\n\t\t\t\t\tbs:botSignals,\n\t\t\t\t\tbsc:botScore\n\t\t\t\t};\n\t\t\t\tif(navigator.connection){\n\t\t\t\t\td.ct=navigator.connection.effectiveType||'';\n\t\t\t\t\td.cd=navigator.connection.downlink||0;\n\t\t\t\t}\n\t\t\t\t// Use the nonce captured at parse time for server-side deduplication\n\t\t\t\tif(_nonce)d.n=_nonce;\n\t\t\t\tvar u=new URLSearchParams(location.search);\n\t\t\t\tif(u.get('s'))d.st=u.get('s');\n\t\t\t\tsend('/api/track',d);\n\t\t\t}\n\n\t\t\t// Exit beacon with time on page and web vitals\n\t\t\tvar pageStart=Date.now();\n\t\t\tfunction sendExit(){\n\t\t\t\tsend('/api/track/exit',{\n\t\t\t\t\tsid:sid,\n\t\t\t\t\ttop:Date.now()-pageStart,\n\t\t\t\t\tsd:_maxScroll,\n\t\t\t\t\tlcp:_lcp,\n\t\t\t\t\tfcp:_fcp,\n\t\t\t\t\tcls:Math.round(_cls*1000)/1000,\n\t\t\t\t\tttfb:_ttfb\n\t\t\t\t});\n\t\t\t}\n\t\t\tdocument.addEventListener('visibilitychange',function(){\n\t\t\t\tif(document.visibilityState==='hidden')sendExit();\n\t\t\t});\n\n\t\t\t// Track on load\n\t\t\tif(document.readyState==='complete'){t();}else{window.addEventListener('load',t);}\n\t\t})();\n\t</script>")
|
|
if templ_7745c5c3_Err != nil {
|
|
return templ_7745c5c3_Err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func themeInitScript(themeMode string) templ.Component {
|
|
switch themeMode {
|
|
case "light", "dark", "system":
|
|
default:
|
|
themeMode = "light"
|
|
}
|
|
// Precedence: admin toolbar override (per-tab, sessionStorage) → visitor
|
|
// preference (bn-theme cookie/localStorage) → site default → system.
|
|
// Exposed as window.bnApplyTheme so the toolbar theme tester can re-apply
|
|
// after changing the override without duplicating this resolution.
|
|
return templ.Raw(`<script>
|
|
window.bnApplyTheme=function(){
|
|
var t=null;try{t=sessionStorage.getItem('bn-theme-override')}catch(e){}
|
|
if(!t){
|
|
var c=document.cookie.match(/(?:^|; )bn-theme=([^;]*)/);
|
|
t=c?c[1]:localStorage.getItem('bn-theme');
|
|
}
|
|
if(!t)t='` + themeMode + `';
|
|
if(t==='system')t=window.matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light';
|
|
document.documentElement.classList.toggle('dark',t==='dark');
|
|
return t;
|
|
};
|
|
window.bnApplyTheme();
|
|
</script>`)
|
|
}
|
|
|
|
var _ = templruntime.GeneratedTemplate
|