Replies: 3 comments 2 replies
-
Does This Break Customer Implementation?This code is a promising solution that provides an API for communication between users and the new edit content feature. However, will this impact the current client implementations? Specifically, clients with extensive custom fields might face challenges when addressing these changes. Discussing this point is crucial, especially if these custom fields are transitioning to a "Legacy" status —something we considered while I was working on Dojo/Dijit Considerations
Alternative SolutionsWhile working on Edit Content, I prioritized maintaining compatibility with existing customer implementations. I developed a POC to ensure custom fields worked seamlessly while emitting their values to Angular. This approach involved dynamically constructing the form for each custom field, preserving all values. The process included creating hidden Proposal: Custom Fields Compatibility Across EditorsSummaryEmbed all input fields within the iframe's HTML to ensure customers can access their values seamlessly. Synchronize Angular and custom fields using PostMessages. Technical Details1. Retrieve Input FieldsThe Angular iframe points to We can utilize String fieldJson = mapper.writeValueAsString(contentType.fieldMap()); 2. Create Input Fields in the iframe HTMLThe following script generates hidden input fields, allowing customers to access them without disrupting their current implementation: <script>
const fields = Object.values(<%= fieldJson %>);
const bodyElement = document.querySelector('body');
// Create fields in the local environment (iframe)
fields.forEach(({ variable, value }) => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = variable;
input.id = variable;
input.setAttribute('dojoType', 'dijit.form.TextBox');
input.value = value;
bodyElement.appendChild(input);
});
<!-- Insert custom field code -->
<%= HTMLString %>
</script> Considerations
3. Synchronize StateUtilize fields.forEach(({ variable }) => {
const input = dojo.byId(variable);
handleGlobalSetInInput(input, variable);
});
function handleGlobalSetInInput(input, variable) {
// Copy the original descriptor from the prototype
const valueDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
Object.defineProperty(input, 'value', {
get() {
return valueDescriptor.get.apply(this);
},
set(value) {
console.log("Triggered on any change, including Dojo updates");
postMessageEditor(variable, value);
valueDescriptor.set.apply(this, [value]);
}
});
} Considerations Dojo's behavior can bypass standard events; for instance, setting Normal HTML updates:
Reference |
Beta Was this translation helpful? Give feedback.
-
The final decision is to create the bridge and to create a migration tool for the customers @danielmdob @john-thomas-dotcms @wezell The plan: Goal Primary Objective
Key Outcomes
Important Note Release Tasks:
Create core API methods for field manipulation:
Demo Site VTLs Enhancement (Task 2, 1 Issue):
Starter Site Updates (Task 3):
Post-Release Tasks:
Migration Tools (A must) (Task 2 / DotAI + Documentation well defined): JavaScript Viewtool Implementation (Task 3) More context: https://dotcms.slack.com/archives/C058GCQ7T39/p1736876783363529 |
Beta Was this translation helpful? Give feedback.
-
Authors: @oarrietadotcms & @nicobytes
Summary
Support custom fields for both versions of the editor: the new Angular-based editor and the legacy Dojo-based editor.
Background
Custom fields require access to form fields to enable custom behaviors. In the old editor, VTL syntax is used with plain JavaScript to achieve this. For example, in the VTL template
text-count.vtl
, the field value is accessed with:This approach enables features like counting characters in a field.
text-count.vtl
However, in the new editor with Angular, custom fields are loaded in an iframe. To access the field value, a reference to the parent element is required:
This works in the new editor but breaks compatibility with the old editor.
Another approach is to expose the Angular form to custom fields, this way was implemented by @kevindaviladev in this PR, allowing access via:
While this works well in the new editor, it fails in the old editor due to the lack of Angular form references. Additionally, exposing Angular Forms ties the implementation to Angular APIs, which might change over time, necessitating VTL template rewrites.
Proposal
Using the Bridge and Facade Patterns, create a
DotFormAPI
to standardize access to field values across both editors. The API provides methods like:Example
text-count.vtl
Or in another vtl template to create a slug.
Using this approach, we can create a custom field that works in both the new and the old editor. More importantly, we are not exposed to the Angular Forms API, and we can change the API without affecting the VTLSs. For example, if we use the new Angular Signals forms in the future, we can change the API without affecting the VTLSs. Alternatively, if in the future dotAdmin wants to use another form library, such as TanStack Angular Form, we can change the API (DotFormAPI) without affecting the VTLs.
Impact
Benefits
Trade-offs
Technical Details
DotFormAPI For Angular
DotFormAPI for Dojo
Beta Was this translation helpful? Give feedback.
All reactions