Skill: Migrazione template HTML → Blade
Regola mentale n.1 — il template/ è la FONTE DI VERITÀ del design (sola lettura)
Gli HTML statici (template/*.html, i nuovi consegnati come template_storia/*.html, e typo.html) sono il prototipo di design approvato. Quando migri:
- Replica il markup e le classi CSS 1:1. Nessuna classe inventata, nessuna omessa, nessuna "semplificazione". Il CSS esistente è agganciato a quei nomi classe: se cambi la struttura, rompi lo stile.
- Non modificare i file dentro
template/*.html per farli combaciare col Blade: è il Blade che deve combaciare con loro.
- Se il markup del prototipo è palesemente sbagliato/incoerente, segnalalo all'utente invece di correggerlo di testa tua.
Regola mentale n.2 — la view Blade contiene SOLO markup. Mai JS o CSS inline.
Questa è la regola non negoziabile del progetto (stesso principio del lato admin: JS/CSS mai inline nel form). Dentro una view Blade del front:
- ❌ Niente
<style>...</style> nel corpo della view.
- ❌ Niente
<script>...</script> con logica nel corpo della view.
- ❌ Niente
style="..." inline (salvo variabili dinamiche brevi, es. style="--i:{{ $index }}").
- ✅ Gli stili vanno nei file CSS di
template/assets/css/ (vedi Regola n.3).
- ✅ Il JS va in
template/assets/js/main.js (o in una lib dedicata) e viene ricompilato con Mix.
- ✅ Il markup HTML va nel Blade (view di pagina, partial o componente).
Regola mentale n.3 — estrazione CHIRURGICA degli stili, MAI sovrascrivere
Il nuovo template porta con sé un suo assets/css/style.css / pages.css. Questi file quasi sicuramente differiscono da quelli live del progetto. Non copiare mai un intero file CSS sopra quello del progetto: cancelleresti gli stili di tutte le altre pagine già migrate.
Procedura corretta:
- Individua quali classi/selettori usa davvero l'HTML che stai migrando (le classi che compaiono nel markup di quella pagina).
- Da
template_storia/assets/css/*.css estrai solo quelle regole (blocco per blocco, incluse eventuali media query e keyframe collegati).
- Aggiungile ai file CSS del progetto (
template/assets/css/), sotto una sezione commentata dedicata (es. /* === STORIA === */), senza toccare le regole esistenti.
- Se una regola ha lo stesso selettore di una già presente, NON sovrascrivere alla cieca: confronta, e se il design è cambiato aggiorna consapevolmente segnalando il diff all'utente.
Dove vivono gli stili (e la pipeline Mix)
template/assets/css/
├── style.css → stili globali + componenti riusabili (header, footer, blocchi, sezioni comuni)
├── pages.css → stili SPECIFICI di singole pagine
└── base.min.css → ARTEFATTO GENERATO da `npx mix` — NON editarlo mai a mano
webpack.mix.js concatena beers.css + style.css + pages.css → base.min.css (e beers.js + main.js → base.min.js).
- Debug (
config('app.debug') true): head.blade.php carica style.css sorgente; scripts.blade.php carica main.js sorgente. → le tue modifiche si vedono subito.
- Produzione: si carica
base.min.{css,js}. → devi ricompilare: da private/ esegui npx mix (o npx mix --production).
Regola pratica: stile di un componente riusabile → style.css. Stile di una singola pagina → pages.css. Dopo aver toccato il CSS/JS, ricompila con Mix.
Struttura del front (dove mettere il markup)
App MVC in private/front/Main/ (vedi CLAUDE.md). Per la migrazione contano:
Views/
├── base/ layout.blade.php (scheletro), head.blade.php (CSS), scripts.blade.php (JS),
│ header/footer/offcanvas
├── pages/ una view per pagina (home, contacts, news, section-page, …)
├── partials/ frammenti riusabili inclusi con @include
└── components/ view dei componenti Blade (x-...)
Components/ classe PHP di ogni componente (PascalCase → x-kebab-case)
Come si aggancia una view di pagina
Ogni pagina @extends('base.layout') ed espone due sezioni chiave del layout:
| Nel layout |
A cosa serve |
Come lo usi nella pagina |
@yield('head') |
CSS specifico di pagina |
@section('head') <link href="{{\Master\Facades\Version::get('/template/assets/css/pages.css')}}" rel="stylesheet"> @endsection |
@yield('content') |
corpo pagina |
@section('content') …markup… @endsection |
@stack('scripts') |
JS specifico di pagina |
in un partial: @push('scripts') <script src="{{\Master\Facades\Version::get('/template/assets/js/…')}}"></script> @endpush |
Sempre \Master\Facades\Version::get('/path') per gli asset locali (cache-busting), mai un path nudo.
Quando creare un COMPONENTE riusabile (vs partial vs markup inline)
Decisione in tre livelli:
Markup inline nella view di pagina — se il pezzo è unico di quella pagina e non si ripete. Es. l'intro testuale della Storia.
Partial (@include('partials.xyz')) — se il pezzo si ripete identico su più pagine e non ha bisogno di parametri/logica (o solo di variabili già in scope). Es. una fascia statica, un blocco di intestazione fisso.
Componente Blade (x-...) — crealo quando almeno una è vera:
- lo stesso blocco compare su ≥2 pagine con contenuti diversi (immagine, titolo, link cambiano) → serve parametrizzazione;
- ha una API di props chiara (es. una card, una sezione feature, un carosello, un header di pagina con varianti);
- contiene logica di presentazione (default, condizioni, mapping) che non vuoi duplicare;
- replica un elemento del design system (i blocchi di
typo.html, la page-header, gli slider).
Guarda gli esempi esistenti: FeatureSection, CtaSection, ParallaxSection, NewsStrip, ProjectsSlider, SectionSidemenu, PageHeader, PictureWebP. Sono la fonte del pattern.
In dubbio: se lo useresti una volta sola e senza parametri, NON creare un componente. Il costo di un componente si ripaga con il riuso o la parametrizzazione. Non trasformare ogni <section> in un componente.
Come si crea un componente (pattern del progetto)
- Classe PHP in
private/front/Main/Components/NomeComponente.php:namespace Front\Main\Components;
use Illuminate\View\Component;
class NomeComponente extends Component
{
public function __construct(
public string $title,
public ?string $link = null,
public $image = null,
) {}
public function render() { return view('components.nome-componente'); }
}
- View in
private/front/Main/Views/components/nome-componente.blade.php — solo markup, usa le props ({{ $title }}, ecc.).
- Uso in pagina:
<x-nome-componente :title="$x" :link="$url" />.
- Gli stili del componente →
style.css (è riusabile), replicati dalle classi del prototipo.
Flusso di lavoro (checklist di migrazione)
Dato un HTML statico da migrare (es. template_storia/storia.html):
- Leggi l'HTML e individua le macro-sezioni (
<section>), le classi usate, gli asset (immagini, video), e gli eventuali comportamenti JS.
- Confronta con l'esistente: la pagina rientra in un tipo già gestito (
section-page, news, contacts…)? Alcune sezioni sono già coperte da componenti esistenti (x-page-header, x-feature-section…)? Riusa prima di ricreare.
- Decidi il partizionamento: cosa resta inline, cosa diventa partial, cosa diventa componente (Regola sui componenti sopra).
- Crea la view di pagina in
Views/pages/ che @extends('base.layout'), con @section('content'). Aggancia la rotta se serve (vedi Routes/web.php, raggruppate per locale).
- Sposta il markup replicando le classi 1:1. Nessun
<style>/<script> inline.
- Estrai gli stili chirurgicamente dai CSS del nuovo template dentro
style.css/pages.css (Regola n.3). Carica il CSS di pagina via @section('head') se non è già nel bundle.
- Sposta il JS (se c'è) in
main.js/lib dedicata; agganciato via @push('scripts') se è per una sola pagina.
- Sposta gli asset (immagini, video) sotto
template/assets/… con path serviti da Version::get(). Per le immagini valuta <x-picture-web-p>.
- Ricompila: da
private/ → npx mix.
- Verifica dal vivo sul front (skill
front-navigation): la pagina deve essere identica al prototipo. Confronta a video con l'HTML statico.
Errori da evitare
- ❌ Copiare un intero
style.css/pages.css del nuovo template sopra quelli del progetto. ✅ Estrarre solo le regole delle classi usate da quella view.
- ❌
<style> o <script> con logica dentro il Blade. ✅ CSS in assets/css, JS in assets/js, poi Mix.
- ❌ Editare
base.min.css / base.min.js a mano. ✅ Sono generati: modifica i sorgenti e lancia npx mix.
- ❌ Inventare/semplificare classi o struttura rispetto al prototipo. ✅ Replica 1:1 — il CSS dipende da quei nomi.
- ❌ Trasformare ogni sezione in un componente. ✅ Componente solo se riusato o parametrizzato; altrimenti inline o partial.
- ❌ Path asset nudi (
/template/assets/…). ✅ Sempre \Master\Facades\Version::get(...) per il cache-busting.
- ❌ Dimenticare di ricompilare Mix → in produzione non si vedono le modifiche a CSS/JS.
- ❌ Ricreare da zero un blocco già coperto da un componente esistente o dai blocchi di
typo.html (vedi skill master-page-content).
1---2name: template-to-blade3description: Skill: Migrazione template HTML → Blade4---56# Skill: Migrazione template HTML → Blade78## Regola mentale n.1 — il `template/` è la FONTE DI VERITÀ del design (sola lettura)910Gli HTML statici (`template/*.html`, i nuovi consegnati come `template_storia/*.html`, e `typo.html`) sono il **prototipo di design approvato**. Quando migri:1112- **Replica il markup e le classi CSS 1:1.** Nessuna classe inventata, nessuna omessa, nessuna "semplificazione". Il CSS esistente è agganciato a quei nomi classe: se cambi la struttura, rompi lo stile.13- **Non modificare i file dentro `template/*.html`** per farli combaciare col Blade: è il Blade che deve combaciare con loro.14- Se il markup del prototipo è palesemente sbagliato/incoerente, **segnalalo all'utente** invece di correggerlo di testa tua.1516## Regola mentale n.2 — la view Blade contiene SOLO markup. Mai JS o CSS inline.1718Questa è la regola non negoziabile del progetto (stesso principio del lato admin: JS/CSS mai inline nel form). Dentro una view Blade del front:1920- ❌ Niente `<style>...</style>` nel corpo della view.21- ❌ Niente `<script>...</script>` con logica nel corpo della view.22- ❌ Niente `style="..."` inline (salvo variabili dinamiche brevi, es. `style="--i:{{ $index }}"`).23- ✅ Gli **stili** vanno nei file CSS di `template/assets/css/` (vedi Regola n.3).24- ✅ Il **JS** va in `template/assets/js/main.js` (o in una lib dedicata) e viene ricompilato con Mix.25- ✅ Il markup HTML va nel Blade (view di pagina, partial o componente).2627## Regola mentale n.3 — estrazione CHIRURGICA degli stili, MAI sovrascrivere2829Il nuovo template porta con sé un suo `assets/css/style.css` / `pages.css`. Questi file **quasi sicuramente differiscono** da quelli live del progetto. **Non copiare mai un intero file CSS sopra quello del progetto**: cancelleresti gli stili di tutte le altre pagine già migrate.3031Procedura corretta:321. Individua quali **classi/selettori** usa davvero l'HTML che stai migrando (le classi che compaiono nel markup di quella pagina).332. Da `template_storia/assets/css/*.css` **estrai solo quelle regole** (blocco per blocco, incluse eventuali media query e keyframe collegati).343. **Aggiungile** ai file CSS del progetto (`template/assets/css/`), sotto una sezione commentata dedicata (es. `/* === STORIA === */`), senza toccare le regole esistenti.354. Se una regola ha lo **stesso selettore** di una già presente, NON sovrascrivere alla cieca: confronta, e se il design è cambiato aggiorna consapevolmente segnalando il diff all'utente.3637### Dove vivono gli stili (e la pipeline Mix)3839```40template/assets/css/41├── style.css → stili globali + componenti riusabili (header, footer, blocchi, sezioni comuni)42├── pages.css → stili SPECIFICI di singole pagine43└── base.min.css → ARTEFATTO GENERATO da `npx mix` — NON editarlo mai a mano44```4546`webpack.mix.js` concatena `beers.css + style.css + pages.css → base.min.css` (e `beers.js + main.js → base.min.js`).4748- **Debug** (`config('app.debug')` true): `head.blade.php` carica `style.css` sorgente; `scripts.blade.php` carica `main.js` sorgente. → le tue modifiche si vedono subito.49- **Produzione**: si carica `base.min.{css,js}`. → **devi ricompilare**: da `private/` esegui `npx mix` (o `npx mix --production`).5051Regola pratica: stile di un **componente riusabile** → `style.css`. Stile di una **singola pagina** → `pages.css`. Dopo aver toccato il CSS/JS, ricompila con Mix.5253## Struttura del front (dove mettere il markup)5455App MVC in `private/front/Main/` (vedi CLAUDE.md). Per la migrazione contano:5657```58Views/59├── base/ layout.blade.php (scheletro), head.blade.php (CSS), scripts.blade.php (JS),60│ header/footer/offcanvas61├── pages/ una view per pagina (home, contacts, news, section-page, …)62├── partials/ frammenti riusabili inclusi con @include63└── components/ view dei componenti Blade (x-...)64Components/ classe PHP di ogni componente (PascalCase → x-kebab-case)65```6667### Come si aggancia una view di pagina6869Ogni pagina `@extends('base.layout')` ed espone due sezioni chiave del layout:7071| Nel layout | A cosa serve | Come lo usi nella pagina |72|---|---|---|73| `@yield('head')` | CSS specifico di pagina | `@section('head') <link href="{{\Master\Facades\Version::get('/template/assets/css/pages.css')}}" rel="stylesheet"> @endsection` |74| `@yield('content')` | corpo pagina | `@section('content') …markup… @endsection` |75| `@stack('scripts')` | JS specifico di pagina | in un partial: `@push('scripts') <script src="{{\Master\Facades\Version::get('/template/assets/js/…')}}"></script> @endpush` |7677**Sempre** `\Master\Facades\Version::get('/path')` per gli asset locali (cache-busting), mai un path nudo.7879## Quando creare un COMPONENTE riusabile (vs partial vs markup inline)8081Decisione in tre livelli:82831. **Markup inline nella view di pagina** — se il pezzo è unico di quella pagina e non si ripete. Es. l'intro testuale della Storia.84852. **Partial (`@include('partials.xyz')`)** — se il pezzo si ripete **identico** su più pagine e **non** ha bisogno di parametri/logica (o solo di variabili già in scope). Es. una fascia statica, un blocco di intestazione fisso.86873. **Componente Blade (`x-...`)** — crealo quando **almeno una** è vera:88 - lo stesso blocco compare su ≥2 pagine **con contenuti diversi** (immagine, titolo, link cambiano) → serve parametrizzazione;89 - ha una **API di props chiara** (es. una card, una sezione feature, un carosello, un header di pagina con varianti);90 - contiene **logica di presentazione** (default, condizioni, mapping) che non vuoi duplicare;91 - replica un elemento del design system (i blocchi di `typo.html`, la `page-header`, gli slider).9293 Guarda gli esempi esistenti: `FeatureSection`, `CtaSection`, `ParallaxSection`, `NewsStrip`, `ProjectsSlider`, `SectionSidemenu`, `PageHeader`, `PictureWebP`. Sono la fonte del pattern.9495> In dubbio: se lo useresti **una volta sola e senza parametri**, NON creare un componente. Il costo di un componente si ripaga con il riuso o la parametrizzazione. Non trasformare ogni `<section>` in un componente.9697### Come si crea un componente (pattern del progetto)98991. Classe PHP in `private/front/Main/Components/NomeComponente.php`:100 ```php101 namespace Front\Main\Components;102 use Illuminate\View\Component;103104 class NomeComponente extends Component105 {106 public function __construct(107 public string $title,108 public ?string $link = null,109 public $image = null,110 ) {}111112 public function render() { return view('components.nome-componente'); }113 }114 ```1152. View in `private/front/Main/Views/components/nome-componente.blade.php` — **solo markup**, usa le props (`{{ $title }}`, ecc.).1163. Uso in pagina: `<x-nome-componente :title="$x" :link="$url" />`.1174. Gli stili del componente → `style.css` (è riusabile), replicati dalle classi del prototipo.118119## Flusso di lavoro (checklist di migrazione)120121Dato un HTML statico da migrare (es. `template_storia/storia.html`):1221231. **Leggi l'HTML** e individua le macro-sezioni (`<section>`), le classi usate, gli asset (immagini, video), e gli eventuali comportamenti JS.1242. **Confronta con l'esistente**: la pagina rientra in un tipo già gestito (`section-page`, `news`, `contacts`…)? Alcune sezioni sono già coperte da componenti esistenti (`x-page-header`, `x-feature-section`…)? Riusa prima di ricreare.1253. **Decidi il partizionamento**: cosa resta inline, cosa diventa partial, cosa diventa componente (Regola sui componenti sopra).1264. **Crea la view di pagina** in `Views/pages/` che `@extends('base.layout')`, con `@section('content')`. Aggancia la rotta se serve (vedi `Routes/web.php`, raggruppate per locale).1275. **Sposta il markup** replicando le classi 1:1. Nessun `<style>`/`<script>` inline.1286. **Estrai gli stili chirurgicamente** dai CSS del nuovo template dentro `style.css`/`pages.css` (Regola n.3). Carica il CSS di pagina via `@section('head')` se non è già nel bundle.1297. **Sposta il JS** (se c'è) in `main.js`/lib dedicata; agganciato via `@push('scripts')` se è per una sola pagina.1308. **Sposta gli asset** (immagini, video) sotto `template/assets/…` con path serviti da `Version::get()`. Per le immagini valuta `<x-picture-web-p>`.1319. **Ricompila**: da `private/` → `npx mix`.13210. **Verifica dal vivo** sul front (skill `front-navigation`): la pagina deve essere identica al prototipo. Confronta a video con l'HTML statico.133134## Errori da evitare135136- ❌ Copiare un intero `style.css`/`pages.css` del nuovo template sopra quelli del progetto. ✅ Estrarre solo le regole delle classi usate da quella view.137- ❌ `<style>` o `<script>` con logica dentro il Blade. ✅ CSS in `assets/css`, JS in `assets/js`, poi Mix.138- ❌ Editare `base.min.css` / `base.min.js` a mano. ✅ Sono generati: modifica i sorgenti e lancia `npx mix`.139- ❌ Inventare/semplificare classi o struttura rispetto al prototipo. ✅ Replica 1:1 — il CSS dipende da quei nomi.140- ❌ Trasformare ogni sezione in un componente. ✅ Componente solo se riusato o parametrizzato; altrimenti inline o partial.141- ❌ Path asset nudi (`/template/assets/…`). ✅ Sempre `\Master\Facades\Version::get(...)` per il cache-busting.142- ❌ Dimenticare di ricompilare Mix → in produzione non si vedono le modifiche a CSS/JS.143- ❌ Ricreare da zero un blocco già coperto da un componente esistente o dai blocchi di `typo.html` (vedi skill `master-page-content`).