Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
475 lines
13 KiB
Markdown
475 lines
13 KiB
Markdown
# Creating a Site with Rustelo Framework
|
|
|
|
This guide provides step-by-step instructions for creating a new website project using Rustelo as a framework dependency.
|
|
|
|
## 🎯 Overview
|
|
|
|
Rustelo follows a **framework-as-dependency** architecture, meaning you don't fork the framework - you use it as a library dependency in your own project. This ensures you can:
|
|
|
|
- ✅ Get framework updates automatically
|
|
- ✅ Keep your customizations separate from framework code
|
|
- ✅ Use the asset fallback system (Local → Framework → Generated)
|
|
- ✅ Avoid maintaining a fork
|
|
|
|
## 📋 Prerequisites
|
|
|
|
- Rust 1.70+ installed
|
|
- Node.js 18+ (for frontend assets)
|
|
- Just task runner: `cargo install just`
|
|
- Git (recommended for version control)
|
|
|
|
## 🚀 Step-by-Step Guide
|
|
|
|
### Step 1: Create Your Project Directory
|
|
|
|
```bash
|
|
# Create your site project
|
|
mkdir my-awesome-site
|
|
cd my-awesome-site
|
|
|
|
# Initialize git repository (optional but recommended)
|
|
git init
|
|
```
|
|
|
|
### Step 2: Create Cargo.toml
|
|
|
|
Create a `Cargo.toml` file with Rustelo dependencies:
|
|
|
|
```toml
|
|
[package]
|
|
name = "my-awesome-site"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
authors = ["Your Name <your.email@example.com>"]
|
|
description = "My awesome site built with Rustelo framework"
|
|
|
|
# Main binary
|
|
[[bin]]
|
|
name = "server"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
# Core Rustelo framework dependencies
|
|
rustelo-core = { path = "../rustelo/crates/rustelo-core" }
|
|
rustelo-web = { path = "../rustelo/crates/rustelo-web" }
|
|
|
|
# Optional framework components (uncomment as needed)
|
|
# rustelo-auth = { path = "../rustelo/crates/rustelo-auth" }
|
|
# rustelo-content = { path = "../rustelo/crates/rustelo-content" }
|
|
|
|
# Web framework essentials
|
|
leptos = { version = "0.8.6", features = ["ssr"] }
|
|
leptos_axum = "0.8.5"
|
|
axum = "0.8.4"
|
|
tokio = { version = "1.47.1", features = ["rt-multi-thread", "signal"] }
|
|
tower = "0.5.2"
|
|
tower-http = { version = "0.6.6", features = ["fs"] }
|
|
|
|
# Basic utilities
|
|
tracing = "0.1"
|
|
tracing-subscriber = "0.3"
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
|
|
[features]
|
|
default = []
|
|
|
|
# Optional features (enable as needed)
|
|
# auth = ["rustelo-auth"]
|
|
# content = ["rustelo-content"]
|
|
# database = ["rustelo-core/database"]
|
|
|
|
[profile.release]
|
|
codegen-units = 1
|
|
lto = true
|
|
opt-level = 'z'
|
|
|
|
# Leptos configuration for development server
|
|
[[workspace.metadata.leptos]]
|
|
name = "my-awesome-site"
|
|
bin-package = "my-awesome-site"
|
|
bin-target-path = "src/main.rs"
|
|
lib-profile-release = "wasm-release"
|
|
```
|
|
|
|
### Step 3: Create Source Code Structure
|
|
|
|
```bash
|
|
# Create source directory
|
|
mkdir -p src
|
|
|
|
# Create basic directory structure
|
|
mkdir -p {content,assets,config,justfiles,public}
|
|
```
|
|
|
|
### Step 4: Create Main Application File
|
|
|
|
Create `src/main.rs`:
|
|
|
|
```rust
|
|
//! My Awesome Site - Built with Rustelo Framework
|
|
//!
|
|
//! This demonstrates using Rustelo as a framework dependency for a production site.
|
|
|
|
use axum::{
|
|
response::Html,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use rustelo_core::config::RusteloConfig;
|
|
use tower_http::services::ServeDir;
|
|
use tracing_subscriber;
|
|
|
|
/// Home page component
|
|
async fn home() -> Html<&'static str> {
|
|
Html(r#"
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>My Awesome Site</title>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 2rem;
|
|
line-height: 1.6;
|
|
}
|
|
.hero {
|
|
text-align: center;
|
|
padding: 4rem 0;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border-radius: 1rem;
|
|
margin-bottom: 3rem;
|
|
}
|
|
.features { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem; }
|
|
.feature {
|
|
background: #f8fafc;
|
|
padding: 2rem;
|
|
border-radius: 0.5rem;
|
|
border: 1px solid #e2e8f0;
|
|
}
|
|
.feature h3 { color: #2d3748; margin-top: 0; }
|
|
.footer {
|
|
text-align: center;
|
|
margin-top: 4rem;
|
|
padding-top: 2rem;
|
|
border-top: 1px solid #e2e8f0;
|
|
color: #718096;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="hero">
|
|
<h1>🌟 My Awesome Site</h1>
|
|
<p>Built with Rustelo Framework-as-Dependency Architecture</p>
|
|
</div>
|
|
|
|
<div class="features">
|
|
<div class="feature">
|
|
<h3>🦀 Framework-as-Dependency</h3>
|
|
<p>Uses Rustelo as a library dependency, not a fork. Get framework updates automatically while keeping your customizations.</p>
|
|
</div>
|
|
|
|
<div class="feature">
|
|
<h3>📁 Asset Fallback System</h3>
|
|
<p>Local → Framework → Generated priority resolution. Override any framework asset with your local version.</p>
|
|
</div>
|
|
|
|
<div class="feature">
|
|
<h3>🔧 Modular Features</h3>
|
|
<p>Enable only the framework features you need: authentication, content management, database support, etc.</p>
|
|
</div>
|
|
|
|
<div class="feature">
|
|
<h3>🚀 Production Ready</h3>
|
|
<p>Built on Leptos + Axum with SSR, optimized builds, and cross-compilation support.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p><em>Powered by Rustelo Framework • <a href="/api/status">API Status</a></em></p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"#)
|
|
}
|
|
|
|
/// About page
|
|
async fn about() -> Html<&'static str> {
|
|
Html(r#"
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>About - My Awesome Site</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 2rem; }
|
|
.nav { margin-bottom: 2rem; }
|
|
.nav a { margin-right: 1rem; text-decoration: none; color: #2563eb; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="nav">
|
|
<a href="/">Home</a>
|
|
<a href="/about">About</a>
|
|
<a href="/api/status">API</a>
|
|
</div>
|
|
<h1>About My Awesome Site</h1>
|
|
<p>This site demonstrates the Rustelo framework-as-dependency architecture.</p>
|
|
<p>Key benefits:</p>
|
|
<ul>
|
|
<li>No source code forking required</li>
|
|
<li>Automatic framework updates</li>
|
|
<li>Local asset overrides</li>
|
|
<li>Modular feature system</li>
|
|
</ul>
|
|
</body>
|
|
</html>
|
|
"#)
|
|
}
|
|
|
|
/// API endpoint showing framework integration
|
|
async fn api_status() -> axum::Json<serde_json::Value> {
|
|
axum::Json(serde_json::json!({
|
|
"status": "ok",
|
|
"framework": "rustelo",
|
|
"architecture": "framework-as-dependency",
|
|
"features": {
|
|
"core": true,
|
|
"web": true,
|
|
"auth": false,
|
|
"content": false
|
|
},
|
|
"message": "🎉 Framework-as-dependency architecture working!"
|
|
}))
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Initialize logging
|
|
tracing_subscriber::fmt()
|
|
.with_target(false)
|
|
.init();
|
|
|
|
tracing::info!("🚀 Starting My Awesome Site...");
|
|
|
|
// Load framework configuration (with defaults if no config file exists)
|
|
let _config = RusteloConfig::load().unwrap_or_default();
|
|
|
|
tracing::info!("📋 Framework configuration loaded");
|
|
|
|
// Build application routes
|
|
let app = Router::new()
|
|
.route("/", get(home))
|
|
.route("/about", get(about))
|
|
.route("/api/status", get(api_status))
|
|
// Serve static files if they exist
|
|
.nest_service("/static", ServeDir::new("public"))
|
|
.nest_service("/assets", ServeDir::new("assets"))
|
|
.with_state(());
|
|
|
|
// Start server
|
|
let addr = "127.0.0.1:3030";
|
|
tracing::info!("🌐 Server starting at http://{}", addr);
|
|
tracing::info!("✨ Framework-as-dependency architecture active!");
|
|
|
|
let listener = tokio::net::TcpListener::bind(addr).await?;
|
|
axum::serve(listener, app).await?;
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
### Step 5: Create Framework Configuration (Optional)
|
|
|
|
Create `rustelo.toml` for framework configuration:
|
|
|
|
```toml
|
|
[framework]
|
|
name = "my-awesome-site"
|
|
version = "0.1.0"
|
|
description = "My awesome site built with Rustelo"
|
|
|
|
[assets]
|
|
# Asset resolution configuration
|
|
local_path = "assets"
|
|
framework_path = "../rustelo/assets"
|
|
organize_by_category = false
|
|
|
|
[server]
|
|
host = "127.0.0.1"
|
|
port = 3030
|
|
enable_tls = false
|
|
|
|
[features]
|
|
# Enable framework features as needed
|
|
auth = false
|
|
content = false
|
|
database = false
|
|
```
|
|
|
|
### Step 6: Create Justfile for Task Management
|
|
|
|
Create `justfile` with framework fallback pattern:
|
|
|
|
```just
|
|
# My Awesome Site - Task Runner with Framework Fallback
|
|
# Local tasks take priority, framework tasks as fallback
|
|
|
|
# Try to import local tasks, then framework tasks
|
|
mod? local-base 'justfiles/base.just' # Local base tasks
|
|
mod? base '../rustelo/justfiles/base.just' # Framework fallback
|
|
|
|
# Local development server
|
|
dev:
|
|
@echo "🚀 Starting development server..."
|
|
cargo run --bin server
|
|
|
|
# Local build
|
|
build mode="release":
|
|
@echo "🔨 Building for {{mode}} mode..."
|
|
@if [ "{{mode}}" = "release" ]; then \
|
|
cargo build --release; \
|
|
else \
|
|
cargo build; \
|
|
fi
|
|
|
|
# Local test
|
|
test:
|
|
@echo "🧪 Running tests..."
|
|
cargo test
|
|
|
|
# Local clean
|
|
clean:
|
|
@echo "🧹 Cleaning build artifacts..."
|
|
cargo clean
|
|
rm -rf target/
|
|
|
|
# Check code quality
|
|
check:
|
|
@echo "🔍 Checking code quality..."
|
|
cargo check
|
|
cargo clippy
|
|
cargo fmt --check
|
|
|
|
# Format code
|
|
fmt:
|
|
@echo "✨ Formatting code..."
|
|
cargo fmt
|
|
|
|
# Install dependencies
|
|
deps:
|
|
@echo "📦 Installing dependencies..."
|
|
cargo fetch
|
|
|
|
# Show available tasks
|
|
help:
|
|
@echo "Available tasks:"
|
|
@just --list
|
|
```
|
|
|
|
### Step 7: Create Local Justfile Tasks (Optional)
|
|
|
|
Create `justfiles/base.just` for site-specific tasks:
|
|
|
|
```just
|
|
# Local base tasks for My Awesome Site
|
|
|
|
# Custom deploy task
|
|
deploy:
|
|
@echo "🚀 Deploying My Awesome Site..."
|
|
just build release
|
|
# Add your deployment commands here
|
|
|
|
# Custom content tasks
|
|
content-update:
|
|
@echo "📝 Updating content..."
|
|
# Add content management commands here
|
|
|
|
# Custom asset processing
|
|
assets-build:
|
|
@echo "🎨 Processing assets..."
|
|
# Add asset processing commands here
|
|
```
|
|
|
|
### Step 8: Run Your Site
|
|
|
|
```bash
|
|
# Run development server
|
|
just dev
|
|
|
|
# Or run directly with cargo
|
|
cargo run --bin server
|
|
|
|
# Visit http://127.0.0.1:3030
|
|
```
|
|
|
|
## 🔧 Customization Options
|
|
|
|
### Enable Framework Features
|
|
|
|
Uncomment features in `Cargo.toml` as needed:
|
|
|
|
```toml
|
|
# Enable authentication
|
|
rustelo-auth = { path = "../rustelo/crates/rustelo-auth" }
|
|
|
|
# Enable content management
|
|
rustelo-content = { path = "../rustelo/crates/rustelo-content" }
|
|
|
|
[features]
|
|
auth = ["rustelo-auth"]
|
|
content = ["rustelo-content"]
|
|
database = ["rustelo-core/database"]
|
|
```
|
|
|
|
### Asset Fallback System
|
|
|
|
1. **Local Assets**: Place in `assets/` - highest priority
|
|
2. **Framework Assets**: Automatic fallback to framework assets
|
|
3. **Generated Assets**: Created by build system if needed
|
|
|
|
### Override Framework Justfile Tasks
|
|
|
|
Create `justfiles/base.just` with your custom tasks to override framework defaults.
|
|
|
|
## 📁 Final Project Structure
|
|
|
|
```
|
|
my-awesome-site/
|
|
├── Cargo.toml # Dependencies and configuration
|
|
├── rustelo.toml # Framework configuration (optional)
|
|
├── justfile # Task runner with framework fallback
|
|
├── src/
|
|
│ └── main.rs # Main application
|
|
├── justfiles/ # Local task overrides
|
|
│ └── base.just # Custom tasks
|
|
├── assets/ # Local assets (override framework)
|
|
├── content/ # Site content
|
|
├── config/ # Configuration files
|
|
├── public/ # Static public files
|
|
└── target/ # Build output
|
|
```
|
|
|
|
## 🚀 Next Steps
|
|
|
|
1. **Add Content**: Create pages in `src/` or use `rustelo-content` crate
|
|
2. **Style Your Site**: Add CSS in `assets/` or `public/`
|
|
3. **Enable Features**: Add authentication, database, etc.
|
|
4. **Deploy**: Use `just deploy` or your preferred deployment method
|
|
5. **Update Framework**: `cargo update` gets latest framework versions
|
|
|
|
## ✨ Benefits Achieved
|
|
|
|
- ✅ **No fork required** - Pure dependency usage
|
|
- ✅ **Framework updates** - Automatic via `cargo update`
|
|
- ✅ **Local customization** - Override any framework asset
|
|
- ✅ **Asset fallback** - Local → Framework → Generated
|
|
- ✅ **Modular features** - Enable only what you need
|
|
- ✅ **Production ready** - Optimized builds and deployment
|
|
|
|
This approach ensures you have a maintainable, updatable website that leverages the Rustelo framework without becoming dependent on a fork!
|