Files
member-console/internal/embeds
cgalo5758 71818de0bd Add setup checklist and empty-state guidance
Implement the ux-first-run change: a state-derived setup checklist on
/operator/setup with a landing region that recedes once required steps
are done, and empty states that distinguish blocked from empty across
operator and member surfaces. Also add production deployment and
environment reference docs, plus a config-key completeness test.
2026-08-23 03:06:11 -05:00
..
2025-12-19 15:47:32 -06:00

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.

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

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:

<!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:

// 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

<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

<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

<button data-bs-toggle="modal" 
        data-bs-target="#createSiteModal"
        hx-get="/partials/fedwiki/create-form" 
        hx-target="#createSiteModalBody">
    Create Site
</button>

Conditional Button State

<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:

<!-- 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:

// 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

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

// Serve static files
staticFS, _ := fs.Sub(embeds.Static, "static")
http.Handle("/static/", http.FileServer(http.FS(staticFS)))