Skip to content

Commit 5a40332

Browse files
wip
1 parent c133c1f commit 5a40332

10 files changed

Lines changed: 327 additions & 768 deletions

File tree

src/.vuepress/config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { description, base } = require('../../package');
22

33
const addonsSidebar = require('./sidebars/addons');
4+
const atomicEditorSidebar = require('./sidebars/atomic-editor');
45
const cliSidebar = require('./sidebars/cli');
56
const contextMenuSidebar = require('./sidebars/context-menu');
67
const controlsSidebar = require('./sidebars/controls');
@@ -115,6 +116,10 @@ module.exports = {
115116
text: 'The Editor',
116117
link: '/editor/',
117118
},
119+
{
120+
text: 'Atomic Editor',
121+
link: '/atomic-editor/',
122+
},
118123
{
119124
text: 'Editor Controls',
120125
link: '/editor-controls/',
@@ -193,6 +198,7 @@ module.exports = {
193198
],
194199
sidebar: {
195200
'/addons/': addonsSidebar,
201+
'/atomic-editor/': atomicEditorSidebar,
196202
'/cli/': cliSidebar,
197203
'/context-menu/': contextMenuSidebar,
198204
'/controls/': controlsSidebar,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = [
2+
{
3+
title: 'Atomic Editor',
4+
collapsable: false,
5+
sidebarDepth: -1,
6+
children: [
7+
[ '', 'Introduction' ],
8+
]
9+
},
10+
{
11+
title: 'Global Classes',
12+
collapsable: false,
13+
sidebarDepth: -1,
14+
children: [
15+
[ 'global-classes/', 'Overview' ],
16+
'global-classes/data-structures',
17+
'global-classes/actions-filters',
18+
'global-classes/rest-api',
19+
]
20+
},
21+
];
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Actions / Filters
2+
3+
<Badge type="tip" vertical="top" text="Elementor Core" /> <Badge type="warning" vertical="top" text="Intermediate" />
4+
5+
## `elementor/global_classes/update`
6+
7+
Fired after every mutation of the global classes set.
8+
9+
```php
10+
do_action(
11+
'elementor/global_classes/update',
12+
string $context, // 'frontend' | 'preview'
13+
array $changes // [ 'added' => string[], 'deleted' => string[], 'modified' => string[], 'order' => bool ]
14+
);
15+
```
16+
17+
Register with `accepted_args = 2`.
18+
19+
```php
20+
add_action( 'elementor/global_classes/update', function( $context, $changes ) {
21+
foreach ( $changes['deleted'] as $class_id ) {
22+
my_plugin_drop_cached_css( $class_id );
23+
}
24+
}, 10, 2 );
25+
```
26+
27+
## `elementor/atomic-widgets/styles/register`
28+
29+
Fired during style registration. Register custom style sources into `Atomic_Styles_Manager`.
30+
31+
```php
32+
do_action(
33+
'elementor/atomic-widgets/styles/register',
34+
\Elementor\Modules\AtomicWidgets\Styles\Atomic_Styles_Manager $manager,
35+
array $post_ids
36+
);
37+
```
38+
39+
Register with `accepted_args = 2`. Use a `[ <your_key>, $post_id, $context ]` tuple per document.
40+
41+
## `elementor/atomic-widgets/styles/clear`
42+
43+
Fired when style caches should be invalidated. `$key` is a hierarchical tuple.
44+
45+
```php
46+
do_action( 'elementor/atomic-widgets/styles/clear', array $key );
47+
```
48+
49+
| Key | Meaning |
50+
| --- | ------- |
51+
| `[ 'global' ]` | Full clear, all documents and contexts. |
52+
| `[ 'global', $context ]` | One context, all documents. |
53+
| `[ 'global', $post_id ]` | One document, both contexts. |
54+
| `[ 'global', $post_id, $context ]` | One document and context. |
55+
56+
```php
57+
add_action( 'elementor/atomic-widgets/styles/clear', function( array $key ) {
58+
if ( ( $key[0] ?? null ) !== 'global' ) {
59+
return;
60+
}
61+
my_plugin_clear_global_cache( $key );
62+
} );
63+
```
64+
65+
## `elementor/kit/meta_to_preserve_on_kit_import`
66+
67+
Preserve kit-level metadata across kit imports.
68+
69+
```php
70+
add_filter( 'elementor/kit/meta_to_preserve_on_kit_import', function( array $meta_keys ) {
71+
$meta_keys[] = 'my_plugin_kit_meta_key';
72+
return $meta_keys;
73+
} );
74+
```
75+
76+
Global Classes itself registers four keys here (order, frontend labels, preview labels, sync map).
77+
78+
## `elementor/atomic-widgets/settings/transformers/classes`
79+
80+
Unchanged contract; internally now resolves labels via `Global_Classes_Repository::all_labels()`.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Data Structures
2+
3+
<Badge type="tip" vertical="top" text="Elementor Core" /> <Badge type="warning" vertical="top" text="Intermediate" />
4+
5+
## Contexts
6+
7+
Every read/write has two contexts: `frontend` (published) and `preview` (editor draft). They are stored under separate meta keys (`` vs `…_preview`).
8+
9+
## Storage layout
10+
11+
```
12+
wp_posts
13+
├── post_type = e_global_class ← one row per class
14+
│ └── wp_postmeta
15+
│ ├── _elementor_global_class_id → "<class_id>"
16+
│ ├── _elementor_global_class_data → { type, variants, … } (frontend)
17+
│ ├── _elementor_global_class_data_preview → { type, variants, … } (preview)
18+
│ ├── _elementor_global_class_using_documents → [ doc_post_id, … ] (reverse index, frontend)
19+
│ └── _elementor_global_class_using_documents_preview → [ doc_post_id, … ] (reverse index, preview)
20+
21+
└── post_type = elementor_library | page | post | … (any document)
22+
└── wp_postmeta
23+
├── _elementor_used_global_class → class_id (multi-value, frontend)
24+
├── _elementor_used_global_class_preview → class_id (multi-value, preview)
25+
├── _elementor_global_class_usage_indexed → "1"
26+
└── _elementor_global_class_usage_indexed_preview → "1"
27+
```
28+
29+
The active Kit holds:
30+
31+
| Constant | Purpose |
32+
| -------- | ------- |
33+
| `Global_Classes_Order::META_KEY` | Global display order. |
34+
| `Global_Classes_Labels::META_KEY_FRONTEND` | `class_id → label` map (frontend). |
35+
| `Global_Classes_Labels::META_KEY_PREVIEW` | `class_id → label` map (preview). |
36+
| `Global_Classes_Sync_Map::META_KEY` | Design-system sync map. |
37+
| `Global_Classes_Post_IDs` storage | `class_id → e_global_class post ID` lookup. |
38+
39+
## Class item shape
40+
41+
```php
42+
[
43+
'id' => 'g-abc',
44+
'label' => 'Card',
45+
'type' => 'class',
46+
'variants' => [ /* … */ ],
47+
]
48+
```
49+
50+
## Constants
51+
52+
```php
53+
\Elementor\Modules\GlobalClasses\Global_Class_Post_Type::CPT; // 'e_global_class'
54+
\Elementor\Modules\GlobalClasses\Global_Classes_REST_API::MAX_ITEMS; // 1000
55+
```
56+
57+
## PHP repository
58+
59+
```php
60+
use Elementor\Modules\GlobalClasses\Global_Classes_Repository;
61+
62+
$repository = Global_Classes_Repository::make();
63+
$repository->set_preview( true ); // operate on preview/draft
64+
$repository->set_preview( false ); // operate on published (default)
65+
```
66+
67+
| Method | Returns | Notes |
68+
| ------ | ------- | ----- |
69+
| `all_labels()` | `array<string, string>` | `class_id → label`, in order. Cheap. |
70+
| `get( $class_id )` | `?array` | Single item or `null`. |
71+
| `get_by_ids( $class_ids )` | `array<string, array>` | Bulk fetch; missing IDs absent. |
72+
| `get_order()` | `string[]` | Current ordered ID list. |
73+
| `each_item( $cb, $skip_migration = false, $batch_size = 100 )` | `void` | Streams every class in display order. |
74+
| `all( $force = false )` | `Global_Classes` | Heavy — avoid on hot paths. |
75+
| `apply_changes( $touched_items, $changes, $order )` | `void` | Persists only touched items + order/labels diff. |
76+
| `put( $items, $order )` || Replace-everything semantics; diffs internally. |
77+
| `update_order_and_labels( $order, $new_labels )` | `void` | Updates kit-level order/labels only. |
78+
| `delete_all()` | `void` | Removes every class in the current context. |
79+
80+
Both `apply_changes()` and `put()` fire `elementor/global_classes/update`.
81+
82+
## Style cache key
83+
84+
`Atomic_Global_Styles` registers global classes per document. The styles key is:
85+
86+
```
87+
[ 'global', $post_id, $context ]
88+
```
89+
90+
Broader forms also exist: `[ 'global' ]`, `[ 'global', $context ]`, `[ 'global', $post_id ]`.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Global Classes
2+
3+
<Badge type="tip" vertical="top" text="Elementor Core" /> <Badge type="warning" vertical="top" text="Intermediate" />
4+
5+
A Global Class is a reusable, named style definition applied across documents. Each class is stored as an `e_global_class` post; the kit holds only lightweight indexes (order, labels, sync map, post-id map).
6+
7+
* [Data Structures](./data-structures/)
8+
* [Actions / Filters](./actions-filters/)
9+
* [REST API](./rest-api/)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# REST API
2+
3+
<Badge type="tip" vertical="top" text="Elementor Core" /> <Badge type="warning" vertical="top" text="Intermediate" />
4+
5+
All endpoints live under the `elementor/v1` namespace. All read endpoints accept an optional `context` argument: `frontend` (default) or `preview`. Read permission is `is_user_logged_in()`.
6+
7+
## `GET /elementor/v1/global-classes`
8+
9+
Lightweight index — labels only, in display order.
10+
11+
| Argument | Type | Required | Default |
12+
| -------- | ---- | -------- | ------- |
13+
| `context` | string | no | `frontend` |
14+
15+
```json
16+
{
17+
"data": [
18+
{ "id": "g-abc", "label": "Card" },
19+
{ "id": "g-def", "label": "Button" }
20+
]
21+
}
22+
```
23+
24+
## `GET /elementor/v1/global-classes/post`
25+
26+
Full class definitions referenced by a specific document.
27+
28+
| Argument | Type | Required | Default |
29+
| -------- | ---- | -------- | ------- |
30+
| `post_id` | integer | yes ||
31+
| `context` | string | no | `frontend` |
32+
33+
```json
34+
{
35+
"data": {
36+
"g-abc": { "id": "g-abc", "label": "Card", "type": "class", "variants": [ ] }
37+
},
38+
"meta": { "order": [ "g-abc" ] }
39+
}
40+
```
41+
42+
`meta.order` is the intersection of the global order with the IDs used by the document.
43+
44+
## `GET /elementor/v1/global-classes/styles`
45+
46+
Bulk fetch by ID list.
47+
48+
| Argument | Type | Required | Default |
49+
| -------- | ---- | -------- | ------- |
50+
| `ids` | string | yes ||
51+
| `context` | string | no | `frontend` |
52+
53+
`ids` is comma-separated. Missing IDs resolve to `null` in `data` and are omitted from `meta.order`.
54+
55+
```json
56+
{
57+
"data": {
58+
"g-abc": { "id": "g-abc", "label": "Card", "type": "class", "variants": [ ] },
59+
"g-missing": null
60+
},
61+
"meta": { "order": [ "g-abc" ] }
62+
}
63+
```
64+
65+
## `PUT /elementor/v1/global-classes`
66+
67+
Create, update, delete, and reorder.
68+
69+
| Argument | Type | Required | Default | Notes |
70+
| -------- | ---- | -------- | ------- | ----- |
71+
| `context` | string | no | `frontend` | |
72+
| `changes` | object | yes || `{ added, deleted, modified, order? }`. `additionalProperties: false`. |
73+
| `items` | object | yes || Map of `class_id → { id, label, type, variants }` for **touched** items only. |
74+
| `order` | string[] | yes || Full ordered list of class IDs after the operation. |
75+
76+
**Permission:** `current_user_can( Add_Capabilities::UPDATE_CLASS )`.
77+
78+
**Responses:**
79+
80+
- `204 No Content` on success.
81+
- `200 OK` with `{ "code": "DUPLICATED_LABEL", "modifiedLabels": { … } }` when duplicates were auto-renamed.
82+
- `400 Bad Request` with `code: "invalid_items" | "invalid_order" | "global_classes_limit_exceeded"`. The limit error carries `meta.current_count` and `meta.max_allowed`.
83+
84+
Hard limit: **1000** classes. Set `changes.order = true` when reordering, or per-document style caches won't be invalidated.
85+
86+
```js
87+
PUT /elementor/v1/global-classes
88+
{
89+
"context": "frontend",
90+
"changes": {
91+
"added": ["g-new"],
92+
"deleted": [],
93+
"modified": ["g-abc"],
94+
"order": true
95+
},
96+
"items": {
97+
"g-abc": { /* full item */ },
98+
"g-new": { /* full item */ }
99+
},
100+
"order": [ "g-new", "g-abc", "g-def" ]
101+
}
102+
```
103+
104+
## `GET /elementor/v1/global-classes/usage`
105+
106+
Detailed usage report across the site.
107+
108+
| Argument | Type | Required | Default |
109+
| -------- | ---- | -------- | ------- |
110+
| `context` | string | no | `frontend` |
111+
112+
**Permission:** `current_user_can( 'manage_options' )`.

src/atomic-editor/index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Atomic Editor
2+
3+
<Badge type="tip" vertical="top" text="Elementor Core" /> <Badge type="warning" vertical="top" text="Intermediate" />
4+
5+
The Atomic Editor (a.k.a. Elementor v4) is the next-generation editor architecture, built around atomic widgets, a typed settings system, and per-document style generation.
6+
7+
## Sections
8+
9+
* [Global Classes](./global-classes/) — reusable style definitions applied across documents.

0 commit comments

Comments
 (0)