Struttura del Progetto
Come Flux organizza il tuo codice per massima produttivitΓ e chiarezza
Panoramica della Struttura
Quando crei un nuovo progetto Flux, viene generata questa struttura:
my-app/
βββ app/ # Cuore dell'applicazione
β βββ routes.flux # Definizione delle route
β βββ controllers/ # Controller (logica)
β βββ models/ # Modelli database
β βββ middleware/ # Middleware personalizzati
β βββ services/ # Servizi e helper
βββ views/ # Template HTML
β βββ layouts/ # Layout riutilizzabili
β βββ components/ # Componenti UI
β βββ errors/ # Pagine di errore
βββ public/ # Asset pubblici
β βββ css/ # Fogli di stile
β βββ js/ # JavaScript client
β βββ images/ # Immagini
β βββ uploads/ # File caricati
βββ config/ # Configurazioni
β βββ app.flux # Config applicazione
β βββ database.flux # Config database
β βββ routes.flux # Route avanzate
βββ storage/ # File generati
β βββ cache/ # Cache applicazione
β βββ logs/ # Log file
β βββ sessions/ # Sessioni utente
βββ tests/ # Test automatici
β βββ unit/ # Test unitari
β βββ integration/ # Test integrazione
βββ .env # Variabili ambiente
βββ .gitignore # File da ignorare
βββ flux.json # Configurazione progetto
βββ README.md # Documentazione progetto
Directory Principali
π app/
Il cuore della tua applicazione. Contiene tutta la logica di business.
routes.flux
Il file principale dove definisci tutte le route della tua applicazione:
# app/routes.flux
route "/" {
return render("home")
}
route "/api/users" requires_auth {
return User.all().to_json()
}
route.group("/admin") requires_admin {
route "/dashboard" uses AdminController.dashboard
route "/users" uses AdminController.users
}
controllers/
I controller gestiscono la logica delle route complesse:
# app/controllers/UserController.flux
class UserController {
def index(request):
users = User.paginate(page=request.get('page', 1))
return render("users/index", {"users": users})
def create(request):
user = User.create(request.all())
return redirect(f"/users/{user.id}")
}
models/
I modelli rappresentano le tabelle del database:
# app/models/User.flux
model User {
# Campi del modello
name: string(100)
email: string unique
password: string hidden
created_at: datetime auto
# Relazioni
has_many posts
belongs_to_many roles
# Metodi personalizzati
def full_name():
return f"{self.first_name} {self.last_name}"
}
π¨ views/
Contiene tutti i template HTML. Flux usa un sistema di template potente ma semplice:
<!-- views/layouts/app.flux.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My App{% endblock %}</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
{% include "components/navbar" %}
<main>
{% block content %}{% endblock %}
</main>
{% include "components/footer" %}
</body>
</html>
π public/
Tutti i file in questa directory sono accessibili pubblicamente via web:
# Accessibili via browser:
/css/style.css β http://tuoapp.com/css/style.css
/js/app.js β http://tuoapp.com/js/app.js
/images/logo.png β http://tuoapp.com/images/logo.png
βοΈ config/
Configurazioni dell'applicazione, database, servizi esterni:
# config/database.flux
database {
default = "mysql"
connections {
mysql {
host = env("DB_HOST", "localhost")
port = env("DB_PORT", 3306)
database = env("DB_NAME", "flux_app")
username = env("DB_USER", "root")
password = env("DB_PASSWORD", "")
}
redis {
host = env("REDIS_HOST", "localhost")
port = env("REDIS_PORT", 6379)
}
}
}
File Importanti
flux.json
Il file di configurazione principale del progetto:
{
"name": "my-awesome-app",
"version": "1.0.0",
"description": "La mia app Flux",
"author": "Nome Cognome",
"license": "MIT",
"dependencies": {
"flux-auth": "^1.0.0",
"flux-mail": "^1.0.0"
},
"scripts": {
"dev": "flux serve",
"build": "flux build",
"test": "flux test"
}
}
.env
Variabili d'ambiente per configurazioni sensibili:
# NON committare questo file!
APP_ENV=development
APP_DEBUG=true
APP_KEY=tua-chiave-segreta-unica
DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_app
DB_USER=root
DB_PASSWORD=password
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
Best Practices
π Organizzazione
- Mantieni i controller snelli, sposta la logica nei services
- Un model per file nella directory models/
- Raggruppa i template per funzionalitΓ in sottocartelle
π Sicurezza
- Mai committare il file .env
- Usa sempre variabili d'ambiente per dati sensibili
- La cartella storage/ non deve essere pubblica
π Performance
- Minimizza CSS/JS in produzione
- Usa la cache per query costose
- Ottimizza le immagini in public/images
Strutture Personalizzate
Flux Γ¨ flessibile. Puoi aggiungere le tue directory:
my-app/
βββ app/
β βββ ...
β βββ events/ # Eventi applicazione
β βββ jobs/ # Job asincroni
β βββ mail/ # Template email
β βββ validators/ # Validatori custom
βββ resources/ # Risorse non compilate
β βββ sass/ # File SASS
β βββ js/ # JavaScript ES6+
βββ ...
Esempio Pratico
Vediamo come i file lavorano insieme in un blog:
# app/routes.flux
route "/blog" uses BlogController.index
route "/blog/:slug" uses BlogController.show
route "/blog/create" requires_auth uses BlogController.create
route "/blog/:id/edit" requires_auth uses BlogController.edit
# app/controllers/BlogController.flux
class BlogController {
def index(request):
posts = Post.published().paginate(10)
return render("blog/index", {"posts": posts})
def show(request, slug):
post = Post.where(slug=slug).first_or_404()
return render("blog/show", {"post": post})
}
# app/models/Post.flux
model Post {
title: string(200)
slug: string unique
content: text
published_at: datetime nullable
belongs_to user
has_many comments
scope published():
return self.where_not_null('published_at')
def excerpt(length=150):
return self.content[:length] + "..."
}
<!-- views/blog/index.flux.html -->
{% extends "layouts/app" %}
{% block content %}
<h1>Blog</h1>
{% for post in posts %}
<article>
<h2>
<a href="/blog/{{ post.slug }}">
{{ post.title }}
</a>
</h2>
<p>{{ post.excerpt() }}</p>
<small>{{ post.published_at.format('%d/%m/%Y') }}</small>
</article>
{% endfor %}
{{ posts.links() }}
{% endblock %}
flux generate per creare automaticamente file con la struttura corretta:
flux generate controller BlogController