Skip to content

Commit c293df5

Browse files
fashxpCopilotlukmzig
authored
Doc refactoring (#1719)
* adapting structure, fixing typos, spelling, grammar and links * updating gdpr docs * general extensions restructuring * extending - custom grid columns * extending - custom icons & tooltips * extending - custom perspective widgets * doc style adaptions & front matter * doc style adaptions & front matter * doc style & content adaptions * doc style & content adaptions * link fixes * restructuring studio-backend bundle * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add docs for field types and translations --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: lukmzig <lukas.mzigot@pimcore.com>
1 parent 5bcdd60 commit c293df5

38 files changed

Lines changed: 2557 additions & 1047 deletions

README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ It provides a unified interface based on the OpenApi Specification for all backe
1111

1212
It uses [zircote/swagger-php](https://github.com/zircote/swagger-php) attributes to generate the OpenApi Specification.
1313

14-
Swagger-ui is available at `/pimcore-studio/api/docs` and the OpenApi Specification is available at `/pimcore-studio/api/docs.json`.
15-
Every description is translatable and can be found in the `studio_api_docs.en.yaml` folder of the bundle.
14+
Swagger UI is available at `/pimcore-studio/api/docs` in the `dev` environment, and the OpenApi Specification (JSON) is available at `/pimcore-studio/api/docs/json`.
15+
Every description is translatable and can be found in the `studio_api_docs.en.yaml` file of the bundle.
1616

1717
## Requirements
1818
This bundle requires the following dependencies:
@@ -22,11 +22,20 @@ This bundle requires the following dependencies:
2222
* Generic Data Index
2323
* Mercure (https://mercure.rocks)
2424

25+
## Features in a Nutshell
26+
27+
- OpenAPI-documented REST API for all Pimcore operations (assets, data objects, documents)
28+
- Real-time updates via Mercure (Server-Sent Events)
29+
- Extensible architecture: custom endpoints, filters, grid columns, document types
30+
- Grid system with configurable columns, filters, and data transformers
31+
- Generic Execution Engine integration for background task processing
32+
- GDPR data extraction support
33+
- Perspective and widget system for UI customization
34+
- Comprehensive event system for customization hooks
35+
2536
## Documentation Overview
2637

27-
- [Installation](./doc/00_Installation.md)
28-
- [Mercure Setup](./doc/02_Mercure_Setup.md)
29-
- [Grid](./doc/03_Grid.md)
30-
- [Generic Execution Engine](./doc/04_Generic_Execution_Engine.md)
31-
- [Additional Attributes](./doc/05_Additional_Custom_Attributes.md)
32-
- [Studio User](./doc/07_User.md)
38+
- [Architecture Overview](./doc/01_Architecture_Overview/README.md)
39+
- [Installation and Configuration](./doc/02_Installation_and_Configuration/README.md)
40+
- [Extending](./doc/03_Extending/README.md)
41+
- [Development Details](./doc/04_Development_Details/README.md)
Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
1+
---
2+
title: Grid
3+
description: "Grid system architecture: columns, filters, transformers, and configuration."
4+
---
5+
16
# Grid
27

3-
On the request level we have three main components for the grid: `Column`, `ColumnConfiguration` and `ColumnData`.
8+
The grid API has three main request-level components: `Column`, `ColumnConfiguration`, and `ColumnData`.
49

510
## Column
6-
A column is a single column in the grid. It has a name, type and a locale. It is used to get the data for the column.
7-
in addition, it has a configuration which can be used to configure the column, like the direction of the sorting
11+
12+
A column defines which data to fetch. It has a name, type, and locale, plus an optional configuration
13+
(e.g. sort direction).
814

915
## ColumnConfiguration
10-
A column configuration represents how the column should behave, for example if it should be sort-able or editable.
11-
For the column to be exportable please make sure that it can be represented as a string.
16+
17+
A column configuration declares how the column behaves: sortable, filterable, editable, exportable.
18+
For export support, the column value must be representable as a string.
1219

1320
## ColumnData
14-
A column data is the actual data for a column. It has a reference to the column and the actual data.
1521

22+
The actual data for a column. Contains a reference to the column definition and the resolved value.
1623

1724
## Filter
18-
A filter is a way to filter the data in the grid. One Property of getting the grid data is the `filter` property.
19-
Here you can define `page`, `pageSize` and `includeDescendants`.
2025

21-
`page` is the page number of the data you want to get.
22-
`pageSize` is the number of items you want to get.
23-
`includeDescendants` is a boolean value to include the descendants of the current item.
26+
The grid `filter` property controls pagination and scope:
27+
28+
- `page` - the page number
29+
- `pageSize` - the number of items per page
30+
- `includeDescendants` - whether to include child elements
2431

2532
### ColumnFilter
26-
It is also possible to filter the data by a column. This is done by adding a `columnFilter` to the `filter` property.
27-
A `columnFilter` has a reference to the column and the value you want to filter by. Some filters do not require a
28-
specific column, like the `system.tag` filter. This filters will be applied to the general search query.
33+
34+
Add a `columnFilter` to the `filter` property to filter by specific column values. Each column filter
35+
references a column and a filter value. Some filters (e.g. `system.tag`) apply to the general search
36+
query and do not require a specific column key.
2937

3038
Available filters are:
3139

@@ -52,7 +60,7 @@ Available filters are:
5260
| classificationstore.date | object of ISO 8601<br/>will round to day | `from`, `to`, or `on` | true |
5361
| classificationstore.datetime | object of ISO 8601 | `from`, `to`, or `on` | true |
5462
| classificationstore.time | object (12:45) | `from`, `to`, or `on` | true |
55-
| classificationstore.quantity_value | sting, integer | `from`, `to`, `is`, `setting`, `unitId` | true |
63+
| classificationstore.quantity_value | string, integer | `from`, `to`, `is`, `setting`, `unitId` | true |
5664
| classificationstore.input_quantity_value | string | `unitId`(string), `value`(string) | true |
5765
| classificationstore.select | array | | true |
5866
| classificationstore.boolean | array | `true`, `false` or `null` | true |
@@ -124,7 +132,7 @@ Filter by Number:
124132
```
125133

126134
Classification Store Basic Filter Value:
127-
The filter value of a Classification Store looks a bit difrent. All Filter need to have a groupId and keyId
135+
The filter value of a Classification Store looks a bit different. All filters need to have a groupId and keyId
128136
```json
129137
...
130138
"columnFilters" [
@@ -167,12 +175,14 @@ To filter by this structure:
167175
```
168176

169177
## Advanced Columns
170-
Advanced columns are a special type of column that can be used to display data in a more advanced way. There are a few types of data sources for advanced columns:
171-
- `simpleField` - a simple field in the object
172-
- `relationField` - a relation field in the object
173-
- `staticText` - a static text that is not related to the object
174178

175-
Let's take a look at the `simpleField` type. The `simpleField` call the getter method of the object. You just have to pass the `field`.
179+
Advanced columns combine multiple data sources and transformers. Data source types:
180+
181+
- `simpleField` - calls a getter method on the object
182+
- `relationField` - resolves a value through a relation
183+
- `staticText` - a fixed text value, not related to the object
184+
185+
The `simpleField` type calls the object's getter for the specified field:
176186
```json
177187
...
178188
"columns": [
@@ -341,7 +351,7 @@ Available configurations:
341351
"transformers": [
342352
{
343353
"key": "combine",
344-
"congfig": {
354+
"config": {
345355
"glue": " - "
346356
}
347357
}

doc/04_Generic_Execution_Engine.md renamed to doc/01_Architecture_Overview/02_Generic_Execution_Engine.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Generic Execution Engine
3+
description: Background task processing for bulk operations, exports, and asynchronous jobs.
4+
---
5+
16
# Generic Execution Engine
27
:::caution
38

@@ -7,9 +12,11 @@ Messages are dispatched via `pimcore_generic_execution_engine` transport. Please
712

813
:::
914

10-
The Generic Execution Engine is a powerful tool to execute actions in the background. It is based on the Symfony Messenger component, to learn more about it, please visit the [Generic Execution Engine documentation](https://github.com/pimcore/pimcore/tree/11.x/doc/19_Development_Tools_and_Details/08_Generic_Execution_Engine).
15+
The Generic Execution Engine executes long-running actions in the background using the Symfony Messenger
16+
component. For the core framework documentation, see the
17+
[Generic Execution Engine](https://github.com/pimcore/pimcore/blob/2026.x/doc/09_Development_Tools/01_Generic_Execution_Engine/README.md).
1118

12-
There are several actions, which currently take benefits of Execution Engine:
19+
The Studio Backend uses the Execution Engine for these operations:
1320

1421
### Asset ZIP Upload
1522
When uploading a ZIP file containing assets, the ZIP file is extracted and the assets are created in the background.
@@ -28,11 +35,11 @@ pimcore_studio_backend:
2835
```
2936
3037
### Element CSV Export
31-
Elements like Assets and Data Objects can be exported based on the provided grid configuration as a CSV file. The export is done in the background and can be downloaded after its finished.
38+
Elements like Assets and Data Objects can be exported based on the provided grid configuration as a CSV file. The export is done in the background and can be downloaded after it's finished.
3239
There are some configuration options available for the CSV export, which can be configured in the `config.yaml` file.
3340

3441
### Element XLSX Export
35-
Elements like Assets and Data Objects can be exported based on the provided grid configuration as a XLSX file. The export is done in the background and can be downloaded after its finished.
42+
Elements like Assets and Data Objects can be exported based on the provided grid configuration as a XLSX file. The export is done in the background and can be downloaded after it's finished.
3643

3744
```yaml
3845
pimcore_studio_backend:
@@ -49,15 +56,15 @@ Assets, Documents, Data Objects and folders can be deleted in the background. Th
4956

5057
### Elements Recycle Bin
5158
Before deleting elements, they and the respective children are moved to the recycle bin. This is done in the background while using the Generic Execution Engine.
52-
by default, recycle bin in only used for elements with less than 100 children. This can be configured in the `config.yaml` file.
59+
By default, the recycle bin is only used for elements with fewer than 100 children. Configure the threshold in `config.yaml`:
5360

5461
```yaml
5562
pimcore_studio_backend:
5663
element_recycle_bin_threshold: 100
5764
```
5865

5966
### Elements Patching
60-
Patching of multiple elements is executed with the help of Generic Execution Engine in the background. This is useful when using a bulk patches on a large number of elements.
67+
Patching of multiple elements is executed with the help of Generic Execution Engine in the background. This is useful when using bulk patches on a large number of elements.
6168

6269
### Elements Rewrite References
6370
When cloning elements, the references to other elements can be rewritten. When this is desired, the action is executed in the background. This is useful when cloning a large number of elements or large trees.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
title: Architecture Overview
3+
description: REST API design, request flow, tagged service extensibility, and core subsystems.
4+
---
5+
6+
# Architecture Overview
7+
8+
The Studio Backend Bundle exposes a REST API built on Symfony that serves as the backend for
9+
Pimcore Studio. All endpoints are documented via OpenAPI/Swagger attributes using the
10+
[zircote/swagger-php](https://zircote.github.io/swagger-php/) library.
11+
12+
## Request Flow
13+
14+
A typical API request flows through these layers:
15+
16+
```
17+
HTTP Request
18+
→ Symfony Firewall (pimcore_studio authentication)
19+
→ Route matching (#[Route] attribute)
20+
→ Permission check (#[IsGranted] attribute, UserPermissionVoter)
21+
→ Controller (extends AbstractApiController)
22+
→ Service layer (business logic, data access)
23+
→ Hydrator (transforms models to API schema objects)
24+
→ PreResponse event (dispatched before serialization)
25+
→ JSON serialization (Symfony Serializer)
26+
→ HTTP Response
27+
```
28+
29+
**Controllers** extend `AbstractApiController`, which provides `jsonResponse()` for JSON
30+
serialization and a configurable URL prefix (`{prefix}`). Controllers use Symfony's
31+
`#[MapQueryString]` and `#[MapRequestPayload]` for type-safe parameter binding.
32+
33+
**Services** encapsulate business logic behind interfaces (e.g. `NoteServiceInterface`,
34+
`LayoutServiceInterface`). Controllers depend on service interfaces, not implementations.
35+
36+
**Hydrators** transform Pimcore model objects into typed API schema classes. Schema classes
37+
use OpenAPI `#[Schema]` and `#[Property]` attributes to generate the Swagger documentation.
38+
39+
**PreResponse events** fire after hydration but before serialization, letting subscribers add
40+
custom attributes or modify the response. See
41+
[Additional and Custom Attributes](../03_Extending/02_Additional_and_Custom_Attributes.md)
42+
for the full event list.
43+
44+
## Authentication and Security
45+
46+
The bundle registers its own Symfony firewall (`pimcore_studio`) with a custom user provider
47+
(`Pimcore\Security\User\UserProvider`). Authentication uses bearer tokens obtained through
48+
the login endpoint. The `UserPermissionVoter` evaluates `#[IsGranted]` attributes against
49+
permissions stored in `users_permission_definitions`.
50+
51+
## Tagged Service Extensibility
52+
53+
Most extension points follow the same pattern: implement an interface, tag the service,
54+
and the bundle auto-discovers it at runtime. Key service tags:
55+
56+
| Tag | Purpose |
57+
|-----|---------|
58+
| `pimcore.studio_backend.update_adapter` | Element update pipeline |
59+
| `pimcore.studio_backend.patch_adapter` | Bulk patch pipeline |
60+
| `pimcore.studio_backend.data_adapter` | Data object field save/load |
61+
| `pimcore.studio_backend.grid_column_definition` | Grid column type registration |
62+
| `pimcore.studio_backend.grid_column_resolver` | Grid column value resolution |
63+
| `pimcore.studio_backend.grid_column_collector` | Grid column availability |
64+
| `pimcore.studio_backend.grid_transformer` | Grid data transformation |
65+
| `pimcore.studio_backend.search_index.filter` | Search index filters (OpenSearch/ES) |
66+
| `pimcore.studio_backend.listing.filter` | Listing filters (classic Pimcore listings) |
67+
| `pimcore.studio_backend.field_definition_resolver` | Field definition resolution (dot notation) |
68+
| `pimcore.studio_backend.widget_repository` | Perspective widget config storage |
69+
| `pimcore.studio_backend.widget_hydrator` | Perspective widget config hydration |
70+
| `pimcore.studio_backend.gdpr_data_provider` | GDPR data extraction |
71+
| `pimcore.studio_backend.settings_provider` | Settings panel data |
72+
| `pimcore.studio_backend.filter_service` | Filter service registration |
73+
74+
Most tags have dedicated guides in [Extending](../03_Extending/README.md). Tags without
75+
a dedicated guide (`settings_provider`, `filter_service`) follow the same pattern:
76+
implement the interface and register with the tag.
77+
78+
## Real-Time Updates
79+
80+
The bundle integrates [Mercure](https://mercure.rocks/) to deliver real-time updates to
81+
connected Pimcore Studio clients via Server-Sent Events (SSE). When elements are created,
82+
modified, or deleted, the backend publishes updates that connected clients receive instantly
83+
without polling. See [Mercure Setup](../02_Installation_and_Configuration/01_Mercure_Setup.md)
84+
for configuration details.
85+
86+
## Core Subsystems
87+
88+
### Grid System
89+
90+
The Grid system provides configurable columns, filters, and data transformers for listing
91+
and searching assets, data objects, and documents. It is composed of three main components:
92+
column definitions (what columns exist), column resolvers (how values are fetched), and
93+
column collectors (which columns are available in a given context).
94+
95+
- [Grid Architecture](./01_Grid.md)
96+
97+
### Generic Execution Engine
98+
99+
The Generic Execution Engine handles long-running and background tasks such as bulk operations,
100+
CSV/XLSX exports, ZIP uploads/downloads, and element cloning. It provides a unified interface
101+
for scheduling, tracking progress, and reporting results.
102+
103+
- [Generic Execution Engine](./02_Generic_Execution_Engine.md)
104+
105+
### MCP Server Infrastructure (Experimental)
106+
107+
The bundle provides shared infrastructure for
108+
[Model Context Protocol](https://modelcontextprotocol.io/) (MCP) servers. This includes a
109+
dedicated `pimcore_mcp` firewall (separate from the Studio API firewall), a dual authentication
110+
chain (session bridge for internal agent-server use, personal access tokens for external MCP
111+
clients like Claude Desktop or Cursor), and pre-registered PSR-7/PSR-17 bridge services.
112+
Bundles that implement MCP servers route their controllers under `/pimcore-mcp/` and get
113+
authentication handled automatically.
114+
115+
- [MCP Server Infrastructure](../04_Development_Details/08_MCP_Server.md)

doc/02_Mercure_Setup.md renamed to doc/02_Installation_and_Configuration/01_Mercure_Setup.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Mercure Setup
3+
description: Configure Mercure for real-time updates in Pimcore Studio.
4+
---
5+
16
# Mercure Setup
27

38
## Start and configure Mercure server
@@ -142,10 +147,10 @@ routed correctly to the Mercure instance.
142147
Also, keep in mind, that communication needs to be HTTPS. Thus, it might be useful to place the Mercure server behind a reverse
143148
proxy of the actual webserver (who handles the certificates).
144149

145-
Beware that the development ui is not working when using a reverse proxy. (See open ticket https://github.com/dunglas/mercure/issues/951)
150+
Beware that the development UI is not working when using a reverse proxy. (See open ticket https://github.com/dunglas/mercure/issues/951)
146151

147152
#### Apache Reverse Proxy
148-
For apache for example enable `http_proxy` in apache and add the following reverse proxy in your apache config:
153+
For Apache, for example, enable `http_proxy` in apache and add the following reverse proxy in your apache config:
149154
```
150155
ProxyPass /hub/ http://localhost:3000/
151156
ProxyPassReverse /hub/ http://localhost:3000/
@@ -160,7 +165,7 @@ For Nginx use following configuration:
160165
```
161166

162167
### Development UI
163-
The development ui can be helpful to develop new features. It is possible to subscribe and publish messages.
168+
The development UI can be helpful to develop new features. It is possible to subscribe and publish messages.
164169

165170
With the configuration below, the development ui is available at `http://localhost:8080/.well-known/mercure/ui/`.
166171

doc/07_User.md renamed to doc/02_Installation_and_Configuration/02_Studio_User.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: Studio User
3+
description: Default key bindings and user configuration for Pimcore Studio.
4+
---
5+
16
# Studio User
27
## Default Key Bindings
38
To change the default key bindings, you can add a Symfony configuration file in your project.

doc/10_Extending_Studio/07_Notes.md renamed to doc/02_Installation_and_Configuration/03_Defining_Note_Types.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
# Extending Notes
1+
---
2+
title: Defining Note Types
3+
description: Add custom note types for assets, documents, and data objects.
4+
---
5+
6+
# Defining Note Types
27

38
Notes to log changes or events on elements independently of the versioning. You can get more general information about notes [here](https://pimcore.com/docs/platform/Pimcore/Tools_and_Features/Notes_and_Events/)
49

0 commit comments

Comments
 (0)