claude-plugin-wordpress-manager 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/CHANGELOG.md +92 -0
- package/agents/wp-accessibility-auditor.md +206 -0
- package/agents/wp-content-strategist.md +18 -0
- package/agents/wp-deployment-engineer.md +34 -2
- package/agents/wp-performance-optimizer.md +12 -0
- package/agents/wp-security-auditor.md +20 -0
- package/agents/wp-security-hardener.md +266 -0
- package/agents/wp-site-manager.md +14 -0
- package/agents/wp-test-engineer.md +207 -0
- package/docs/guides/INDEX.md +46 -0
- package/docs/guides/wp-blog.md +590 -0
- package/docs/guides/wp-design-system.md +976 -0
- package/docs/guides/wp-ecommerce.md +786 -0
- package/docs/guides/wp-landing-page.md +762 -0
- package/docs/guides/wp-portfolio.md +713 -0
- package/docs/plans/2026-02-27-design-system-guide-design.md +30 -0
- package/docs/plans/2026-02-27-site-type-guides-design.md +44 -0
- package/package.json +2 -2
- package/skills/wordpress-router/references/decision-tree.md +12 -2
- package/skills/wp-accessibility/SKILL.md +170 -0
- package/skills/wp-accessibility/references/a11y-audit-tools.md +248 -0
- package/skills/wp-accessibility/references/a11y-testing.md +222 -0
- package/skills/wp-accessibility/references/block-a11y.md +247 -0
- package/skills/wp-accessibility/references/interactive-a11y.md +272 -0
- package/skills/wp-accessibility/references/media-a11y.md +254 -0
- package/skills/wp-accessibility/references/theme-a11y.md +309 -0
- package/skills/wp-audit/SKILL.md +4 -0
- package/skills/wp-block-development/SKILL.md +5 -0
- package/skills/wp-block-themes/SKILL.md +4 -0
- package/skills/wp-e2e-testing/SKILL.md +186 -0
- package/skills/wp-e2e-testing/references/ci-integration.md +174 -0
- package/skills/wp-e2e-testing/references/jest-wordpress.md +114 -0
- package/skills/wp-e2e-testing/references/phpunit-wordpress.md +141 -0
- package/skills/wp-e2e-testing/references/playwright-wordpress.md +108 -0
- package/skills/wp-e2e-testing/references/test-data-generation.md +127 -0
- package/skills/wp-e2e-testing/references/visual-regression.md +107 -0
- package/skills/wp-e2e-testing/references/wp-env-setup.md +97 -0
- package/skills/wp-e2e-testing/scripts/test_inspect.mjs +375 -0
- package/skills/wp-headless/SKILL.md +168 -0
- package/skills/wp-headless/references/api-layer-choice.md +160 -0
- package/skills/wp-headless/references/cors-config.md +245 -0
- package/skills/wp-headless/references/frontend-integration.md +331 -0
- package/skills/wp-headless/references/headless-auth.md +286 -0
- package/skills/wp-headless/references/webhooks.md +277 -0
- package/skills/wp-headless/references/wpgraphql.md +331 -0
- package/skills/wp-headless/scripts/headless_inspect.mjs +321 -0
- package/skills/wp-i18n/SKILL.md +170 -0
- package/skills/wp-i18n/references/js-i18n.md +201 -0
- package/skills/wp-i18n/references/multilingual-setup.md +219 -0
- package/skills/wp-i18n/references/php-i18n.md +196 -0
- package/skills/wp-i18n/references/rtl-support.md +206 -0
- package/skills/wp-i18n/references/translation-workflow.md +178 -0
- package/skills/wp-i18n/references/wpcli-i18n.md +177 -0
- package/skills/wp-i18n/scripts/i18n_inspect.mjs +330 -0
- package/skills/wp-interactivity-api/SKILL.md +4 -0
- package/skills/wp-plugin-development/SKILL.md +6 -0
- package/skills/wp-rest-api/SKILL.md +4 -0
- package/skills/wp-security/SKILL.md +179 -0
- package/skills/wp-security/references/api-restriction.md +147 -0
- package/skills/wp-security/references/authentication-hardening.md +105 -0
- package/skills/wp-security/references/filesystem-hardening.md +105 -0
- package/skills/wp-security/references/http-headers.md +105 -0
- package/skills/wp-security/references/incident-response.md +144 -0
- package/skills/wp-security/references/user-capabilities.md +115 -0
- package/skills/wp-security/references/wp-config-security.md +129 -0
- package/skills/wp-security/scripts/security_inspect.mjs +393 -0
|
@@ -0,0 +1,976 @@
|
|
|
1
|
+
# WordPress Design System — Da Token a Pixel
|
|
2
|
+
|
|
3
|
+
**Tipologia:** Guida concettuale + pratica
|
|
4
|
+
**Versione:** 1.0.0
|
|
5
|
+
**Ultima modifica:** 2026-02-28
|
|
6
|
+
**Skill correlate:** wpds, wp-block-themes, wp-block-development, wp-interactivity-api
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Paradigma Design-as-Data
|
|
11
|
+
|
|
12
|
+
### Il Problema
|
|
13
|
+
|
|
14
|
+
In un progetto WordPress tradizionale, le decisioni di design vivono disperse: colori hardcodati nel CSS, spaziature nei template, font nei file PHP. Ogni modifica richiede una caccia al tesoro nel codice.
|
|
15
|
+
|
|
16
|
+
I block theme di WordPress risolvono questo problema con un paradigma radicale: **il design e dati, non codice**.
|
|
17
|
+
|
|
18
|
+
### La Catena Completa
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
DESIGN TOKEN COMPILATORE CSS CUSTOM PROPERTY BLOCCO PIXEL
|
|
22
|
+
(dato puro) (theme.json) (variabile CSS) (markup) (browser)
|
|
23
|
+
|
|
24
|
+
"accent" ──→ color.palette ──→ --wp--preset--color-- ──→ has-accent- ──→ #6366f1
|
|
25
|
+
"#6366f1" [{ slug, accent: #6366f1; background- sullo
|
|
26
|
+
color }] color schermo
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Perche Design-as-Data
|
|
30
|
+
|
|
31
|
+
| Approccio tradizionale | Design-as-Data |
|
|
32
|
+
|------------------------|----------------|
|
|
33
|
+
| `.header { color: #6366f1; }` | Token `accent` in theme.json |
|
|
34
|
+
| Duplicazione colori in N file | Singola fonte di verita |
|
|
35
|
+
| Modifica = cerca e sostituisci | Modifica = un valore, propagazione automatica |
|
|
36
|
+
| Sviluppatore decide lo stile | Utente personalizza nell'editor |
|
|
37
|
+
| CSS custom per ogni componente | Classi preset generate da WordPress |
|
|
38
|
+
|
|
39
|
+
### I 6 Strati
|
|
40
|
+
|
|
41
|
+
Il design system WordPress si articola in 6 strati, dal piu astratto al piu concreto:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
┌─────────────────────────────────────────────────┐
|
|
45
|
+
│ Strato 6: Interattivita (Interactivity API) │ ← Comportamento
|
|
46
|
+
├─────────────────────────────────────────────────┤
|
|
47
|
+
│ Strato 5: Blocchi Custom con WPDS │ ← Componenti editor
|
|
48
|
+
├─────────────────────────────────────────────────┤
|
|
49
|
+
│ Strato 4: Patterns (pagine prefabbricate) │ ← Layout compositi
|
|
50
|
+
├─────────────────────────────────────────────────┤
|
|
51
|
+
│ Strato 3: Blocchi Core (componenti UI) │ ← Elementi singoli
|
|
52
|
+
├─────────────────────────────────────────────────┤
|
|
53
|
+
│ Strato 2: theme.json (compilatore) │ ← Configurazione
|
|
54
|
+
├─────────────────────────────────────────────────┤
|
|
55
|
+
│ Strato 1: Design Tokens (dati puri) │ ← Decisioni
|
|
56
|
+
└─────────────────────────────────────────────────┘
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Ogni strato consuma quello inferiore. Un pattern (Strato 4) usa blocchi core (Strato 3) che leggono variabili CSS (Strato 2) generate dai token (Strato 1).
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 2. Strato 1: Design Tokens
|
|
64
|
+
|
|
65
|
+
### Cosa Sono
|
|
66
|
+
|
|
67
|
+
I design token sono le decisioni atomiche del design: un colore, una dimensione font, uno spazio. Sono **valori primitivi** senza contesto d'uso.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Token Valore Tipo
|
|
71
|
+
───────────────────── ────────── ──────────
|
|
72
|
+
color/accent #6366f1 Colore
|
|
73
|
+
color/base #0f172a Colore
|
|
74
|
+
font-size/medium 1rem Tipografia
|
|
75
|
+
font-family/heading JetBrains Mono Tipografia
|
|
76
|
+
spacing/large 2rem Spaziatura
|
|
77
|
+
border-radius/default 8px Forma
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Convenzione di Naming
|
|
81
|
+
|
|
82
|
+
WordPress usa uno schema slug-based. Il nome (slug) diventa parte della CSS Custom Property:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Token slug: "accent"
|
|
86
|
+
|
|
87
|
+
↓ theme.json lo compila in:
|
|
88
|
+
|
|
89
|
+
--wp--preset--color--accent: #6366f1;
|
|
90
|
+
|
|
91
|
+
↓ WordPress genera la classe:
|
|
92
|
+
|
|
93
|
+
.has-accent-color { color: var(--wp--preset--color--accent); }
|
|
94
|
+
.has-accent-background-color { background-color: var(--wp--preset--color--accent); }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Token per il Blog "Developer Journal"
|
|
98
|
+
|
|
99
|
+
Le decisioni di design per un blog tecnico dark:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
PALETTE
|
|
103
|
+
─────────────────────────────────────────
|
|
104
|
+
base #0f172a Sfondo principale (Slate 900)
|
|
105
|
+
contrast #f8fafc Testo principale (Slate 50)
|
|
106
|
+
accent #6366f1 Link, CTA (Indigo 500)
|
|
107
|
+
surface #1e293b Card, sidebar (Slate 800)
|
|
108
|
+
muted #94a3b8 Testo secondario (Slate 400)
|
|
109
|
+
border #334155 Bordi, separatori (Slate 700)
|
|
110
|
+
|
|
111
|
+
TIPOGRAFIA
|
|
112
|
+
─────────────────────────────────────────
|
|
113
|
+
heading JetBrains Mono Titoli (monospace = dev feel)
|
|
114
|
+
body Inter Corpo testo (alta leggibilita)
|
|
115
|
+
|
|
116
|
+
SCALE FONT
|
|
117
|
+
─────────────────────────────────────────
|
|
118
|
+
small 0.875rem Note, date
|
|
119
|
+
medium 1rem Corpo testo
|
|
120
|
+
large 1.25rem Lead paragraph
|
|
121
|
+
x-large 1.75rem Titoli sezione (H2)
|
|
122
|
+
xx-large 2.5rem Titolo pagina (H1)
|
|
123
|
+
|
|
124
|
+
LAYOUT
|
|
125
|
+
─────────────────────────────────────────
|
|
126
|
+
contentSize 720px Colonna testo (65-75 char/riga)
|
|
127
|
+
wideSize 1100px Code block, immagini larghe
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Regole per i Token
|
|
131
|
+
|
|
132
|
+
1. **Nomi semantici, non descrittivi**: `accent` non `indigo-500`
|
|
133
|
+
2. **Massimo 7 colori**: base, contrast, accent, surface, muted, + 1-2 varianti
|
|
134
|
+
3. **Scale tipografiche coerenti**: rapporto ~1.25 tra livelli (Major Third)
|
|
135
|
+
4. **Content width basato sulla leggibilita**: 65-75 caratteri per riga
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 3. Strato 2: theme.json come Compilatore
|
|
140
|
+
|
|
141
|
+
### Il Ruolo di theme.json
|
|
142
|
+
|
|
143
|
+
`theme.json` e il **compilatore** del design system WordPress. Prende i token in input e produce:
|
|
144
|
+
|
|
145
|
+
1. **CSS Custom Properties** nel `<head>` della pagina
|
|
146
|
+
2. **Classi CSS preset** per ogni valore (`.has-{slug}-color`, `.has-{slug}-font-size`)
|
|
147
|
+
3. **Opzioni nell'editor** visibili nell'interfaccia del Site Editor
|
|
148
|
+
4. **Stili elemento** che applicano token a elementi HTML (`<h1>`, `<p>`, `<a>`)
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
┌──────────────┐
|
|
152
|
+
Design Tokens ──→ │ theme.json │ ──→ CSS Custom Properties
|
|
153
|
+
(decisioni) │ │ ──→ Classi preset
|
|
154
|
+
│ compilatore │ ──→ Opzioni editor
|
|
155
|
+
│ │ ──→ Stili elemento
|
|
156
|
+
└──────────────┘
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Struttura Completa
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
|
164
|
+
"version": 3,
|
|
165
|
+
"settings": {
|
|
166
|
+
"color": {
|
|
167
|
+
"palette": [
|
|
168
|
+
{ "slug": "base", "color": "#0f172a", "name": "Base" },
|
|
169
|
+
{ "slug": "contrast", "color": "#f8fafc", "name": "Contrast" },
|
|
170
|
+
{ "slug": "accent", "color": "#6366f1", "name": "Accent" },
|
|
171
|
+
{ "slug": "surface", "color": "#1e293b", "name": "Surface" },
|
|
172
|
+
{ "slug": "muted", "color": "#94a3b8", "name": "Muted" },
|
|
173
|
+
{ "slug": "border", "color": "#334155", "name": "Border" }
|
|
174
|
+
],
|
|
175
|
+
"gradients": [],
|
|
176
|
+
"defaultPalette": false,
|
|
177
|
+
"defaultGradients": false
|
|
178
|
+
},
|
|
179
|
+
"typography": {
|
|
180
|
+
"fontFamilies": [
|
|
181
|
+
{
|
|
182
|
+
"fontFamily": "'JetBrains Mono', monospace",
|
|
183
|
+
"slug": "heading",
|
|
184
|
+
"name": "Heading"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"fontFamily": "'Inter', sans-serif",
|
|
188
|
+
"slug": "body",
|
|
189
|
+
"name": "Body"
|
|
190
|
+
}
|
|
191
|
+
],
|
|
192
|
+
"fontSizes": [
|
|
193
|
+
{ "slug": "small", "size": "0.875rem", "name": "Small" },
|
|
194
|
+
{ "slug": "medium", "size": "1rem", "name": "Medium" },
|
|
195
|
+
{ "slug": "large", "size": "1.25rem", "name": "Large" },
|
|
196
|
+
{ "slug": "x-large", "size": "1.75rem", "name": "X-Large" },
|
|
197
|
+
{ "slug": "xx-large", "size": "2.5rem", "name": "XX-Large" }
|
|
198
|
+
],
|
|
199
|
+
"fluid": true,
|
|
200
|
+
"defaultFontSizes": false
|
|
201
|
+
},
|
|
202
|
+
"spacing": {
|
|
203
|
+
"units": ["px", "rem", "%", "vw"],
|
|
204
|
+
"spacingSizes": [
|
|
205
|
+
{ "slug": "10", "size": "0.25rem", "name": "XXS" },
|
|
206
|
+
{ "slug": "20", "size": "0.5rem", "name": "XS" },
|
|
207
|
+
{ "slug": "30", "size": "1rem", "name": "S" },
|
|
208
|
+
{ "slug": "40", "size": "1.5rem", "name": "M" },
|
|
209
|
+
{ "slug": "50", "size": "2rem", "name": "L" },
|
|
210
|
+
{ "slug": "60", "size": "3rem", "name": "XL" },
|
|
211
|
+
{ "slug": "70", "size": "4rem", "name": "XXL" }
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
"layout": {
|
|
215
|
+
"contentSize": "720px",
|
|
216
|
+
"wideSize": "1100px"
|
|
217
|
+
},
|
|
218
|
+
"appearanceTools": true
|
|
219
|
+
},
|
|
220
|
+
"styles": {
|
|
221
|
+
"color": {
|
|
222
|
+
"background": "var(--wp--preset--color--base)",
|
|
223
|
+
"text": "var(--wp--preset--color--contrast)"
|
|
224
|
+
},
|
|
225
|
+
"typography": {
|
|
226
|
+
"fontFamily": "var(--wp--preset--font-family--body)",
|
|
227
|
+
"fontSize": "var(--wp--preset--font-size--medium)",
|
|
228
|
+
"lineHeight": "1.7"
|
|
229
|
+
},
|
|
230
|
+
"spacing": {
|
|
231
|
+
"blockGap": "var(--wp--preset--spacing--40)"
|
|
232
|
+
},
|
|
233
|
+
"elements": {
|
|
234
|
+
"heading": {
|
|
235
|
+
"typography": {
|
|
236
|
+
"fontFamily": "var(--wp--preset--font-family--heading)",
|
|
237
|
+
"lineHeight": "1.2"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"h1": {
|
|
241
|
+
"typography": { "fontSize": "var(--wp--preset--font-size--xx-large)" }
|
|
242
|
+
},
|
|
243
|
+
"h2": {
|
|
244
|
+
"typography": { "fontSize": "var(--wp--preset--font-size--x-large)" }
|
|
245
|
+
},
|
|
246
|
+
"h3": {
|
|
247
|
+
"typography": { "fontSize": "var(--wp--preset--font-size--large)" }
|
|
248
|
+
},
|
|
249
|
+
"link": {
|
|
250
|
+
"color": { "text": "var(--wp--preset--color--accent)" },
|
|
251
|
+
":hover": {
|
|
252
|
+
"typography": { "textDecoration": "none" }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"blocks": {
|
|
257
|
+
"core/code": {
|
|
258
|
+
"color": {
|
|
259
|
+
"background": "var(--wp--preset--color--surface)",
|
|
260
|
+
"text": "var(--wp--preset--color--contrast)"
|
|
261
|
+
},
|
|
262
|
+
"typography": {
|
|
263
|
+
"fontFamily": "var(--wp--preset--font-family--heading)",
|
|
264
|
+
"fontSize": "var(--wp--preset--font-size--small)"
|
|
265
|
+
},
|
|
266
|
+
"border": {
|
|
267
|
+
"radius": "8px"
|
|
268
|
+
},
|
|
269
|
+
"spacing": {
|
|
270
|
+
"padding": {
|
|
271
|
+
"top": "var(--wp--preset--spacing--40)",
|
|
272
|
+
"bottom": "var(--wp--preset--spacing--40)",
|
|
273
|
+
"left": "var(--wp--preset--spacing--40)",
|
|
274
|
+
"right": "var(--wp--preset--spacing--40)"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"core/quote": {
|
|
279
|
+
"border": {
|
|
280
|
+
"left": {
|
|
281
|
+
"color": "var(--wp--preset--color--accent)",
|
|
282
|
+
"width": "3px",
|
|
283
|
+
"style": "solid"
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"color": {
|
|
287
|
+
"text": "var(--wp--preset--color--muted)"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### La Catena di Override
|
|
296
|
+
|
|
297
|
+
theme.json segue una gerarchia di specificita con 4 livelli. Ogni livello sovrascrive quello precedente:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
┌─────────────────────────────────────────┐
|
|
301
|
+
│ 4. Stili utente (Site Editor) │ ← Massima priorita
|
|
302
|
+
├─────────────────────────────────────────┤
|
|
303
|
+
│ 3. Child theme theme.json │
|
|
304
|
+
├─────────────────────────────────────────┤
|
|
305
|
+
│ 2. Parent theme theme.json │
|
|
306
|
+
├─────────────────────────────────────────┤
|
|
307
|
+
│ 1. WordPress core (default) │ ← Minima priorita
|
|
308
|
+
└─────────────────────────────────────────┘
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Questo significa che l'utente puo sempre personalizzare i token dal Site Editor senza toccare codice.
|
|
312
|
+
|
|
313
|
+
### Output CSS Generato
|
|
314
|
+
|
|
315
|
+
Da un singolo token colore, WordPress genera automaticamente:
|
|
316
|
+
|
|
317
|
+
```css
|
|
318
|
+
/* Custom Property */
|
|
319
|
+
body {
|
|
320
|
+
--wp--preset--color--accent: #6366f1;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Classi preset (generate automaticamente) */
|
|
324
|
+
.has-accent-color {
|
|
325
|
+
color: var(--wp--preset--color--accent) !important;
|
|
326
|
+
}
|
|
327
|
+
.has-accent-background-color {
|
|
328
|
+
background-color: var(--wp--preset--color--accent) !important;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* Stile elemento (da styles.elements.link) */
|
|
332
|
+
a {
|
|
333
|
+
color: var(--wp--preset--color--accent);
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Tipografia Fluida con clamp()
|
|
338
|
+
|
|
339
|
+
WordPress 6.1+ supporta font size fluide. Invece di breakpoint rigidi:
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"fontSizes": [
|
|
344
|
+
{
|
|
345
|
+
"slug": "xx-large",
|
|
346
|
+
"size": "2.5rem",
|
|
347
|
+
"fluid": {
|
|
348
|
+
"min": "1.75rem",
|
|
349
|
+
"max": "2.5rem"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Genera:
|
|
357
|
+
|
|
358
|
+
```css
|
|
359
|
+
--wp--preset--font-size--xx-large: clamp(1.75rem, 1.75rem + ((1vw - 0.48rem) * 1.442), 2.5rem);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Il titolo cresce fluidamente da 1.75rem (mobile) a 2.5rem (desktop) senza media query.
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## 4. Strato 3: Blocchi Core come Componenti UI
|
|
367
|
+
|
|
368
|
+
### Blocchi = Componenti
|
|
369
|
+
|
|
370
|
+
In un design system tradizionale (Material Design, Ant Design), i componenti sono Button, Card, Input. In WordPress, i **blocchi core** sono i componenti:
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
Design System WordPress Block
|
|
374
|
+
─────────────── ───────────────────────
|
|
375
|
+
Button core/button
|
|
376
|
+
Card core/group + backgroundColor
|
|
377
|
+
Grid core/columns
|
|
378
|
+
Image core/image
|
|
379
|
+
Text core/paragraph
|
|
380
|
+
Heading core/heading
|
|
381
|
+
List core/list
|
|
382
|
+
Separator core/separator
|
|
383
|
+
Spacer core/spacer
|
|
384
|
+
Navigation core/navigation
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Anatomia di un Blocco
|
|
388
|
+
|
|
389
|
+
Ogni blocco nel markup di un template e un commento HTML con attributi JSON:
|
|
390
|
+
|
|
391
|
+
```html
|
|
392
|
+
<!-- wp:group {"backgroundColor":"surface","style":{"spacing":{"padding":{"top":"2rem","bottom":"2rem"}},"border":{"radius":"8px"}}} -->
|
|
393
|
+
<div class="wp-block-group has-surface-background-color has-background"
|
|
394
|
+
style="border-radius:8px;padding-top:2rem;padding-bottom:2rem">
|
|
395
|
+
<!-- blocchi figli -->
|
|
396
|
+
</div>
|
|
397
|
+
<!-- /wp:group -->
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
WordPress trasforma gli attributi in:
|
|
401
|
+
1. **Classi CSS preset**: `has-surface-background-color` (dal token `surface`)
|
|
402
|
+
2. **Inline styles**: `border-radius: 8px` (proprietà non tokenizzate)
|
|
403
|
+
3. **Tag HTML**: `<div>` con le classi applicate
|
|
404
|
+
|
|
405
|
+
### Esempio: Card Articolo
|
|
406
|
+
|
|
407
|
+
Un componente "card articolo" per il blog, costruito interamente con blocchi core:
|
|
408
|
+
|
|
409
|
+
```html
|
|
410
|
+
<!-- wp:group {"backgroundColor":"surface","style":{"spacing":{"padding":{"top":"var:preset|spacing|40","bottom":"var:preset|spacing|40","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}},"border":{"radius":"8px"}}} -->
|
|
411
|
+
<div class="wp-block-group has-surface-background-color has-background">
|
|
412
|
+
|
|
413
|
+
<!-- wp:post-date {"textColor":"muted","fontSize":"small"} /-->
|
|
414
|
+
|
|
415
|
+
<!-- wp:post-title {"level":3,"isLink":true} /-->
|
|
416
|
+
|
|
417
|
+
<!-- wp:post-excerpt {"moreText":"continua →","excerptLength":25} /-->
|
|
418
|
+
|
|
419
|
+
<!-- wp:post-terms {"term":"category","textColor":"accent","fontSize":"small"} /-->
|
|
420
|
+
|
|
421
|
+
</div>
|
|
422
|
+
<!-- /wp:group -->
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
I token in azione:
|
|
426
|
+
- `backgroundColor: "surface"` → card scura su sfondo piu scuro
|
|
427
|
+
- `textColor: "muted"` → data in grigio
|
|
428
|
+
- `textColor: "accent"` → categorie colorate
|
|
429
|
+
- `fontSize: "small"` → elementi secondari ridotti
|
|
430
|
+
- `spacing|40` → padding uniforme dal token
|
|
431
|
+
|
|
432
|
+
### Layout: Constrained vs Flex vs Grid
|
|
433
|
+
|
|
434
|
+
I blocchi supportano tre tipi di layout:
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
constrained (default) flex grid (WP 6.3+)
|
|
438
|
+
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
|
|
439
|
+
│ ┌──────────────┐ │ │ ┌────┐ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ ┌────┐ │
|
|
440
|
+
│ │ 720px │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
441
|
+
│ │ content │ │ │ └────┘ └────┘ └────┘ │ │ ├────┤ ├────┤ ├────┤ │
|
|
442
|
+
│ └──────────────┘ │ │ ← flex-direction → │ │ │ │ │ │ │ │ │
|
|
443
|
+
│ 1100px wide │ │ │ │ └────┘ └────┘ └────┘ │
|
|
444
|
+
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘
|
|
445
|
+
|
|
446
|
+
Uso: testo lungo, Uso: header, navigation, Uso: gallerie, portfolio,
|
|
447
|
+
articoli, pagine toolbar, card orizzontali cataloghi prodotto
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
```html
|
|
451
|
+
<!-- Constrained: centra il contenuto con contentSize -->
|
|
452
|
+
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
|
453
|
+
|
|
454
|
+
<!-- Flex: elementi affiancati -->
|
|
455
|
+
<!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"}} -->
|
|
456
|
+
|
|
457
|
+
<!-- Grid: griglia responsive -->
|
|
458
|
+
<!-- wp:group {"layout":{"type":"grid","minimumColumnWidth":"300px"}} -->
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Blocchi Essenziali per Tipo di Sito
|
|
462
|
+
|
|
463
|
+
| Blocco | Blog | Landing | E-commerce | Portfolio |
|
|
464
|
+
|--------|:----:|:-------:|:----------:|:---------:|
|
|
465
|
+
| `core/query` + `core/post-template` | ● | - | ○ | ● |
|
|
466
|
+
| `core/cover` | ○ | ● | ○ | ○ |
|
|
467
|
+
| `core/columns` | ○ | ● | ● | ○ |
|
|
468
|
+
| `core/group` (card) | ● | ● | ● | ● |
|
|
469
|
+
| `core/image` / `core/gallery` | ○ | ○ | ● | ● |
|
|
470
|
+
| `core/navigation` | ● | - | ● | ● |
|
|
471
|
+
| `core/button` | ○ | ● | ● | ○ |
|
|
472
|
+
| `core/heading` + `core/paragraph` | ● | ● | ● | ● |
|
|
473
|
+
|
|
474
|
+
● = essenziale | ○ = opzionale | - = non usato
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## 5. Strato 4: Patterns come Pagine Prefabbricate
|
|
479
|
+
|
|
480
|
+
### Cosa Sono i Patterns
|
|
481
|
+
|
|
482
|
+
I patterns sono **composizioni riutilizzabili** di blocchi. Se i blocchi core sono i mattoni, i patterns sono le pareti prefabbricate: combinazioni testate e pronte all'uso.
|
|
483
|
+
|
|
484
|
+
```
|
|
485
|
+
Blocco singolo Pattern
|
|
486
|
+
─────────────── ───────────────────
|
|
487
|
+
core/heading "Hero con titolo, sottotitolo
|
|
488
|
+
e CTA su sfondo immagine"
|
|
489
|
+
|
|
490
|
+
core/paragraph = core/cover + core/heading +
|
|
491
|
+
core/paragraph + core/button
|
|
492
|
+
core/button (pre-assemblati con stili)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Registrazione Automatica
|
|
496
|
+
|
|
497
|
+
WordPress scopre automaticamente i file PHP nella directory `patterns/` del tema:
|
|
498
|
+
|
|
499
|
+
```php
|
|
500
|
+
<?php
|
|
501
|
+
/**
|
|
502
|
+
* Title: Newsletter CTA
|
|
503
|
+
* Slug: developer-journal/newsletter-cta
|
|
504
|
+
* Categories: call-to-action
|
|
505
|
+
* Keywords: email, subscribe, newsletter
|
|
506
|
+
* Block Types: core/group
|
|
507
|
+
*/
|
|
508
|
+
?>
|
|
509
|
+
<!-- wp:group {"backgroundColor":"surface","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}},"border":{"radius":"8px"}},"layout":{"type":"constrained","contentSize":"600px"}} -->
|
|
510
|
+
<div class="wp-block-group has-surface-background-color has-background">
|
|
511
|
+
|
|
512
|
+
<!-- wp:heading {"level":3,"textColor":"contrast"} -->
|
|
513
|
+
<h3 class="wp-block-heading has-contrast-color has-text-color">Resta aggiornato</h3>
|
|
514
|
+
<!-- /wp:heading -->
|
|
515
|
+
|
|
516
|
+
<!-- wp:paragraph {"textColor":"muted"} -->
|
|
517
|
+
<p class="has-muted-color has-text-color">Ricevi i nuovi post nella inbox. Niente spam, solo contenuti tecnici.</p>
|
|
518
|
+
<!-- /wp:paragraph -->
|
|
519
|
+
|
|
520
|
+
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
|
|
521
|
+
<div class="wp-block-buttons">
|
|
522
|
+
<!-- wp:button {"backgroundColor":"accent","textColor":"contrast"} -->
|
|
523
|
+
<div class="wp-block-button"><a class="wp-block-button__link has-accent-background-color has-contrast-color has-text-color has-background wp-element-button">Iscriviti</a></div>
|
|
524
|
+
<!-- /wp:button -->
|
|
525
|
+
</div>
|
|
526
|
+
<!-- /wp:buttons -->
|
|
527
|
+
|
|
528
|
+
</div>
|
|
529
|
+
<!-- /wp:group -->
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Template Lock
|
|
533
|
+
|
|
534
|
+
I patterns possono bloccare la struttura per evitare modifiche accidentali:
|
|
535
|
+
|
|
536
|
+
```html
|
|
537
|
+
<!-- wp:group {"templateLock":"all"} -->
|
|
538
|
+
<!-- L'utente NON puo aggiungere, rimuovere o riordinare i blocchi -->
|
|
539
|
+
<!-- /wp:group -->
|
|
540
|
+
|
|
541
|
+
<!-- wp:group {"templateLock":"insert"} -->
|
|
542
|
+
<!-- L'utente puo riordinare ma NON aggiungere/rimuovere -->
|
|
543
|
+
<!-- /wp:group -->
|
|
544
|
+
|
|
545
|
+
<!-- wp:group {"templateLock":"contentOnly"} -->
|
|
546
|
+
<!-- L'utente puo solo modificare il testo, non la struttura -->
|
|
547
|
+
<!-- /wp:group -->
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
`contentOnly` e ideale per i pattern di brand: il layout resta fisso, l'utente cambia solo i contenuti.
|
|
551
|
+
|
|
552
|
+
### Patterns Chiave per Developer Journal
|
|
553
|
+
|
|
554
|
+
| Pattern | Slug | Dove si usa |
|
|
555
|
+
|---------|------|-------------|
|
|
556
|
+
| Hero post in evidenza | `hero-featured-post` | Homepage, sopra il loop |
|
|
557
|
+
| Card articolo | `post-card` | Dentro `core/post-template` |
|
|
558
|
+
| Newsletter CTA | `newsletter-cta` | Fine articolo, sidebar |
|
|
559
|
+
| About autore | `author-bio` | Template `single.html` |
|
|
560
|
+
| Footer con link | `footer-minimal` | Part `footer.html` |
|
|
561
|
+
|
|
562
|
+
### Categorie di Pattern
|
|
563
|
+
|
|
564
|
+
Le categorie organizzano i pattern nell'inserter dell'editor:
|
|
565
|
+
|
|
566
|
+
```php
|
|
567
|
+
// In functions.php del tema
|
|
568
|
+
register_block_pattern_category('developer-journal', [
|
|
569
|
+
'label' => 'Developer Journal'
|
|
570
|
+
]);
|
|
571
|
+
|
|
572
|
+
register_block_pattern_category('call-to-action', [
|
|
573
|
+
'label' => 'Call to Action'
|
|
574
|
+
]);
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Il frontmatter PHP del pattern (`Categories: call-to-action`) lo assegna automaticamente alla categoria.
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 6. Strato 5: Blocchi Custom con WPDS
|
|
582
|
+
|
|
583
|
+
### Quando Creare un Blocco Custom
|
|
584
|
+
|
|
585
|
+
I blocchi core coprono l'80% dei casi. Serve un blocco custom quando:
|
|
586
|
+
|
|
587
|
+
1. **Logica specifica**: calcolo, API esterna, dati dinamici
|
|
588
|
+
2. **Markup non riproducibile**: struttura HTML non ottenibile con blocchi core
|
|
589
|
+
3. **Interazione nell'editor**: controlli personalizzati nella sidebar
|
|
590
|
+
4. **Riuso cross-progetto**: componente da pubblicare come plugin
|
|
591
|
+
|
|
592
|
+
### @wordpress/components (WPDS)
|
|
593
|
+
|
|
594
|
+
WordPress fornisce una libreria di componenti React per l'editor: il **WordPress Design System** (WPDS). Questi componenti si usano SOLO nell'editor (edit.js), non nel frontend.
|
|
595
|
+
|
|
596
|
+
```
|
|
597
|
+
Componenti WPDS principali:
|
|
598
|
+
─────────────────────────────────────
|
|
599
|
+
Panel / PanelBody Sidebar controls
|
|
600
|
+
TextControl Input testo
|
|
601
|
+
SelectControl Dropdown
|
|
602
|
+
ToggleControl Switch on/off
|
|
603
|
+
RangeControl Slider numerico
|
|
604
|
+
ColorPalette Selezione colore
|
|
605
|
+
Button Azioni
|
|
606
|
+
Placeholder Stato vuoto del blocco
|
|
607
|
+
ToolbarButton Barra strumenti blocco
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Esempio: Blocco "Tech Stack Badge"
|
|
611
|
+
|
|
612
|
+
Un blocco custom che mostra badge tecnologici nel portfolio.
|
|
613
|
+
|
|
614
|
+
#### block.json (metadata)
|
|
615
|
+
|
|
616
|
+
```json
|
|
617
|
+
{
|
|
618
|
+
"$schema": "https://schemas.wp.org/trunk/block.json",
|
|
619
|
+
"apiVersion": 3,
|
|
620
|
+
"name": "developer-journal/tech-badge",
|
|
621
|
+
"version": "1.0.0",
|
|
622
|
+
"title": "Tech Stack Badge",
|
|
623
|
+
"category": "text",
|
|
624
|
+
"icon": "tag",
|
|
625
|
+
"description": "Badge per tecnologia con nome e colore personalizzabile.",
|
|
626
|
+
"keywords": ["tech", "badge", "stack", "tag"],
|
|
627
|
+
"attributes": {
|
|
628
|
+
"label": {
|
|
629
|
+
"type": "string",
|
|
630
|
+
"default": "WordPress"
|
|
631
|
+
},
|
|
632
|
+
"badgeColor": {
|
|
633
|
+
"type": "string",
|
|
634
|
+
"default": ""
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
"supports": {
|
|
638
|
+
"html": false,
|
|
639
|
+
"color": {
|
|
640
|
+
"background": true,
|
|
641
|
+
"text": true
|
|
642
|
+
},
|
|
643
|
+
"typography": {
|
|
644
|
+
"fontSize": true
|
|
645
|
+
},
|
|
646
|
+
"spacing": {
|
|
647
|
+
"padding": true
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
"textdomain": "developer-journal",
|
|
651
|
+
"editorScript": "file:./index.js",
|
|
652
|
+
"editorStyle": "file:./index.css",
|
|
653
|
+
"style": "file:./style-index.css",
|
|
654
|
+
"render": "file:./render.php"
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
#### edit.js (interfaccia editor)
|
|
659
|
+
|
|
660
|
+
```jsx
|
|
661
|
+
import { useBlockProps } from '@wordpress/block-editor';
|
|
662
|
+
import { TextControl, PanelBody, ColorPalette } from '@wordpress/components';
|
|
663
|
+
import { InspectorControls } from '@wordpress/block-editor';
|
|
664
|
+
import { __ } from '@wordpress/i18n';
|
|
665
|
+
|
|
666
|
+
export default function Edit({ attributes, setAttributes }) {
|
|
667
|
+
const { label, badgeColor } = attributes;
|
|
668
|
+
const blockProps = useBlockProps({
|
|
669
|
+
className: 'tech-badge',
|
|
670
|
+
style: badgeColor ? { backgroundColor: badgeColor } : undefined
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
return (
|
|
674
|
+
<>
|
|
675
|
+
<InspectorControls>
|
|
676
|
+
<PanelBody title={__('Impostazioni Badge', 'developer-journal')}>
|
|
677
|
+
<TextControl
|
|
678
|
+
label={__('Tecnologia', 'developer-journal')}
|
|
679
|
+
value={label}
|
|
680
|
+
onChange={(val) => setAttributes({ label: val })}
|
|
681
|
+
/>
|
|
682
|
+
<ColorPalette
|
|
683
|
+
value={badgeColor}
|
|
684
|
+
onChange={(val) => setAttributes({ badgeColor: val })}
|
|
685
|
+
/>
|
|
686
|
+
</PanelBody>
|
|
687
|
+
</InspectorControls>
|
|
688
|
+
<span {...blockProps}>{label}</span>
|
|
689
|
+
</>
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
#### render.php (output frontend)
|
|
695
|
+
|
|
696
|
+
```php
|
|
697
|
+
<?php
|
|
698
|
+
/**
|
|
699
|
+
* Render del blocco Tech Stack Badge.
|
|
700
|
+
*
|
|
701
|
+
* @var array $attributes Attributi del blocco.
|
|
702
|
+
* @var string $content Contenuto del blocco.
|
|
703
|
+
* @var WP_Block $block Istanza del blocco.
|
|
704
|
+
*/
|
|
705
|
+
|
|
706
|
+
$label = esc_html($attributes['label'] ?? 'WordPress');
|
|
707
|
+
$color = $attributes['badgeColor'] ?? '';
|
|
708
|
+
$style = $color ? sprintf('background-color: %s;', esc_attr($color)) : '';
|
|
709
|
+
?>
|
|
710
|
+
|
|
711
|
+
<span <?php echo get_block_wrapper_attributes(['class' => 'tech-badge']); ?>
|
|
712
|
+
<?php echo $style ? 'style="' . $style . '"' : ''; ?>>
|
|
713
|
+
<?php echo $label; ?>
|
|
714
|
+
</span>
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Setup Ambiente di Sviluppo Blocchi
|
|
718
|
+
|
|
719
|
+
```bash
|
|
720
|
+
# Creare un nuovo blocco con @wordpress/create-block
|
|
721
|
+
cd themes/developer-journal
|
|
722
|
+
npx @wordpress/create-block tech-badge --namespace=developer-journal
|
|
723
|
+
|
|
724
|
+
# Sviluppo con hot reload
|
|
725
|
+
cd tech-badge
|
|
726
|
+
npm start
|
|
727
|
+
|
|
728
|
+
# Build per produzione
|
|
729
|
+
npm run build
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Flusso Dati: Editor → Frontend
|
|
733
|
+
|
|
734
|
+
```
|
|
735
|
+
EDITOR (React) FRONTEND (PHP/HTML)
|
|
736
|
+
══════════════ ═══════════════════
|
|
737
|
+
|
|
738
|
+
edit.js ──→ Salvataggio ──→ render.php
|
|
739
|
+
(componenti WPDS) (attributi JSON (get_block_wrapper_attributes)
|
|
740
|
+
nel post_content)
|
|
741
|
+
|
|
742
|
+
setAttributes() ──→ {"label":"React", ──→ esc_html($attributes['label'])
|
|
743
|
+
"badgeColor":"#61dafb"}
|
|
744
|
+
|
|
745
|
+
InspectorControls ──→ Salvato nel DB ──→ Output HTML statico
|
|
746
|
+
(sidebar editor) come commento HTML (no JavaScript necessario)
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
L'editor usa React e WPDS. Il frontend e puro HTML/CSS/PHP. I due mondi comunicano attraverso gli attributi JSON salvati nel database.
|
|
750
|
+
|
|
751
|
+
---
|
|
752
|
+
|
|
753
|
+
## 7. Strato 6: Interattivita (Interactivity API)
|
|
754
|
+
|
|
755
|
+
### Il Problema
|
|
756
|
+
|
|
757
|
+
I blocchi WordPress sono statici per default: il render PHP produce HTML, fine. Per aggiungere interattivita (filtri, accordion, lightbox, toggle) serviva JavaScript custom o React idratato.
|
|
758
|
+
|
|
759
|
+
L'**Interactivity API** (WordPress 6.5+) risolve questo con un approccio dichiarativo ispirato ad Alpine.js: direttive HTML che connettono stato e comportamento senza scrivere framework code.
|
|
760
|
+
|
|
761
|
+
### Concetti Chiave
|
|
762
|
+
|
|
763
|
+
```
|
|
764
|
+
Store Direttive HTML Effetto
|
|
765
|
+
(stato + azioni) (data-wp-*) (DOM reactivo)
|
|
766
|
+
|
|
767
|
+
state.isOpen ────→ data-wp-bind--hidden ────→ elemento mostrato/nascosto
|
|
768
|
+
actions.toggle ──→ data-wp-on--click ────→ click cambia state.isOpen
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
### Esempio: Filtro Portfolio per Tecnologia
|
|
772
|
+
|
|
773
|
+
#### view.js (client-side store)
|
|
774
|
+
|
|
775
|
+
```javascript
|
|
776
|
+
import { store, getContext } from '@wordpress/interactivity';
|
|
777
|
+
|
|
778
|
+
store('developer-journal/portfolio-filter', {
|
|
779
|
+
state: {
|
|
780
|
+
get filteredProjects() {
|
|
781
|
+
const { activeFilter } = getContext();
|
|
782
|
+
if (activeFilter === 'all') return true;
|
|
783
|
+
const { tech } = getContext();
|
|
784
|
+
return tech.includes(activeFilter);
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
actions: {
|
|
788
|
+
setFilter() {
|
|
789
|
+
const context = getContext();
|
|
790
|
+
context.activeFilter = context.filterValue;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
#### render.php (markup con direttive)
|
|
797
|
+
|
|
798
|
+
```php
|
|
799
|
+
<?php
|
|
800
|
+
$filters = ['all', 'wordpress', 'react', 'php', 'javascript'];
|
|
801
|
+
$projects = get_posts(['post_type' => 'progetto', 'numberposts' => -1]);
|
|
802
|
+
?>
|
|
803
|
+
|
|
804
|
+
<div data-wp-interactive="developer-journal/portfolio-filter"
|
|
805
|
+
<?php echo get_block_wrapper_attributes(); ?>
|
|
806
|
+
data-wp-context='{"activeFilter": "all"}'>
|
|
807
|
+
|
|
808
|
+
<!-- Barra filtri -->
|
|
809
|
+
<div class="filter-bar">
|
|
810
|
+
<?php foreach ($filters as $filter) : ?>
|
|
811
|
+
<button
|
|
812
|
+
data-wp-context='{"filterValue": "<?php echo esc_attr($filter); ?>"}'
|
|
813
|
+
data-wp-on--click="actions.setFilter"
|
|
814
|
+
data-wp-class--active="state.isActiveFilter">
|
|
815
|
+
<?php echo esc_html(ucfirst($filter)); ?>
|
|
816
|
+
</button>
|
|
817
|
+
<?php endforeach; ?>
|
|
818
|
+
</div>
|
|
819
|
+
|
|
820
|
+
<!-- Griglia progetti -->
|
|
821
|
+
<div class="projects-grid">
|
|
822
|
+
<?php foreach ($projects as $project) :
|
|
823
|
+
$techs = wp_get_post_terms($project->ID, 'tecnologia', ['fields' => 'slugs']);
|
|
824
|
+
?>
|
|
825
|
+
<article
|
|
826
|
+
data-wp-context='{"tech": <?php echo wp_json_encode($techs); ?>}'
|
|
827
|
+
data-wp-bind--hidden="!state.filteredProjects"
|
|
828
|
+
class="project-card">
|
|
829
|
+
<h3><?php echo esc_html($project->post_title); ?></h3>
|
|
830
|
+
<div class="tech-tags">
|
|
831
|
+
<?php foreach ($techs as $tech) : ?>
|
|
832
|
+
<span class="tech-badge"><?php echo esc_html($tech); ?></span>
|
|
833
|
+
<?php endforeach; ?>
|
|
834
|
+
</div>
|
|
835
|
+
</article>
|
|
836
|
+
<?php endforeach; ?>
|
|
837
|
+
</div>
|
|
838
|
+
</div>
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Direttive Principali
|
|
842
|
+
|
|
843
|
+
| Direttiva | Scopo | Esempio |
|
|
844
|
+
|-----------|-------|---------|
|
|
845
|
+
| `data-wp-interactive` | Dichiara il namespace dello store | `data-wp-interactive="mio-plugin/filter"` |
|
|
846
|
+
| `data-wp-context` | Stato locale dell'elemento | `data-wp-context='{"isOpen": false}'` |
|
|
847
|
+
| `data-wp-bind--{attr}` | Binding reattivo su attributo HTML | `data-wp-bind--hidden="!state.isOpen"` |
|
|
848
|
+
| `data-wp-on--{event}` | Event listener dichiarativo | `data-wp-on--click="actions.toggle"` |
|
|
849
|
+
| `data-wp-class--{class}` | Toggle classe CSS | `data-wp-class--active="state.isActive"` |
|
|
850
|
+
| `data-wp-text` | Binding testo reattivo | `data-wp-text="state.count"` |
|
|
851
|
+
| `data-wp-each` | Iterazione su array | `data-wp-each="state.items"` |
|
|
852
|
+
|
|
853
|
+
### Interactivity API vs Alpine.js vs React
|
|
854
|
+
|
|
855
|
+
```
|
|
856
|
+
Interactivity API Alpine.js React (idratato)
|
|
857
|
+
───────────────── ───────── ────────────────
|
|
858
|
+
Paradigma Dichiarativo Dichiarativo Imperativo
|
|
859
|
+
Dove vive HTML (direttive) HTML (direttive) JSX (componenti)
|
|
860
|
+
Bundle size ~5 KB ~15 KB ~40+ KB
|
|
861
|
+
Server rendering PHP nativo No (JS only) Richiede SSR/hydration
|
|
862
|
+
Stato Store + Context x-data useState/Redux
|
|
863
|
+
WordPress native Si No (plugin) No (custom setup)
|
|
864
|
+
Curva apprendimento Bassa Bassa Alta
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
### Quando Usare Interactivity API
|
|
868
|
+
|
|
869
|
+
- **Si**: filtri, accordion, lightbox, toggle, tab, contatori, form dinamici
|
|
870
|
+
- **No**: applicazioni complesse (dashboard, editor WYSIWYG, real-time collaboration)
|
|
871
|
+
|
|
872
|
+
Per applicazioni complesse nell'admin, usa React direttamente con `@wordpress/element`.
|
|
873
|
+
|
|
874
|
+
---
|
|
875
|
+
|
|
876
|
+
## 8. Mappa Skill del Plugin
|
|
877
|
+
|
|
878
|
+
### Quale Skill per Quale Strato
|
|
879
|
+
|
|
880
|
+
Questa tabella mappa ogni strato del design system alla skill del plugin wordpress-manager che lo gestisce:
|
|
881
|
+
|
|
882
|
+
| Strato | Oggetto | Skill Plugin | Comando |
|
|
883
|
+
|--------|---------|--------------|---------|
|
|
884
|
+
| 1 - Token | Decisioni di design | `wpds` | — |
|
|
885
|
+
| 2 - theme.json | Configurazione | `wp-block-themes` | — |
|
|
886
|
+
| 3 - Blocchi Core | Templates e parts | `wp-block-themes` | — |
|
|
887
|
+
| 4 - Patterns | Composizioni | `wp-block-themes` | — |
|
|
888
|
+
| 5 - Blocchi Custom | Sviluppo React | `wp-block-development` | — |
|
|
889
|
+
| 6 - Interattivita | Client-side logic | `wp-interactivity-api` | — |
|
|
890
|
+
| — | Ambiente locale | `wp-local-env` | `/wp-start` |
|
|
891
|
+
| — | Contenuti | `wp-content` | — |
|
|
892
|
+
| — | Deploy | `wp-deploy` | `/wp-deploy` |
|
|
893
|
+
|
|
894
|
+
### Flusso di Lavoro Tipico
|
|
895
|
+
|
|
896
|
+
```
|
|
897
|
+
1. Concetto → Definire token (palette, font, spacing)
|
|
898
|
+
Skill: wpds
|
|
899
|
+
|
|
900
|
+
2. Setup ambiente → Creare progetto con wp-env
|
|
901
|
+
Skill: wp-local-env
|
|
902
|
+
Comando: /wp-start
|
|
903
|
+
|
|
904
|
+
3. Compilazione → Scrivere theme.json con i token
|
|
905
|
+
Skill: wp-block-themes
|
|
906
|
+
|
|
907
|
+
4. Struttura → Creare templates (index, single, page, archive)
|
|
908
|
+
Skill: wp-block-themes
|
|
909
|
+
|
|
910
|
+
5. Composizione → Creare patterns (hero, card, CTA)
|
|
911
|
+
Skill: wp-block-themes
|
|
912
|
+
|
|
913
|
+
6. Estensione → Sviluppare blocchi custom se necessario
|
|
914
|
+
Skill: wp-block-development
|
|
915
|
+
|
|
916
|
+
7. Interazione → Aggiungere comportamenti con Interactivity API
|
|
917
|
+
Skill: wp-interactivity-api
|
|
918
|
+
|
|
919
|
+
8. Contenuti → Popolare il sito con contenuti reali
|
|
920
|
+
Skill: wp-content
|
|
921
|
+
|
|
922
|
+
9. Deploy → Pubblicare in produzione
|
|
923
|
+
Skill: wp-deploy
|
|
924
|
+
Comando: /wp-deploy
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
### Uso con Claude Code
|
|
928
|
+
|
|
929
|
+
**Linguaggio naturale per ogni strato:**
|
|
930
|
+
|
|
931
|
+
Strato 1-2 (Token + theme.json):
|
|
932
|
+
> "Crea un theme.json dark per blog developer con palette slate, font monospace per i titoli, content width 720px"
|
|
933
|
+
|
|
934
|
+
Strato 3 (Templates):
|
|
935
|
+
> "Crea il template single.html con data, titolo, categorie, contenuto e navigazione prev/next"
|
|
936
|
+
|
|
937
|
+
Strato 4 (Patterns):
|
|
938
|
+
> "Crea un pattern newsletter CTA con sfondo surface, titolo, descrizione e bottone accent"
|
|
939
|
+
|
|
940
|
+
Strato 5 (Blocchi Custom):
|
|
941
|
+
> "Crea un blocco custom tech-badge con attributi label e colore, usa @wordpress/create-block"
|
|
942
|
+
|
|
943
|
+
Strato 6 (Interactivity):
|
|
944
|
+
> "Aggiungi un filtro per tecnologia al portfolio usando l'Interactivity API"
|
|
945
|
+
|
|
946
|
+
Claude Code usera automaticamente la skill appropriata in base al contesto della richiesta.
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
## Riferimenti
|
|
951
|
+
|
|
952
|
+
### Skill del Plugin
|
|
953
|
+
|
|
954
|
+
| Skill | Strato | Quando usarla |
|
|
955
|
+
|-------|--------|---------------|
|
|
956
|
+
| `wpds` | 1, 5 | Design token, @wordpress/components, UI editor |
|
|
957
|
+
| `wp-block-themes` | 2, 3, 4 | theme.json, templates, parts, patterns |
|
|
958
|
+
| `wp-block-development` | 5 | Blocchi custom con @wordpress/create-block |
|
|
959
|
+
| `wp-interactivity-api` | 6 | Interattivita client-side dichiarativa |
|
|
960
|
+
| `wp-local-env` | — | Ambiente locale wp-env, Docker, WP-CLI |
|
|
961
|
+
| `wp-content` | — | Gestione post, pagine, tassonomie |
|
|
962
|
+
| `wp-deploy` | — | Deploy, staging, produzione |
|
|
963
|
+
|
|
964
|
+
### Risorse Esterne
|
|
965
|
+
|
|
966
|
+
- [Global Settings & Styles (theme.json)](https://developer.wordpress.org/themes/global-settings-and-styles/) — Schema ufficiale
|
|
967
|
+
- [Block Editor Handbook](https://developer.wordpress.org/block-editor/) — Sviluppo blocchi
|
|
968
|
+
- [Block Theme Handbook](https://developer.wordpress.org/themes/block-themes/) — Templates e patterns
|
|
969
|
+
- [@wordpress/create-block](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/) — Scaffolding blocchi
|
|
970
|
+
- [Interactivity API Reference](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/) — Direttive e store
|
|
971
|
+
- [@wordpress/components](https://developer.wordpress.org/block-editor/reference-guides/components/) — Catalogo WPDS
|
|
972
|
+
- [theme.json Living Reference](https://developer.wordpress.org/themes/global-settings-and-styles/settings/typography/) — Impostazioni per sezione
|
|
973
|
+
|
|
974
|
+
---
|
|
975
|
+
|
|
976
|
+
*Guida per il plugin [wordpress-manager](https://github.com/morrealev/wordpress-manager) v1.5.0+*
|