Skip to content

Commit 731fb73

Browse files
authored
Merge pull request #92 from Automattic/cook/figma-to-wordpress-plugin
Add Figma to WordPress plugin prototype
2 parents c742ceb + a1e0a12 commit 731fb73

20 files changed

Lines changed: 2279 additions & 0 deletions

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Start here before changing skills, generator code, verification contracts, or ge
2020
| [Generated outputs](generated-outputs.md) | Generated package matrix, build pipeline, generated-output contracts, MCP config shape, telemetry MCP tool reference, verifier expectations, and Cursor export contract. | Change or review generated files under `plugins/`, add a surface, or reason about package artifacts. |
2121
| [Skills and integrations](skills-and-integrations.md) | Skill inventory, Studio integration concepts, MCP contracts, relationship to WordPress agent skills packaging, and safe extension boundaries. | Update shared skills, Studio guidance, or agent integration behavior. |
2222
| [Contributor workflows](contributor-workflows.md) | Setup, commands, change recipes, manual smoke testing, CI automation contracts, and pull request checklist. | Prepare, verify, and review a repository change. |
23+
| [Figma to WordPress](figma-playground-runner.md) | Figma plugin handoff to a WordPress Playground runner for Static Site Importer and Blocks Engine. | Review or test the Figma-to-HTML-to-WordPress integration path. |
2324

2425
## Repository source inventory
2526

