226 lines
5.2 KiB
Markdown
226 lines
5.2 KiB
Markdown
# Embedded Assets
|
|
|
|
This package provides embedded static files, templates, and configuration using Go's `embed` directive.
|
|
|
|
## Overview
|
|
|
|
All assets are embedded at compile time, producing a single binary with no external file dependencies.
|
|
|
|
```go
|
|
package embeds
|
|
|
|
//go:embed static
|
|
var Static embed.FS
|
|
|
|
//go:embed templates
|
|
var Templates embed.FS
|
|
|
|
//go:embed mc-config.yaml
|
|
var Config embed.FS
|
|
```
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
internal/embeds/
|
|
├── embeds.go # Embed directives
|
|
├── mc-config.yaml # Default configuration template
|
|
├── static/ # Static assets (CSS, JS, images)
|
|
│ ├── bootstrap.css
|
|
│ ├── bootstrap.bundle.js
|
|
│ ├── htmx.min.js
|
|
│ └── favicon*.png
|
|
└── templates/ # HTML templates
|
|
├── index.html # Main page template
|
|
└── partials/ # HTMX partial templates
|
|
├── fedwiki_sites.html
|
|
├── fedwiki_create_form.html
|
|
├── fedwiki_create_success.html
|
|
├── fedwiki_delete_confirm.html
|
|
└── fedwiki_delete_success.html
|
|
```
|
|
|
|
## Static Assets
|
|
|
|
### Serving Static Files
|
|
|
|
```go
|
|
staticFS, _ := fs.Sub(embeds.Static, "static")
|
|
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticFS))))
|
|
```
|
|
|
|
### Included Libraries
|
|
|
|
- `bootstrap.css` (5.3.x) - CSS framework
|
|
- `bootstrap.bundle.js` (5.3.x) - Bootstrap JS (includes Popper)
|
|
- `htmx.min.js` (2.0.4) - HTMX for dynamic content
|
|
|
|
### Favicons
|
|
|
|
Standard favicon set for various platforms:
|
|
- `favicon.ico` - Traditional favicon
|
|
- `favicon-16x16.png`, `favicon-32x32.png` - Standard sizes
|
|
- `apple-touch-icon.png` - iOS home screen
|
|
- `android-chrome-*.png` - Android home screen
|
|
- `site.webmanifest` - PWA manifest
|
|
|
|
## Templates
|
|
|
|
### Main Page Template (`index.html`)
|
|
|
|
The full HTML page that serves as the application shell:
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<!-- Meta, CSS, HTMX -->
|
|
</head>
|
|
<body>
|
|
<!-- Navigation -->
|
|
|
|
<!-- Content sections with HTMX triggers -->
|
|
<div hx-get="/partials/fedwiki/sites"
|
|
hx-trigger="load, refreshSites from:body">
|
|
<!-- Loading spinner -->
|
|
</div>
|
|
|
|
<!-- Modals -->
|
|
<div class="modal" id="createSiteModal">...</div>
|
|
|
|
<!-- Scripts -->
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
### Partial Templates (`partials/`)
|
|
|
|
HTML fragments returned by HTMX handlers. These are **not** full pages.
|
|
|
|
#### Naming Convention
|
|
|
|
```
|
|
{feature}_{action}.html
|
|
```
|
|
|
|
Examples:
|
|
- `fedwiki_sites.html` - Sites list display
|
|
- `fedwiki_create_form.html` - Site creation form
|
|
- `fedwiki_create_success.html` - Creation success message
|
|
- `fedwiki_delete_confirm.html` - Delete confirmation dialog
|
|
- `fedwiki_delete_success.html` - Deletion success message
|
|
|
|
#### Template Data Pattern
|
|
|
|
Each partial has a corresponding Go struct for its data:
|
|
|
|
```go
|
|
// In fedwiki_partials.go
|
|
type SitesData struct {
|
|
Sites []SiteViewModel
|
|
CurrentCount int64
|
|
Quota int64
|
|
IsMember bool
|
|
CanCreate bool
|
|
Error string
|
|
}
|
|
```
|
|
|
|
### HTMX Patterns in Templates
|
|
|
|
#### Loading Content on Page Load
|
|
|
|
```html
|
|
<div hx-get="/partials/fedwiki/sites"
|
|
hx-trigger="load, refreshSites from:body"
|
|
hx-swap="innerHTML">
|
|
<!-- Initial loading spinner -->
|
|
<div class="spinner-border"></div>
|
|
</div>
|
|
```
|
|
|
|
#### Form Submission
|
|
|
|
```html
|
|
<form hx-post="/partials/fedwiki/sites"
|
|
hx-swap="innerHTML"
|
|
hx-target="#createSiteModalBody">
|
|
<!-- Form fields -->
|
|
<button type="submit">
|
|
<span class="spinner-border d-none" id="spinner"></span>
|
|
Create Site
|
|
</button>
|
|
</form>
|
|
```
|
|
|
|
#### Loading Button into Modal
|
|
|
|
```html
|
|
<button data-bs-toggle="modal"
|
|
data-bs-target="#createSiteModal"
|
|
hx-get="/partials/fedwiki/create-form"
|
|
hx-target="#createSiteModalBody">
|
|
Create Site
|
|
</button>
|
|
```
|
|
|
|
#### Conditional Button State
|
|
|
|
```html
|
|
<button {{ if .CanCreate }}
|
|
hx-get="/partials/fedwiki/create-form"
|
|
{{ else }}
|
|
disabled title="Site limit reached"
|
|
{{ end }}>
|
|
Create Site
|
|
</button>
|
|
```
|
|
|
|
### Spinner Pattern
|
|
|
|
Spinners are hidden by default and shown during HTMX requests:
|
|
|
|
```html
|
|
<!-- CSS to show spinner during request -->
|
|
<style>.htmx-request #createSpinner { display: inline-block !important; }</style>
|
|
|
|
<!-- Spinner hidden by default -->
|
|
<span class="spinner-border d-none" id="createSpinner"></span>
|
|
```
|
|
|
|
The `htmx-request` class is automatically added to elements during requests.
|
|
|
|
## Configuration Template
|
|
|
|
`mc-config.yaml` provides a default configuration template that can be extracted:
|
|
|
|
```go
|
|
// Extract default config
|
|
configData, _ := embeds.Config.ReadFile("mc-config.yaml")
|
|
```
|
|
|
|
This is used by the `init` command to create a starter configuration file.
|
|
|
|
## Usage
|
|
|
|
### Accessing Templates
|
|
|
|
```go
|
|
import "git.coopcloud.tech/wiki-cafe/member-console/internal/embeds"
|
|
|
|
// For full page templates
|
|
tmpl, err := template.ParseFS(embeds.Templates, "templates/index.html")
|
|
|
|
// For partial templates
|
|
partialFS, _ := fs.Sub(embeds.Templates, "templates/partials")
|
|
tmpl, err := template.ParseFS(partialFS, "*.html")
|
|
```
|
|
|
|
### Accessing Static Files
|
|
|
|
```go
|
|
// Serve static files
|
|
staticFS, _ := fs.Sub(embeds.Static, "static")
|
|
http.Handle("/static/", http.FileServer(http.FS(staticFS)))
|
|
```
|