dotCMS / dotCMS/core

[Edit Screen]: tinymceprops Field Variable no longer supports VTL directives (regression from legacy screen)

Open
#36,199 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

stale Team : Maintenance Type : Defect
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Problem Statement

In the legacy edit screen, the `tinymceprops` WYSIWYG field variable value was processed through Velocity server-side before being applied as TinyMCE configuration. This meant customers could use VTL directives in the value — the most common pattern being:

```
#dotInclude("/application/tinymce-editor/tinymceprops.vtl")
```

This was explicitly supported in `edit_field_js.jsp` via:
```java
String propsOverride = VelocityUtil.getInstance().parseVelocity(
field.fieldVariablesMap().get("tinymceprops").value(), ctx
);
```

Because `parseVelocity()` returned the rendered output as a JavaScript string (evaluated directly by the browser), the legacy screen supported any valid JavaScript in the tinymceprops config — including functions.

In the new Edit Content screen (implemented in PR #28074 / issue #27944), the `tinymceprops` field variable value is read as a raw string by the Angular frontend and passed directly to `JSON.parse()` via `stringToJson()`. This introduces two regressions:

  1. VTL directives are not executed — values like `#dotInclude(...)` are never rendered, so the actual config is never loaded. Console shows: `#dotInclude(...) is not a valid JSON`
  2. JavaScript functions are not supported — the new screen only accepts JSON-serializable values. Customers whose config includes functions (e.g. `setup`, `file_picker_callback`, `urlconverter_callback`) cannot save the value at all — the field variable save button is greyed out because the input fails JSON validation.
Impact

This is a complete functional regression for customers with non-trivial TinyMCE customizations. Common use cases that no longer work:

  • `setup` callback — used to hook into editor events (e.g. table wrapping logic, custom `BeforeSetContent`/`Change` handlers)
  • `file_picker_callback` — used to integrate the dotCMS file browser into TinyMCE image/file dialogs
  • `urlconverter_callback` — used for custom URL conversion logic (e.g. `cmsURLConverter`)
  • `external_plugins` with custom plugin JS — still JSON-serializable, but plugins themselves may register callbacks

None of these can be expressed in JSON. Customers who relied on any of these cannot migrate their TinyMCE config to the new screen.

Steps to Reproduce

VTL regression:

  1. On a WYSIWYG field, set the `tinymceprops` field variable to `#dotInclude("/application/tinymce-editor/tinymceprops.vtl")`
  2. Open a contentlet in the new Edit Content screen
  3. Console shows `#dotInclude(...) is not a valid JSON` — TinyMCE loads with default config

Function regression:

  1. On a WYSIWYG field, attempt to set `tinymceprops` to a config containing a `setup` function:
    ```
    { "setup": function(editor) { ... }, "branding": false }
    ```
  2. The field variable save button is greyed out — the input is rejected because functions are not valid JSON
Root Cause

dot-wysiwyg-tinymce.component.ts:

```ts
$customPropsContentField = computed(() => {
const { fieldVariables } = this.$field();
const { tinymceprops } = getFieldVariablesParsed(fieldVariables);
return stringToJson(tinymceprops as string); // raw JSON.parse — no VTL, no functions
});
```

The field variables are returned as raw strings from the REST API. The legacy JSP ran them through `VelocityUtil.parseVelocity()` which returned evaluated JavaScript; the new Angular screen only accepts JSON.

Acceptance Criteria
  • Customers whose `tinymceprops` value contains VTL directives (e.g. `#dotInclude(...)`) should have those resolved server-side before the value reaches the frontend, matching legacy behavior
  • Customers should be able to define function-based TinyMCE config (at minimum `setup`, `file_picker_callback`, `urlconverter_callback`) — the mechanism for this needs to be designed (e.g. a server-side VTL endpoint that returns evaluated JS, or a dedicated Angular hook/extension point)
  • At minimum, the breaking format change must be documented clearly in the WYSIWYG field docs with a migration path
dotCMS Version

Affects all versions with the new Edit Content screen (24.04.16+). Confirmed on `26.06.06-01`.

Related Issues
  • #27944 — original implementation of tinymceprops in new edit screen (did not port VTL support)
  • #28097 — system-wide tinymceprops config implementation
  • #32557 — UX improvement for missing system-wide VTL file (separate issue)
External Links

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with core-web/libs/edit-content/src/lib/fields/dot-edit-content-wysiwyg-field/components/dot-wysiwyg-tinymce/dot-wysiwyg-tinymce.component.ts, especially getFieldVariablesParsed() and stringToJson(), then compare the legacy edit_field_js.jsp path using VelocityUtil.parseVelocity(). Trace how tinymceprops reaches the frontend and define a solution covering VTL and function-based configuration; done means the listed regressions are resolved and the WYSIWYG field documentation includes a migration path.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, java, typescript
Domain
backend, documentation, frontend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.