website-htmx-rustelo-code/README.md
2026-07-10 03:44:13 +01:00

357 lines
No EOL
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Website Implementation - Rustelo Framework
A complete **content website with code highlighting** built using the Rustelo framework, demonstrating modern multi-crate architecture and PAP compliance.
## 🎯 Project Overview
This implementation validates Rustelo's project generation capabilities and serves as a reference for content websites that need code display features.
### Key Features
- **Multi-crate architecture**: Client, server, shared, pages with build.rs integration
- **Type-safe configuration**: Nickel (NCL) for routes, themes, menus with compile-time validation
- **Bilingual single-source**: Zero duplication - EN/ES in one file
- **Code highlighting**: Complete syntax highlighting with copy functionality
- **Language-agnostic**: Supports any language without code changes
- **Smart caching**: Multi-layer cache system for incremental builds
- **PAP compliant**: Follows Rustelo's Project Architecture Principles
## 🚀 Quick Start
### Prerequisites
- **Rust 1.75+** - Core language and toolchain
- **Node.js 18+** - Frontend tooling
- **Nickel** (Configuration language) - **REQUIRED** for type-safe configuration
- macOS: `brew install nickel`
- Linux/Windows: `cargo install nickel-lang-cli`
- See [Nickel Installation Guide](../../docs/guides/nickel-installation.md)
- Site content in `../site/` directory
> **Note**: This project uses Nickel (NCL) for all configuration files (routes, themes, menus, content types). See [NCL Configuration](#-ncl-configuration) section below.
### Setup & Development
```bash
# Install dependencies
just setup
# Start development server with hot reload
just dev
# Build for production
just build-prod
```
### Development Commands
```bash
# Development
just dev # Hot reload with CSS watching
just dev-server # Rust only (no CSS watching)
just dev-css # CSS watching only
# Building
just build # Development build
just build-prod # Production build
just build-rust # Rust components only
just build-css # CSS only
# Quality & Testing
just quality # All quality checks
just test # Run tests
just format # Format code
just lint # Lint code
# Content & Deployment
just validate-content # Validate site content
just deploy-staging # Deploy to staging
just status # Project status
```
## 🏗️ Architecture
### Multi-Crate Structure
```
website-impl/
├── crates/
│ ├── shared/ # Route generation & shared types
│ ├── pages/ # Custom page component generation
│ ├── client/ # WASM frontend with asset processing
│ ├── server/ # Axum backend with configuration
│ └── plugin-example-theme/ # Example plugin (theme + i18n)
├── config.toml # Application configuration
├── uno.config.ts # UnoCSS configuration (synced with @website)
├── package.json # Code highlighting & build tools
├── justfile # Development automation
└── scripts/ # Build scripts for themes & highlighting
```
## 🔌 Plugin System
This implementation demonstrates Rustelo's **Level 5 Plugin Architecture** - a trait-based plugin system for unlimited extensibility without framework coupling.
### Included Plugins
- **WebsiteResourceContributor** (core): Provides themes, menus, and i18n
- **plugin-example-theme** (example): Complete working theme plugin with tests
### Plugin Features
-**ResourceContributor Trait**: Contribute themes, menus, translations
-**Type-Safe Registration**: Compile-time validation
-**Zero Conditional Compilation**: Framework code is pure Rust
-**Configuration-Driven**: Resources from TOML/FTL files
-**Self-Contained**: Plugins are independent crates
### Creating Custom Plugins
**Step 1: Create plugin crate**
```bash
cd crates/
cargo new --lib my-custom-plugin
```
**Step 2: Implement ResourceContributor**
```rust
use rustelo_core_lib::registration::ResourceContributor;
pub struct MyPlugin;
impl ResourceContributor for MyPlugin {
fn contribute_themes(&self) -> HashMap<String, String> {
let mut themes = HashMap::new();
themes.insert("my-theme".to_string(),
include_str!("../config/themes/my-theme.toml").to_string());
themes
}
fn name(&self) -> &str {
"my-plugin"
}
}
```
**Step 3: Add to workspace**
- Add to main `Cargo.toml` workspace members
- Create configuration files in `config/themes/` and `config/i18n/`
**Step 4: Register at startup**
```rust
// In crates/server/src/resources.rs
rustelo_core_lib::register_contributor(&MyPlugin)?;
```
### Plugin Types
| Type | Purpose | Example |
|------|---------|---------|
| **Resource-Only** | Themes, menus, translations | Custom theme plugin |
| **Page Provider** | Custom page components | Analytics dashboard |
| **Composite** | Resources + pages | Feature module |
### Example Plugin Walkthrough
See `crates/plugin-example-theme/` for a complete, production-ready example:
- Analytics dashboard theme configuration
- English and Spanish translations
- 10/10 passing unit tests
- Comprehensive documentation
### Plugin Documentation
- **Quick Start**: See this README's "Creating Custom Plugins" section above
- **Complete Guide**: [Plugin Development Guide](../../.coder/info/PHASE3-PLUGIN-DEVELOPMENT-GUIDE.md)
- **Architecture**: [Rustelo Plugin Architecture](../../docs/architecture/rustelo-plugin-architecture.md)
- **Example Plugin**: `./crates/plugin-example-theme/README.md`
## 🎨 Code Highlighting Features
### Syntax Highlighting
- **highlight.js**: Multi-language syntax highlighting
- **highlightjs-copy**: One-click code copying
- **Theme system**: Light/dark mode with custom themes
- **UnoCSS integration**: Built-in code styling with design system
### Design System Integration
Uses complete design system from @website:
- `ds-*` prefixed utility classes
- Theme variables for consistent styling
- Built-in dark mode support
- Code block styling with proper contrast
## 📝 NCL Configuration
This project uses **Nickel (NCL)** for type-safe, DRY configuration. All configuration files use `.ncl` format with TOML fallback support.
### Why NCL?
**Type Safety**: Compile-time validation catches errors before runtime
**Zero Duplication**: Bilingual configs in single file (no separate en.toml/es.toml)
**DRY Principles**: Shared defaults and helper functions
**Better Tooling**: Syntax highlighting, LSP support, validation
### Configuration Files
```
site/
├── schemas/ # Reusable NCL type definitions
│ ├── content/
│ │ ├── contracts.ncl # Type contracts for content
│ │ └── defaults.ncl # Shared defaults + helpers
│ ├── menus/
│ │ ├── contracts.ncl
│ │ └── defaults.ncl
│ ├── footer/
│ │ ├── contracts.ncl
│ │ └── defaults.ncl
│ └── themes/
│ ├── contracts.ncl
│ └── defaults.ncl
├── config/
│ └── themes/
│ ├── default.ncl # Default theme
│ └── dark.ncl # Dark theme variant
├── content/
│ └── content-kinds.ncl # Content type definitions
└── ui/
├── menus/
│ └── menu.ncl # Navigation menu (bilingual)
└── footer/
└── footer.ncl # Footer config (bilingual)
```
### Example: Bilingual Menu (Before vs After)
**Before (TOML - 130 lines across 2 files):**
```toml
# en.toml
[[items]]
route = "/services"
label = "Services"
# es.toml
[[items]]
route = "/servicios"
label = "Servicios"
```
**After (NCL - 115 lines, single file):**
```nickel
{
items = [
make_menu_item {
routes = { en = "/services", es = "/servicios" },
labels = { en = "Services", es = "Servicios" },
},
]
}
```
### Working with NCL Configs
**Export to JSON:**
```bash
nickel export --format json site/ui/menus/menu.ncl | jq '.'
```
**Validate:**
```bash
nickel typecheck site/ui/menus/menu.ncl
```
**Auto-Detection:**
Build system automatically prefers `.ncl` files over `.toml`:
```
site/config/themes/dark.ncl ✅ Used
site/config/themes/dark.toml ⏭️ Ignored (fallback)
```
### Documentation
- **Configuration Guide**: [../../docs/guides/nickel-configuration-guide.md](../../docs/guides/nickel-configuration-guide.md)
- **Installation**: [../../docs/guides/nickel-installation.md](../../docs/guides/nickel-installation.md)
- **ADR**: [../../docs/adr/0002-nickel-configuration-language.md](../../docs/adr/0002-nickel-configuration-language.md)
- **Implementation Summary**: [./.coder/info/summaries/2026-02-09-nickel-config-implementation-complete.md](./.coder/info/summaries/2026-02-09-nickel-config-implementation-complete.md)
### Metrics
| Config Type | Lines | Duplication Reduced |
|-------------|-------|---------------------|
| Content-Kinds | 29 | ~60% less |
| Menus | 115 | 100% (bilingual) |
| Footers | 63 | 29% smaller |
| Themes | 4 × 14 | Variants from base |
**Total**: ~140 lines of config + ~920 lines of reusable schemas
---
## 🔧 Configuration
### Site Integration
```toml
# Links to site content structure
[content]
root_path = "../site" # Site content directory
public_path = "../site/public" # Static assets
content_url = "/content" # Content API URL
types = ["blog", "recipes"] # Available content types
languages = ["en", "es"] # Supported languages
default_language = "en" # Default language
```
## 🧪 PAP Compliance
**Configuration-driven**: All routes, themes, menus from NCL files with type-safety
**Language-agnostic**: No hardcoded languages, bilingual single-source configs
**Custom routing**: Uses Rustelo routing, NOT Leptos router
**Error handling**: Proper Result<T, E> patterns, no unwrap()
**Modular design**: Feature-based architecture with plugin system
**Type-safe configuration**: Nickel contracts validate at compile-time
**No hardcoding**: All paths and routes configurable
**Self-describing**: Architecture tracked via on+re protocol — `.ontology/` + `adrs/`
## 🔍 Architecture Self-Description (on+re)
This project implements the [Ontoref](https://github.com/ontoref) `on+re` protocol. The `.ontology/` and `adrs/` directories provide a machine- and agent-readable description of the project's architecture, current state, and invariants as a Rustelo consumer (Service kind).
### `.ontology/` files
| File | Contents |
|------|---------|
| `core.ncl` | Knowledge graph: axioms (`rustelo-consumer`, `bilingual-content`), tensions (hydration complexity, build-time vs runtime), project nodes |
| `state.ncl` | State dimensions: `deployment-readiness` (pre-production), `hydration-stability` (zero-mismatch), `auth-system` (operational), `css-pipeline` (correct) |
| `gate.ncl` | Membranes: `hydration-parity` (Low permeability), `content-integrity` (Medium), `rbac-correctness` (Low) |
| `manifest.ncl` | Service manifest: EndUser, Developer, Agent consumption modes; implementation, content, self-description layers |
### ADR System (`adrs/`)
| ADR | Decision |
|-----|---------|
| `adr-001` | NCL (Nickel) over TOML for site configuration |
| `adr-002` | SsrTranslator in both SSR and WASM targets for hydration parity — 4 hard constraints |
| `adr-003` | WebSocket broadcast for RBAC hot-reload without server restart |
### Browsing the architecture
```bash
# What this project is and how it can be consumed
nickel export .ontology/manifest.ncl
# Current state across all tracked dimensions
nickel export .ontology/state.ncl
# Active architecture constraints and gates
nickel export .ontology/gate.ncl
# Cross-project: browse Rustelo framework capabilities
# (rustelo-browse operational mode in manifest.ncl)
nickel export ../../rustelo/.ontology/core.ncl
```
## 📖 Documentation
- **Setup Guide**: `info/setup_from_rustelo_plan.md` - Complete implementation journey
- **Enhancements**: `info/enhancements/` - Proposed improvements for Rustelo
## 📄 License
MIT License - Part of the Rustelo framework ecosystem.