-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Edit EMA Page #26644
Comments
Edit mode for external pagesAuthor(s): @fmontes Status: [Working] Last Updated: 2023-11-09 ObjectiveEnhance dotCMS edit mode to better integrate with pages rendered by modern frontend frameworks, improving developer implementation and the editing experience for marketers and content creators. Goals
Non-Goals
BackgroundOriginally, dotCMS was tailored for page rendering using VTL and containers, and thus the edit mode was designed accordingly. With the advent of JamStack and the demand for headless CMS, dotCMS allowed external page editing but the implementation is complex and provides a subpar experience for both developers and editors.
Current ProblemsFor developers
For marketers and content creator
For us
OverviewIntroduce a simplified edit mode that doesn't rely on runtime HTML, CSS, and JavaScript injection.
The new approach is very simple:
![]() Detailed DesignThe following four components require development: Edit modeWe have the Angular-based page builder at
We can implement the new solution in this component behind a feature flag. Add, edit, delete contentWhen a event from the iframe is emmited the edit mode will be poping the dialog to work with the content, the same way we do it right now in the current edit mode. After the user finish with it dialog, we need to reload the iframe so the customer app reflects those changes. Customer nextjs appWe're going to provide a starter of this. It will be a simple app that will be rendering pages from demo.dotcms.com and it will implement the dotcms react library. A React libraryWe provide that customer will need to implement into their nextjs app. This library will contain:
Solution 1FrontendWe can implement the feature flag to show/hide old/new iframe here: For the new version: 🚫 We don't need to load the code in the iframe. 🚫 We don't need to subscribe to 🚫 We don't need to subscribe to the iframe actions because new iframe will use 🚫 We don't need to do drag and drop events here because will be moving that to the customer webapp. ✅ We do need to the iframe overlay, so our new iframe should have an olverlay as well because some controls that show on top of the iframe needs to react to iframe clicks. core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 606 to 611 in 2eff4cc
✅ We need to reload the page when the site change. core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 600 to 604 in 2eff4cc
✅ We need the core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Line 559 in 2eff4cc
✅ We need to set allowed contents for the palette core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 378 to 386 in 2eff4cc
core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 535 to 538 in 2eff4cc
core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 125 to 173 in 2eff4cc
Event list: Events from the buttons on containers and contentlets:
Events from edit/add contentlet dialogs:
All this events are handle here: core/core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/dot-edit-content.component.ts Lines 545 to 553 in 8a0c462
Events from the code we inject in the iframe:
All this events are hold here: Lines 823 to 916 in 3790af6
All this events are handle here. Note that in the string we use to inject the code, we make use of RxJS to trigger the events. Because, the handler is a RxJS Subject. Solution 2AngularCreate a new path in our Angular routing Ex. Then we can add an iframe with the Ex. Where Other queryparams we can have:
These parameters can be passed to the page API. This approach facilitate direct page editing in our editor from the developer's localhost, no tunnels or hacks. 1️⃣ Load the page
Store this information in Angular's state for use during editing.
2️⃣ Event Listener
3️⃣ Save After any action that add, delete or relocate a contentlet within the page we need to save the page object to the Page API. The request:
[
{
"identifier": "{containerA-Id}",
"uuid": "{containerA-UUID}",
"contentletsId": [
"{contentletA-ID}"
]
},
{
"identifier": "{containerB-Id}",
"uuid": "{containerB-UUID}",
"contentletsId": [
"contentletB-ID",
"contentletC-ID"
]
}
] So the payload is a list of containers instances (UUID) with all the contentlets inside, that the way the page API know where each contentlet, form or widget goes. To get all the containers and contentlets ids, we have two ways:
I feel the option 1 is better.
Nextjs
Next.js will render pages, sourcing data from dotCMS via the PageAPI. Customizations include: 1️⃣ Routing Implement dynamic routing which allow us to have one nextjs file to render all dotCMS pages. In short dotCMS provide the routes. 2️⃣ Fetching the page Use the "slug" that we can use to fetch the page from the dotCMS page API. Pass URL query parameters ( 3️⃣ Multilang Nextjs have a i18n functionality, we need research how will fit our needs. The JS LibraryThe library simplifies dotCMS page rendering and editor communication for content editing actions. 3️⃣ Components
4️⃣ React Context E.g.
5️⃣ Styles Employ pure CSS for styling to avoid conflicts with customer frameworks. Utilize CSS grids for rows and columns. Create 12 cols grid and use 6️⃣ UI tooling Encapsulate all buttons and styles using react-shadow to prevent CSS specificity conflicts. 7️⃣ Event system We need to
State Management E.g of a state: interface state {
language_id: number;
persona_id: string;
currentPath: string;
mode: 'edit' | 'preview' | 'loading';
previewSelected: string;
action: 'add' | 'edit' | 'delete' | 'bookmark' | 'worklow';
pageState: any;
} Considerations
Metrics
|
Closing and we starting next: #27546 |
Due Date
1/22/2024
Parent Issue
No response
User Story
As a developer, I want to be able to edit the pages of my nextjs app with the dotCMS page builder.
Acceptance Criteria
Proposed Objective
Core Features
Proposed Priority
Priority 2 - Important
External Links... Slack Conversations, Support Tickets, Figma Designs, etc.
N/A
Assumptions & Initiation Needs
Even tho we have edit mode right now, the approach wasn't designed to edit pages created with modern JavaScript frameworks.
Our current approach is too intrusive because we inject HTML, CSS, and JavaScript to the pages to get the tools (buttons) and drag and drop functionality.
Injecting code into a page managed by a JavaScript framework can cause conflicts. HTML injections can disrupt the virtual DOM, leading to render issues, CSS injections may break styles and layouts, and JavaScript injections can interfere with event handling and component lifecycle, potentially breaking page functionality. This leads to compatibility problems with the framework's expected operations.
This is why we need to work on a solution that is less intrusive and that doesn't require injecting code on runtime.
We are not redoing edit mode from the ground up, we are creating a new version by reusing as much all the components and services of the current version.
Quality Assurance Notes & Workarounds
N/A
Sub-Tasks & Estimates
N/A
Tasks
dotcms-page.js
#26820/layout
#26988select-contentlet
is triggering twice on ng-contentlet-selector #26958The text was updated successfully, but these errors were encountered: