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.
Files changed (67) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/CHANGELOG.md +92 -0
  3. package/agents/wp-accessibility-auditor.md +206 -0
  4. package/agents/wp-content-strategist.md +18 -0
  5. package/agents/wp-deployment-engineer.md +34 -2
  6. package/agents/wp-performance-optimizer.md +12 -0
  7. package/agents/wp-security-auditor.md +20 -0
  8. package/agents/wp-security-hardener.md +266 -0
  9. package/agents/wp-site-manager.md +14 -0
  10. package/agents/wp-test-engineer.md +207 -0
  11. package/docs/guides/INDEX.md +46 -0
  12. package/docs/guides/wp-blog.md +590 -0
  13. package/docs/guides/wp-design-system.md +976 -0
  14. package/docs/guides/wp-ecommerce.md +786 -0
  15. package/docs/guides/wp-landing-page.md +762 -0
  16. package/docs/guides/wp-portfolio.md +713 -0
  17. package/docs/plans/2026-02-27-design-system-guide-design.md +30 -0
  18. package/docs/plans/2026-02-27-site-type-guides-design.md +44 -0
  19. package/package.json +2 -2
  20. package/skills/wordpress-router/references/decision-tree.md +12 -2
  21. package/skills/wp-accessibility/SKILL.md +170 -0
  22. package/skills/wp-accessibility/references/a11y-audit-tools.md +248 -0
  23. package/skills/wp-accessibility/references/a11y-testing.md +222 -0
  24. package/skills/wp-accessibility/references/block-a11y.md +247 -0
  25. package/skills/wp-accessibility/references/interactive-a11y.md +272 -0
  26. package/skills/wp-accessibility/references/media-a11y.md +254 -0
  27. package/skills/wp-accessibility/references/theme-a11y.md +309 -0
  28. package/skills/wp-audit/SKILL.md +4 -0
  29. package/skills/wp-block-development/SKILL.md +5 -0
  30. package/skills/wp-block-themes/SKILL.md +4 -0
  31. package/skills/wp-e2e-testing/SKILL.md +186 -0
  32. package/skills/wp-e2e-testing/references/ci-integration.md +174 -0
  33. package/skills/wp-e2e-testing/references/jest-wordpress.md +114 -0
  34. package/skills/wp-e2e-testing/references/phpunit-wordpress.md +141 -0
  35. package/skills/wp-e2e-testing/references/playwright-wordpress.md +108 -0
  36. package/skills/wp-e2e-testing/references/test-data-generation.md +127 -0
  37. package/skills/wp-e2e-testing/references/visual-regression.md +107 -0
  38. package/skills/wp-e2e-testing/references/wp-env-setup.md +97 -0
  39. package/skills/wp-e2e-testing/scripts/test_inspect.mjs +375 -0
  40. package/skills/wp-headless/SKILL.md +168 -0
  41. package/skills/wp-headless/references/api-layer-choice.md +160 -0
  42. package/skills/wp-headless/references/cors-config.md +245 -0
  43. package/skills/wp-headless/references/frontend-integration.md +331 -0
  44. package/skills/wp-headless/references/headless-auth.md +286 -0
  45. package/skills/wp-headless/references/webhooks.md +277 -0
  46. package/skills/wp-headless/references/wpgraphql.md +331 -0
  47. package/skills/wp-headless/scripts/headless_inspect.mjs +321 -0
  48. package/skills/wp-i18n/SKILL.md +170 -0
  49. package/skills/wp-i18n/references/js-i18n.md +201 -0
  50. package/skills/wp-i18n/references/multilingual-setup.md +219 -0
  51. package/skills/wp-i18n/references/php-i18n.md +196 -0
  52. package/skills/wp-i18n/references/rtl-support.md +206 -0
  53. package/skills/wp-i18n/references/translation-workflow.md +178 -0
  54. package/skills/wp-i18n/references/wpcli-i18n.md +177 -0
  55. package/skills/wp-i18n/scripts/i18n_inspect.mjs +330 -0
  56. package/skills/wp-interactivity-api/SKILL.md +4 -0
  57. package/skills/wp-plugin-development/SKILL.md +6 -0
  58. package/skills/wp-rest-api/SKILL.md +4 -0
  59. package/skills/wp-security/SKILL.md +179 -0
  60. package/skills/wp-security/references/api-restriction.md +147 -0
  61. package/skills/wp-security/references/authentication-hardening.md +105 -0
  62. package/skills/wp-security/references/filesystem-hardening.md +105 -0
  63. package/skills/wp-security/references/http-headers.md +105 -0
  64. package/skills/wp-security/references/incident-response.md +144 -0
  65. package/skills/wp-security/references/user-capabilities.md +115 -0
  66. package/skills/wp-security/references/wp-config-security.md +129 -0
  67. 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+*