Compare commits
No commits in common. "main" and "v0.20.3" have entirely different histories.
43
AGENTS.md
43
AGENTS.md
@ -1,44 +1,9 @@
|
|||||||
# Core SDK
|
# Core SDK
|
||||||
|
|
||||||
Go module `git.dev.alexdunmow.com/block/core`.
|
Go module `git.dev.alexdunmow.com/block/core`. Shared Go code between the **CMS and the orchestrator** — template engine, block registry, shared types, proto definitions.
|
||||||
|
|
||||||
**Purpose: core exists ONLY for code that must be shared between first-party
|
|
||||||
BlockNinja entities** — the **CMS**, the **orchestrator**, the **ninja CLI**,
|
|
||||||
and any future entity that genuinely needs to share code with the others.
|
|
||||||
|
|
||||||
## Admission test
|
|
||||||
|
|
||||||
Before adding anything here, ask: **do two or more first-party entities need
|
|
||||||
this code?**
|
|
||||||
|
|
||||||
- Needed by only one entity → it belongs in that entity's repo, not core.
|
|
||||||
- Needed by plugins → it does NOT belong here (see below); plugins build
|
|
||||||
against the wasm ABI, whose contract the CMS owns (`cms/backend/abi/`,
|
|
||||||
`cms/docs/abi/`).
|
|
||||||
|
|
||||||
The standing direction (Captain, 2026-07-07) is to **shrink core**: prefer
|
|
||||||
moving code out to its single consumer over adding more in. When a package's
|
|
||||||
consumer count drops to one, migrate it out.
|
|
||||||
|
|
||||||
## Critical Rules
|
## Critical Rules
|
||||||
|
|
||||||
- **Core is NOT for plugins.** Plugins are standalone wasm artifacts built
|
- **Core is NOT for plugins.** Its only consumers are the CMS and the orchestrator; it exists purely to share code between those two. Plugins must not import `block/core` — in the wasm-plugin era they are standalone artifacts built against the wasm ABI, not this module. (Core was previously the plugin SDK; that role is gone.)
|
||||||
against the wasm ABI, not this module. (Core was previously the plugin SDK;
|
- **NEVER use `replace` directives in go.mod** — not in this repo, not in any consumer. All module resolution goes through the Gitea module proxy. If you need to test local changes, tag and push a version.
|
||||||
that role is gone, and remaining plugin-era surface is legacy to be worked
|
- All consumers are in-house — no backwards compatibility shims needed. Just change the API and update consumers.
|
||||||
off, not a precedent.)
|
|
||||||
- **NEVER use `replace` directives in go.mod** — not in this repo, not in any
|
|
||||||
consumer. All module resolution goes through the Gitea module proxy. If you
|
|
||||||
need to test local changes, tag and push a version.
|
|
||||||
- All consumers are in-house — no backwards compatibility shims needed. Just
|
|
||||||
change the API and update consumers.
|
|
||||||
|
|
||||||
## Special case: `templates/bn/` is a synced copy, do not author here
|
|
||||||
|
|
||||||
The bn page chrome (head / toolbar / engagement / asset_hooks) is **authored
|
|
||||||
in `cms/backend/templates/bn`** and mechanically copied here (`make
|
|
||||||
sync-templates` in cms) solely so guest-side plugin templates can compile it
|
|
||||||
into their wasm. check-safety check 31 fails cms commits while the copies
|
|
||||||
drift. Never edit these files here directly — change them in cms and sync.
|
|
||||||
`templates/bn/validation.go` is intentionally divergent (cms's version bridges
|
|
||||||
the SDK ValidationTracker under both context keys) and is NOT part of the sync
|
|
||||||
set. Spec: cms `docs/superpowers/specs/2026-07-07-bn-chrome-single-source-design.md`.
|
|
||||||
|
|||||||
35
README.md
35
README.md
@ -1,19 +1,8 @@
|
|||||||
# BlockNinja Core
|
# BlockNinja Core
|
||||||
|
|
||||||
Go code shared between first-party BlockNinja entities: the **CMS**, the
|
Shared Go code between the BlockNinja CMS and the orchestrator: types, interfaces, and utilities both need.
|
||||||
**orchestrator**, the **ninja CLI**, and any future entity that genuinely
|
|
||||||
needs to share code with the others.
|
|
||||||
|
|
||||||
> **Scope rule:** core is ONLY for code needed by **two or more** of those
|
> **Not a plugin SDK.** Core is purely for sharing code between the CMS and the orchestrator. Plugins must **not** import `block/core` — in the wasm-plugin era they are standalone artifacts built against the wasm ABI. (Core previously served as the plugin SDK; that role is gone.)
|
||||||
> entities. Code with a single consumer belongs in that consumer's repo. The
|
|
||||||
> standing direction is to shrink core — when a package's consumer count drops
|
|
||||||
> to one, it gets migrated out.
|
|
||||||
|
|
||||||
> **Not a plugin SDK.** Plugins must **not** treat `block/core` as their SDK —
|
|
||||||
> in the wasm-plugin era they are standalone artifacts built against the wasm
|
|
||||||
> ABI (owned by the CMS: `cms/backend/abi/`, `cms/docs/abi/`). Core previously
|
|
||||||
> served as the plugin SDK; that role is gone, and remaining plugin-era
|
|
||||||
> surface here is legacy to be worked off, not a precedent.
|
|
||||||
|
|
||||||
## Package Structure
|
## Package Structure
|
||||||
|
|
||||||
@ -23,7 +12,7 @@ needs to share code with the others.
|
|||||||
| `blocks/` | BlockMeta, BlockFunc, BlockRegistry interface, BlockContext |
|
| `blocks/` | BlockMeta, BlockFunc, BlockRegistry interface, BlockContext |
|
||||||
| `blocks/builtin/` | Reusable block implementations (HTMLBlock) |
|
| `blocks/builtin/` | Reusable block implementations (HTMLBlock) |
|
||||||
| `templates/` | TemplateRegistry interface |
|
| `templates/` | TemplateRegistry interface |
|
||||||
| `templates/bn/` | Synced copy of the cms-authored bn chrome (see below) |
|
| `templates/bn/` | Shared templ components (head, engagement, toolbar) |
|
||||||
| `auth/` | Claims types, context extractors |
|
| `auth/` | Claims types, context extractors |
|
||||||
| `content/` | Content access interface |
|
| `content/` | Content access interface |
|
||||||
| `settings/` | Settings access interface |
|
| `settings/` | Settings access interface |
|
||||||
@ -34,20 +23,10 @@ needs to share code with the others.
|
|||||||
| `ai/` | AI tool registry interface and types |
|
| `ai/` | AI tool registry interface and types |
|
||||||
| `rbac/` | Role type definition |
|
| `rbac/` | Role type definition |
|
||||||
|
|
||||||
### `templates/bn/` is a synced copy — do not edit here
|
|
||||||
|
|
||||||
The bn page chrome (head / toolbar / engagement / asset_hooks) is authored in
|
|
||||||
`cms/backend/templates/bn` and copied here via the cms `make sync-templates`
|
|
||||||
target, solely so guest-side plugin templates can compile it into their wasm.
|
|
||||||
check-safety (check 31) fails cms commits while the copies drift. Change the
|
|
||||||
chrome in cms, sync, then commit + tag + push here.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```go
|
Consumers are the CMS and the orchestrator only.
|
||||||
import "git.dev.alexdunmow.com/block/core/blocks"
|
|
||||||
```
|
|
||||||
|
|
||||||
Versioned via git tags through the Gitea module proxy — never `replace`
|
```go
|
||||||
directives. All consumers are in-house; no backwards-compatibility shims —
|
import "git.dev.alexdunmow.com/block/core/plugin"
|
||||||
change the API and update the consumers.
|
```
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ type RedeemResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
secret atomic.Pointer[[]byte]
|
secret []byte
|
||||||
count, size, d int
|
count, size, d int
|
||||||
challengeTTL time.Duration
|
challengeTTL time.Duration
|
||||||
tokenTTL time.Duration
|
tokenTTL time.Duration
|
||||||
@ -60,6 +59,7 @@ func WithUsedTokenStore(ns NonceStore) Option { return func(sv *Server) { sv.use
|
|||||||
// 32-char salts, difficulty 4, 10-min challenge / 5-min token expiry.
|
// 32-char salts, difficulty 4, 10-min challenge / 5-min token expiry.
|
||||||
func New(secret []byte, opts ...Option) *Server {
|
func New(secret []byte, opts ...Option) *Server {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
|
secret: secret,
|
||||||
count: 50,
|
count: 50,
|
||||||
size: 32,
|
size: 32,
|
||||||
d: 4,
|
d: 4,
|
||||||
@ -68,20 +68,12 @@ func New(secret []byte, opts ...Option) *Server {
|
|||||||
nonces: NewMemoryNonceStore(),
|
nonces: NewMemoryNonceStore(),
|
||||||
usedTokens: NewMemoryNonceStore(),
|
usedTokens: NewMemoryNonceStore(),
|
||||||
}
|
}
|
||||||
s.secret.Store(&secret)
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(s)
|
o(s)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) secretBytes() []byte { return *s.secret.Load() }
|
|
||||||
|
|
||||||
// SetSecret swaps the HMAC secret at runtime. Outstanding challenge and
|
|
||||||
// verification tokens signed with the old secret immediately fail
|
|
||||||
// verification, so callers can use this to invalidate all issued tokens.
|
|
||||||
func (s *Server) SetSecret(secret []byte) { s.secret.Store(&secret) }
|
|
||||||
|
|
||||||
func (s *Server) CreateChallenge() (ChallengeResponse, error) {
|
func (s *Server) CreateChallenge() (ChallengeResponse, error) {
|
||||||
buf := make([]byte, 25)
|
buf := make([]byte, 25)
|
||||||
if _, err := rand.Read(buf); err != nil {
|
if _, err := rand.Read(buf); err != nil {
|
||||||
@ -89,7 +81,7 @@ func (s *Server) CreateChallenge() (ChallengeResponse, error) {
|
|||||||
}
|
}
|
||||||
nonce := hex.EncodeToString(buf)
|
nonce := hex.EncodeToString(buf)
|
||||||
expires := nowMs() + s.challengeTTL.Milliseconds()
|
expires := nowMs() + s.challengeTTL.Milliseconds()
|
||||||
token := makeChallengeToken(s.secretBytes(), nonce, expires, s.count, s.size, s.d)
|
token := makeChallengeToken(s.secret, nonce, expires, s.count, s.size, s.d)
|
||||||
return ChallengeResponse{
|
return ChallengeResponse{
|
||||||
Challenge: Challenge{C: s.count, S: s.size, D: s.d},
|
Challenge: Challenge{C: s.count, S: s.size, D: s.d},
|
||||||
Token: token,
|
Token: token,
|
||||||
@ -98,7 +90,7 @@ func (s *Server) CreateChallenge() (ChallengeResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Redeem(token string, solutions []string) RedeemResponse {
|
func (s *Server) Redeem(token string, solutions []string) RedeemResponse {
|
||||||
claims := verifyChallengeToken(s.secretBytes(), token)
|
claims := verifyChallengeToken(s.secret, token)
|
||||||
if claims == nil {
|
if claims == nil {
|
||||||
return RedeemResponse{Success: false}
|
return RedeemResponse{Success: false}
|
||||||
}
|
}
|
||||||
@ -119,7 +111,7 @@ func (s *Server) Redeem(token string, solutions []string) RedeemResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expires := nowMs() + s.tokenTTL.Milliseconds()
|
expires := nowMs() + s.tokenTTL.Milliseconds()
|
||||||
vt, err := makeVerificationToken(s.secretBytes(), expires)
|
vt, err := makeVerificationToken(s.secret, expires)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RedeemResponse{Success: false}
|
return RedeemResponse{Success: false}
|
||||||
}
|
}
|
||||||
@ -140,7 +132,7 @@ func (s *Server) Redeem(token string, solutions []string) RedeemResponse {
|
|||||||
// fragment that still carries the widget (with its reset flow) lets the visitor
|
// fragment that still carries the widget (with its reset flow) lets the visitor
|
||||||
// re-solve and retry — callers MUST keep the widget present on rejection paths.
|
// re-solve and retry — callers MUST keep the widget present on rejection paths.
|
||||||
func (s *Server) VerifyToken(token string) bool {
|
func (s *Server) VerifyToken(token string) bool {
|
||||||
claims := parseVerificationToken(s.secretBytes(), token)
|
claims := parseVerificationToken(s.secret, token)
|
||||||
if claims == nil {
|
if claims == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
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 }
|
|
||||||
@ -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: `engagement.templ`, Line: 30, Col: 63}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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 {
|
||||||
|
|||||||
@ -16,56 +16,22 @@ 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
|
||||||
Favicon96 string // /.brand/{id}/favicon-96x96.png
|
AppleTouchIcon string // /brand/{id}/apple-touch-icon.png (180x180)
|
||||||
AppleTouchIcon string // /.brand/{id}/apple-touch-icon.png (180x180)
|
Android192 string // /brand/{id}/android-chrome-192x192.png
|
||||||
Android192 string // /.brand/{id}/android-chrome-192x192.png
|
Android512 string // /brand/{id}/android-chrome-512x512.png
|
||||||
Android512 string // /.brand/{id}/android-chrome-512x512.png
|
Maskable512 string // /brand/{id}/maskable-512x512.png
|
||||||
Maskable512 string // /.brand/{id}/maskable-512x512.png
|
Master1024 string // /brand/{id}/icon-1024x1024.png
|
||||||
Master1024 string // /.brand/{id}/icon-1024x1024.png
|
ManifestURL string // /brand/{id}/site.webmanifest
|
||||||
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
|
||||||
@ -75,9 +41,8 @@ type SiteSettingsData struct {
|
|||||||
LogoAlt string
|
LogoAlt string
|
||||||
AppleTouchIcon string
|
AppleTouchIcon string
|
||||||
GoogleAnalyticsID string
|
GoogleAnalyticsID string
|
||||||
CustomScripts []CustomScriptEntry
|
CustomHeadScripts string
|
||||||
GoogleAnalyticsEnabled bool
|
CustomBodyScripts string
|
||||||
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
|
||||||
@ -102,10 +67,6 @@ 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
|
||||||
@ -198,75 +159,15 @@ 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 {
|
||||||
legacyHeadScripts = v
|
settings.CustomHeadScripts = v
|
||||||
}
|
}
|
||||||
if v, ok := analyticsData["custom_body_scripts"].(string); ok {
|
if v, ok := analyticsData["custom_body_scripts"].(string); ok {
|
||||||
legacyBodyScripts = v
|
settings.CustomBodyScripts = 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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,18 +209,6 @@ 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)
|
||||||
@ -387,18 +276,6 @@ 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
|
||||||
}
|
}
|
||||||
@ -433,12 +310,6 @@ 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
|
||||||
}
|
}
|
||||||
@ -519,30 +390,15 @@ 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 (modern RFG-parity set; SVG first)
|
// Use generated brand assets
|
||||||
if data.Settings.Branding.SVG != "" {
|
|
||||||
<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="16x16" href={ data.Settings.Branding.Favicon16 }/>
|
|
||||||
<link rel="icon" type="image/x-icon" href={ data.Settings.Branding.FaviconICO }/>
|
<link rel="icon" type="image/x-icon" href={ data.Settings.Branding.FaviconICO }/>
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href={ data.Settings.Branding.Favicon16 }/>
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href={ data.Settings.Branding.Favicon32 }/>
|
||||||
<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 != "" {
|
||||||
@ -562,9 +418,9 @@ templ Head(data HeadData) {
|
|||||||
<meta name="description" content={ data.Settings.MetaDescription }/>
|
<meta name="description" content={ data.Settings.MetaDescription }/>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canonical URL: admin override (resolved to absolute) → auto self-canonical (M8)
|
// Canonical URL (page-level only, no site default)
|
||||||
if canonical := canonicalURL(data.PageMeta.CanonicalURL, data.PageMeta.PageURL); canonical != "" {
|
if data.PageMeta.CanonicalURL != "" {
|
||||||
<link rel="canonical" href={ canonical }/>
|
<link rel="canonical" href={ data.PageMeta.CanonicalURL }/>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Robots directive (page-level only - defaults to index,follow if not set)
|
// Robots directive (page-level only - defaults to index,follow if not set)
|
||||||
@ -603,25 +459,8 @@ templ Head(data HeadData) {
|
|||||||
<meta property="og:image" content={ resolveMediaURL(data.Settings.DefaultOGImage) }/>
|
<meta property="og:image" content={ resolveMediaURL(data.Settings.DefaultOGImage) }/>
|
||||||
}
|
}
|
||||||
|
|
||||||
// og:type: article for posts, website otherwise (M5)
|
// og:type - default to website
|
||||||
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 != "" {
|
||||||
@ -673,7 +512,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 != "" && (data.Settings.GoogleAnalyticsEnabled || !data.Settings.GoogleAnalyticsExplicitlySet) {
|
if data.Settings.GoogleAnalyticsID != "" {
|
||||||
<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)
|
||||||
}
|
}
|
||||||
@ -682,16 +521,14 @@ 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={ VersionedAssetURL(style) }/>
|
<link rel="stylesheet" href={ 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)
|
||||||
}
|
}
|
||||||
for _, script := range data.Settings.CustomScripts {
|
if data.Settings.CustomHeadScripts != "" {
|
||||||
if script.Enabled && script.Placement == "head" {
|
@templ.Raw(data.Settings.CustomHeadScripts)
|
||||||
@templ.Raw(script.Code)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if data.StructuredData != "" {
|
if data.StructuredData != "" {
|
||||||
@structuredDataScript(data.StructuredData)
|
@structuredDataScript(data.StructuredData)
|
||||||
@ -733,10 +570,8 @@ 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")
|
||||||
for _, script := range settings.CustomScripts {
|
if settings.CustomBodyScripts != "" {
|
||||||
if script.Enabled && script.Placement == "body" {
|
@templ.Raw(settings.CustomBodyScripts)
|
||||||
@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)
|
||||||
@ -944,6 +779,7 @@ 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
@ -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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 301, Col: 38}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 311, Col: 73}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 313, Col: 80}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 323, Col: 170}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 435, Col: 46}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 443, Col: 62}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 460, Col: 63}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 473, Col: 46}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 474, Col: 38}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 515, Col: 91}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 519, Col: 25}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 519, Col: 73}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 535, Col: 61}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 535, Col: 100}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 537, Col: 50}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 542, Col: 86}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 546, Col: 84}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 554, Col: 48}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 558, Col: 59}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 563, Col: 44}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 569, Col: 43}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 575, Col: 45}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 597, Col: 67}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 625, Col: 62}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 646, Col: 71}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 649, Col: 15}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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: `toolbar.templ`, Line: 1, Col: 0}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/bn/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 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user