docs/figma-playground-runner.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Figma to WordPress
2+
3+
`plugins/figma-to-wordpress` moves a Figma file into WordPress. It hands the design to a WordPress runner service that creates a Playground session and imports the result with Static Site Importer and Blocks Engine.
4+
5+
## Architecture
6+
7+
```text
8+
Figma plugin UI
9+
-> Figma document scene data
10+
-> runner request
11+
-> WordPress runner service
12+
-> WordPress Playground session URL
13+
-> Static Site Importer / Blocks Engine inside WordPress
14+
```
15+
16+
The TypeScript boundary stops at request construction and opening the returned Playground URL. WordPress, PHP, Static Site Importer, Blocks Engine, and Playground session orchestration remain WordPress-side runtime concerns.
17+
18+
## Figma Iframe Limits
19+
20+
Figma plugin UIs run in a constrained browser context. That context is friendly to HTML, CSS, and client-side JavaScript, but it is not a normal browser tab.
21+
22+
Practical constraints for this browser-based flow:
23+
24+
- Cross-origin iframes can be blocked or limited.
25+
- Popup and new-tab behavior can be host-dependent.
26+
- Large WASM boot flows may not behave reliably inside the plugin UI.
27+
- Clipboard access can require user activation.
28+
- Local file URLs can behave differently between desktop Figma, browser Figma, and development builds.
29+
30+
Because of those constraints, the primary integration shape is a service handoff: the plugin posts a runner request and opens the returned URL in a browser tab. If in-plugin embedding works later, it can consume the same runner response interface.
31+
32+
## Playground And PHP Role
33+
34+
WordPress Playground is the correct place to run WordPress and PHP plugin logic. It provides a browser-hosted WordPress runtime backed by WebAssembly PHP and a virtual filesystem.
35+
36+
Static Site Importer and Blocks Engine should run in that WordPress runtime because they are WordPress/PHP import systems. The Figma plugin should not reimplement them in TypeScript. The plugin's job is to hand off design data with enough metadata for the WordPress runner to transform, install, activate, and import with those plugins.
37+
38+
## Current Boundary
39+
40+
Implemented now:
41+
42+
- `GeneratedWebsiteArtifact` for static generated files from Figma.
43+
- `figma-to-wordpress/runner-request/v1` for the runner handoff plan.
44+
- A Figma UI client that posts the runner request and opens the returned Playground URL.
45+
46+
Not implemented yet:
47+
48+
- The hosted WordPress runner endpoint that creates the Playground session.
49+
- Post-import block validation and visual parity checks.
50+
51+
## Local Testing
52+
53+
From the repository root, run the plugin checks:
54+
55+
```bash
56+
npm run check --prefix plugins/figma-to-wordpress
57+
npm run build --prefix plugins/figma-to-wordpress
58+
npm test --prefix plugins/figma-to-wordpress
59+
```
60+
61+
Figma development test:
62+
63+
1. Run `npm run build --prefix plugins/figma-to-wordpress`.
64+
2. Load `plugins/figma-to-wordpress/manifest.json` as a Figma development plugin.
65+
3. Run the plugin.
66+
4. Use `Open in WordPress Playground`.
67+
5. Confirm the runner service returns a Playground URL that opens in a normal browser tab.
68+
69+
## Next Integration Step
70+
71+
The next meaningful step is a hosted WordPress runner endpoint with progress/error reporting around the Playground import and post-import block/visual validation. That should remain in the WordPress/Playground runner layer, not by porting PHP importer behavior into the Figma plugin.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Figma to WordPress
2+
3+
This plugin moves a Figma file into WordPress by handing the design to a WordPress runner service that imports it with Static Site Importer and Blocks Engine in WordPress Playground.
4+
5+
It does not port Static Site Importer, Blocks Engine, WordPress, PHP, or Playground internals to TypeScript. The TypeScript code extracts Figma scene data, prepares the runner request, and opens the Playground session URL returned by the WordPress-side runner.
6+
7+
## Flow
8+
9+
```text
10+
Figma plugin controller + UI
11+
-> whole Figma document scene data
12+
-> runner request
13+
-> WordPress runner service
14+
-> WordPress Playground session
15+
-> Static Site Importer imports through Blocks Engine
16+
```
17+
18+
## Boundaries
19+
20+
- Implemented: a Figma Desktop-loadable plugin shell with whole-file export.
21+
- Implemented: a reusable scene-to-HTML/CSS artifact generator with diagnostics and tests for the current local handoff.
22+
- Implemented: a product-neutral runner request that can be posted to a WordPress-side Playground session service.
23+
- Not implemented: running Static Site Importer from TypeScript.
24+
- Not implemented: the hosted WordPress runner endpoint that creates the Playground session and returns its URL.
25+
- Not implemented: automated visual parity/block validation after import.
26+
27+
## Files
28+
29+
- `manifest.json` is a minimal Figma plugin manifest for local development.
30+
- `src/code.ts` is the Figma plugin main thread entry.
31+
- `src/ui.ts` is the Figma UI-side handoff logic.
32+
- `src/index.ts` contains the reusable Figma-scene-to-website-artifact generator.
33+
- `src/payload.ts` contains the reusable TypeScript interfaces for the runner handoff.
34+
- `src/wordpress-runner.ts` posts the runner request and expects an `open_url` response.
35+
- `src/ui.html` is the Figma UI shell bundled into `dist/ui.html`.
36+
37+
## Local Test
38+
39+
1. Run `npm run build --prefix plugins/figma-to-wordpress`.
40+
2. In Figma Desktop, use Plugins -> Development -> Import plugin from manifest, then select `plugins/figma-to-wordpress/manifest.json`.
41+
3. Open the plugin and choose `Open in WordPress Playground`.
42+
4. Confirm the WordPress runner service returns a Playground URL and the plugin opens it in a browser tab.
43+
44+
For quick syntax verification without a full Figma build pipeline:
45+
46+
```bash
47+
npm run check --prefix plugins/figma-to-wordpress
48+
npm run build --prefix plugins/figma-to-wordpress
49+
npm test --prefix plugins/figma-to-wordpress
50+
```
51+
52+
## Runner Boundary
53+
54+
Figma plugin UIs run in a constrained iframe-like environment. Cross-origin iframes, WASM boot, popup behavior, and navigation can be restricted depending on host context and plugin permissions. The supported boundary is a WordPress-side runner service: the plugin posts a runner request, the service creates the Playground session, and the plugin opens the returned URL.
55+
56+
See [`../../docs/figma-playground-runner.md`](../../docs/figma-playground-runner.md) for the integration notes.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{
2+
"id": "0:1",
3+
"name": "Landing Page",
4+
"type": "FRAME",
5+
"width": 1440,
6+
"fills": [
7+
{
8+
"type": "SOLID",
9+
"color": "#f8fafc"
10+
}
11+
],
12+
"children": [
13+
{
14+
"id": "1:1",
15+
"name": "Hero Section",
16+
"type": "FRAME",
17+
"width": 1180,
18+
"height": 640,
19+
"fills": [
20+
{
21+
"type": "SOLID",
22+
"color": "#ffffff"
23+
}
24+
],
25+
"children": [
26+
{
27+
"id": "1:2",
28+
"name": "Hero Title",
29+
"type": "TEXT",
30+
"characters": "Build faster with WordPress",
31+
"style": {
32+
"fontFamily": "Inter",
33+
"fontSize": 56,
34+
"fontWeight": 800,
35+
"lineHeight": 64,
36+
"textAlignHorizontal": "LEFT"
37+
}
38+
},
39+
{
40+
"id": "1:3",
41+
"name": "Hero Copy",
42+
"type": "TEXT",
43+
"characters": "Turn design intent into a clean static artifact before choosing a WordPress implementation path.",
44+
"style": {
45+
"fontSize": 20,
46+
"lineHeight": 30
47+
}
48+
},
49+
{
50+
"id": "1:4",
51+
"name": "Primary Button",
52+
"type": "FRAME",
53+
"width": 220,
54+
"height": 56,
55+
"cornerRadius": 999,
56+
"href": "#start",
57+
"fills": [
58+
{
59+
"type": "SOLID",
60+
"color": "#3858e9"
61+
}
62+
],
63+
"children": [
64+
{
65+
"id": "1:5",
66+
"name": "Button Label",
67+
"type": "TEXT",
68+
"characters": "Start building",
69+
"style": {
70+
"fontSize": 16,
71+
"fontWeight": 700
72+
}
73+
}
74+
]
75+
},
76+
{
77+
"id": "1:6",
78+
"name": "Hero Image",
79+
"type": "IMAGE",
80+
"width": 560,
81+
"height": 360,
82+
"cornerRadius": 24,
83+
"image": {
84+
"src": "assets/hero-placeholder.png",
85+
"alt": "Abstract WordPress builder interface"
86+
}
87+
},
88+
{
89+
"id": "1:7",
90+
"name": "Prototype Connection",
91+
"type": "CONNECTOR"
92+
}
93+
]
94+
}
95+
]
96+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "Figma to WordPress",
3+
"id": "figma-to-wordpress",
4+
"api": "1.0.0",
5+
"main": "dist/code.js",
6+
"ui": "dist/ui.html",
7+
"editorType": ["figma"],
8+
"permissions": []
9+
}

0 commit comments

Comments
 (0)