# 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.
