@dotcms/uve 0.0.1-beta.13 → 0.0.1-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,16 +1,37 @@
1
1
  # DotCMS UVE SDK
2
2
 
3
- A JavaScript library to connect your dotCMS pages with the Universal Visual Editor (UVE) and enable content authors to edit pages in real time.
3
+ A JavaScript library to connect your dotCMS pages with the Universal Visual Editor (UVE) and enable content authors to edit pages in real time.
4
+
5
+ > **BETA VERSION NOTICE:** This SDK is currently in beta. APIs, functionality, and documentation may change significantly in the stable release.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Installation](#installation)
10
+ - [Entry Points](#entry-points)
11
+ - [Getting Started](#getting-started)
12
+ - [API Reference](#api-reference)
13
+ - [Editor State](#editor-state)
14
+ - [Event Subscriptions](#event-subscriptions)
15
+ - [Content Editing](#content-editing)
16
+ - [Navigation & UI](#navigation--ui)
17
+ - [Messaging](#messaging)
18
+ - [Types Reference](#types-reference)
19
+ - [Examples](#examples)
20
+ - [Contributing](#contributing)
21
+ - [License](#license)
4
22
 
5
23
  ## Installation
6
24
 
7
25
  The UVE SDK is automatically included in DotCMS installations. For external usage:
8
26
 
9
27
  ```bash
28
+ # Using npm
29
+ npm install @dotcms/uve-sdk
30
+
31
+ # Using yarn
10
32
  yarn add @dotcms/uve-sdk
11
33
  ```
12
34
 
13
-
14
35
  ## Entry Points
15
36
 
16
37
  The library exposes three main entry points:
@@ -19,36 +40,35 @@ The library exposes three main entry points:
19
40
 
20
41
  - **`@dotcms/uve/types`**: Offers TypeScript types, interfaces, and other structures to help users organize their code properly.
21
42
 
22
- ---
23
-
24
- ## Functions
25
-
26
- ### `createUVESubscription`
27
-
28
- Subscribe to the pages changes. Receive a callback that will be called with the updated content of the page.
29
-
30
- **Parameters:**
31
- - `eventType` - The type of event to subscribe to.
32
- - `callback` - The callback function that will be called when the event occurs.
43
+ ## Getting Started
33
44
 
34
- **Returns:**
35
- - An event subscription that can be used to unsubscribe.
45
+ To use the UVE SDK in your project, import the necessary functions:
36
46
 
37
- **Example:**
38
- ***typescript
39
- // Subscribe to page changes
40
- const subscription = createUVESubscription(UVEEventType.CONTENT_CHANGES, (changes) => {
41
- console.log('Content changes:', changes);
42
- });
43
-
44
- // Unsubscribe
45
-
46
- subscription.unsubscribe()
47
+ ```typescript
48
+ import { getUVEState, createUVESubscription, editContentlet } from '@dotcms/uve';
49
+ import { UVEEventType, UVE_MODE } from '@dotcms/uve/types';
50
+
51
+ // Check if we're in the editor
52
+ const uveState = getUVEState();
53
+ if (uveState?.mode === UVE_MODE.EDIT) {
54
+ console.log('Running in edit mode!');
55
+
56
+ // Subscribe to content changes
57
+ const subscription = createUVESubscription(UVEEventType.CONTENT_CHANGES, (changes) => {
58
+ console.log('Content updated:', changes);
59
+ // Update your UI with the new content
60
+ });
61
+
62
+ // Later, when no longer needed
63
+ subscription.unsubscribe();
64
+ }
47
65
  ```
48
66
 
49
- ---
67
+ ## API Reference
68
+
69
+ ### Editor State
50
70
 
51
- ### `getUVEState`
71
+ #### `getUVEState`
52
72
 
53
73
  Retrieves the current UVE state.
54
74
 
@@ -73,9 +93,33 @@ if (editorState?.mode === 'edit') {
73
93
  }
74
94
  ```
75
95
 
76
- ---
96
+ ### Event Subscriptions
97
+
98
+ #### `createUVESubscription`
99
+
100
+ Subscribe to page changes and other UVE events. Receive a callback that will be called with the updated content of the page.
101
+
102
+ **Parameters:**
103
+ - `eventType` - The type of event to subscribe to.
104
+ - `callback` - The callback function that will be called when the event occurs.
105
+
106
+ **Returns:**
107
+ - An event subscription that can be used to unsubscribe.
108
+
109
+ **Example:**
110
+ ```typescript
111
+ // Subscribe to page changes
112
+ const subscription = createUVESubscription(UVEEventType.CONTENT_CHANGES, (changes) => {
113
+ console.log('Content changes:', changes);
114
+ });
115
+
116
+ // Later, unsubscribe when no longer needed
117
+ subscription.unsubscribe();
118
+ ```
119
+
120
+ ### Content Editing
77
121
 
78
- ### `editContentlet`
122
+ #### `editContentlet`
79
123
 
80
124
  Allows you to edit a contentlet in the editor.
81
125
 
@@ -86,12 +130,33 @@ Calling this function within the editor prompts the UVE to open a dialog to edit
86
130
 
87
131
  **Example:**
88
132
  ```typescript
133
+ // Edit a contentlet
89
134
  editContentlet(myContentlet);
90
135
  ```
91
136
 
92
- ---
137
+ #### `initInlineEditing`
93
138
 
94
- ### `reorderMenu`
139
+ Initializes inline editing in the editor.
140
+
141
+ **Parameters:**
142
+ - `type` - The type of inline editing ('BLOCK_EDITOR' or 'WYSIWYG').
143
+ - `data` - (Optional) Data for the inline editing session.
144
+
145
+ **Example:**
146
+ ```typescript
147
+ // Initialize block editor
148
+ initInlineEditing('BLOCK_EDITOR', {
149
+ inode: 'abc123',
150
+ language: 1,
151
+ contentType: 'Blog',
152
+ fieldName: 'body',
153
+ content: { /* content data */ }
154
+ });
155
+ ```
156
+
157
+ ### Navigation & UI
158
+
159
+ #### `reorderMenu`
95
160
 
96
161
  Reorders the menu based on the provided configuration.
97
162
 
@@ -104,46 +169,156 @@ This function constructs a URL for the reorder menu page with the specified `sta
104
169
 
105
170
  **Example:**
106
171
  ```typescript
172
+ // Reorder menu starting from level 2 with depth of 3
107
173
  reorderMenu({ startLevel: 2, depth: 3 });
108
174
  ```
109
175
 
110
- ---
176
+ ### Messaging
111
177
 
112
- ### `initInlineEditing`
178
+ #### `sendMessageToUVE`
113
179
 
114
- Initializes inline editing in the editor.
180
+ The `sendMessageToUVE` function allows you to send messages to the dotCMS page editor. This is useful for triggering specific actions or updating the editor's state.
181
+
182
+ This function is primarily used within other library functions but can be helpful if you need to trigger specific behavior by sending a message to the UVE.
115
183
 
116
184
  **Example:**
117
185
  ```typescript
118
- initInlineEditing();
186
+ sendMessageToUVE({
187
+ action: DotCMSUVEAction.CUSTOM_MESSAGE,
188
+ payload: { key: 'value' }
189
+ });
119
190
  ```
120
191
 
121
- ---
192
+ ### Available Message Types (DotCMSUVEAction)
122
193
 
123
- ### `sendMessageToUVE`
194
+ | **Type** | **Description** |
195
+ |--------------------------------------|---------------------------------------------------------------------------------------------------|
196
+ | `NAVIGATION_UPDATE` | Notifies the dotCMS editor that the page has changed. |
197
+ | `SET_BOUNDS` | Sends the position of rows, columns, containers, and contentlets to the editor. |
198
+ | `SET_CONTENTLET` | Sends information about the currently hovered contentlet. |
199
+ | `IFRAME_SCROLL` | Informs the editor that the page is being scrolled. |
200
+ | `IFRAME_SCROLL_END` | Notifies the editor that scrolling has stopped. |
201
+ | `PING_EDITOR` | Pings the editor to check if the page is inside the editor. |
202
+ | `INIT_INLINE_EDITING` | Initializes the inline editing mode in the editor. |
203
+ | `COPY_CONTENTLET_INLINE_EDITING` | Opens the "Copy Contentlet" dialog to duplicate and edit a contentlet inline. |
204
+ | `UPDATE_CONTENTLET_INLINE_EDITING` | Triggers the save action for inline-edited contentlets. |
205
+ | `REORDER_MENU` | Triggers the menu reorder action with a specified configuration. |
206
+ | `GET_PAGE_DATA` | Requests the current page information from the editor. |
207
+ | `CLIENT_READY` | Indicates that the client has completed initialization. |
208
+ | `EDIT_CONTENTLET` | Opens the contentlet editing dialog in the editor. |
209
+
210
+ ## Types Reference
211
+
212
+ The SDK provides TypeScript types to assist in development:
213
+
214
+ ### UVE State and Modes
124
215
 
125
- The `sendMessageToUVE` function allows you to send messages to the dotCMS page editor. This is useful for triggering specific actions or updating the editor's state.
216
+ ```typescript
217
+ // UVE State Interface
218
+ interface UVEState {
219
+ mode: UVE_MODE;
220
+ persona: string | null;
221
+ variantName: string | null;
222
+ experimentId: string | null;
223
+ publishDate: string | null;
224
+ languageId: string | null;
225
+ }
126
226
 
127
- This function is primarily used within other libraries but can be helpful if you need to trigger specific behavior by sending a message to the UVE.
227
+ // UVE Mode Enum
228
+ enum UVE_MODE {
229
+ EDIT = 'EDIT_MODE',
230
+ PREVIEW = 'PREVIEW_MODE',
231
+ LIVE = 'LIVE',
232
+ UNKNOWN = 'UNKNOWN'
233
+ }
234
+ ```
235
+
236
+ ### UVE Events
128
237
 
129
- **Example:**
130
238
  ```typescript
131
- sendMessageToEditor({ type: 'CUSTOM_MESSAGE': DotCMSUVEAction, payload: { key: 'value' } });
239
+ // Event Types Enum
240
+ enum UVEEventType {
241
+ CONTENT_CHANGES = 'changes',
242
+ PAGE_RELOAD = 'page-reload',
243
+ REQUEST_BOUNDS = 'request-bounds',
244
+ IFRAME_SCROLL = 'iframe-scroll',
245
+ CONTENTLET_HOVERED = 'contentlet-hovered'
246
+ }
247
+
248
+ // Event Subscription Interface
249
+ interface UVEEventSubscription {
250
+ unsubscribe: () => void;
251
+ event: string;
252
+ }
132
253
  ```
133
254
 
134
- ### Available Message Types (DotCMSUVEAction)
255
+ ## Examples
135
256
 
136
- | **Type** | **Description** |
137
- |--------------------------------------|---------------------------------------------------------------------------------------------------|
138
- | `set-url` | Notifies the dotCMS editor that the page has changed. |
139
- | `set-bounds` | Sends the position of rows, columns, containers, and contentlets to the editor. |
140
- | `set-contentlet` | Sends information about the currently hovered contentlet. |
141
- | `scroll` | Informs the editor that the page is being scrolled. |
142
- | `scroll-end` | Notifies the editor that scrolling has stopped.
143
- | `init-inline-editing` | Initializes the inline editing mode in the editor. |
144
- | `copy-contentlet-inline-editing` | Opens the "Copy Contentlet" dialog to duplicate and edit a contentlet inline. |
145
- | `update-contentlet-inline-editing` | Triggers the save action for inline-edited contentlets. |
146
- | `reorder-menu` | Triggers the menu reorder action with a specified configuration. |
147
- | `get-page-data` | Requests the current page information from the editor. |
148
- | `client-ready` | Indicates that the client has sent a GraphQL query to the editor. |
149
- | `edit-contentlet` | Opens the contentlet editing dialog in the editor. |
257
+ ### Basic Usage
258
+
259
+ ```typescript
260
+ import { getUVEState, createUVESubscription } from '@dotcms/uve';
261
+ import { UVEEventType, UVE_MODE } from '@dotcms/uve/types';
262
+
263
+ // Check if we're in the editor
264
+ const uveState = getUVEState();
265
+ if (uveState) {
266
+ console.log(`Running in ${uveState.mode} mode`);
267
+
268
+ // Initialize components based on editor state
269
+ if (uveState.mode === UVE_MODE.EDIT) {
270
+ enableEditFeatures();
271
+ }
272
+ }
273
+ ```
274
+
275
+ ### Content Updates
276
+
277
+ ```typescript
278
+ import { createUVESubscription } from '@dotcms/uve';
279
+ import { UVEEventType } from '@dotcms/uve/types';
280
+
281
+ // Subscribe to content changes
282
+ const subscription = createUVESubscription(UVEEventType.CONTENT_CHANGES, (changes) => {
283
+ // Update your UI with the new content
284
+ updateUI(changes);
285
+ });
286
+
287
+ // Clean up when component unmounts
288
+ function cleanup() {
289
+ subscription.unsubscribe();
290
+ }
291
+ ```
292
+
293
+ ### Inline Editing Integration
294
+
295
+ ```typescript
296
+ import { initInlineEditing } from '@dotcms/uve';
297
+
298
+ // Integrate with a block editor component
299
+ function setupBlockEditor(element, contentData) {
300
+ element.addEventListener('click', () => {
301
+ initInlineEditing('BLOCK_EDITOR', {
302
+ inode: contentData.inode,
303
+ language: contentData.languageId,
304
+ contentType: contentData.contentType,
305
+ fieldName: 'body',
306
+ content: contentData.content
307
+ });
308
+ });
309
+ }
310
+ ```
311
+
312
+ ## Contributing
313
+
314
+ We welcome contributions to the UVE SDK! Please follow these steps:
315
+
316
+ 1. Fork the repository
317
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
318
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
319
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
320
+ 5. Open a Pull Request
321
+
322
+ ## License
323
+
324
+ This project is licensed under the MIT License - see the LICENSE file for details.
package/internal.cjs.js CHANGED
@@ -210,6 +210,167 @@ function computeScrollIsInBottom() {
210
210
  const scrollY = window.scrollY;
211
211
  return scrollY + viewportHeight >= documentHeight;
212
212
  }
213
+ /**
214
+ *
215
+ *
216
+ * Combine classes into a single string.
217
+ *
218
+ * @param {string[]} classes
219
+ * @returns {string} Combined classes
220
+ */
221
+ const combineClasses = classes => classes.filter(Boolean).join(' ');
222
+ /**
223
+ *
224
+ *
225
+ * Calculates and returns the CSS Grid positioning classes for a column based on its configuration.
226
+ * Uses a 12-column grid system where columns are positioned using grid-column-start and grid-column-end.
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * const classes = getColumnPositionClasses({
231
+ * leftOffset: 1, // Starts at the first column
232
+ * width: 6 // Spans 6 columns
233
+ * });
234
+ * // Returns: { startClass: 'col-start-1', endClass: 'col-end-7' }
235
+ * ```
236
+ *
237
+ * @param {DotPageAssetLayoutColumn} column - Column configuration object
238
+ * @param {number} column.leftOffset - Starting position (0-based) in the grid
239
+ * @param {number} column.width - Number of columns to span
240
+ * @returns {{ startClass: string, endClass: string }} Object containing CSS class names for grid positioning
241
+ */
242
+ const getColumnPositionClasses = column => {
243
+ const {
244
+ leftOffset,
245
+ width
246
+ } = column;
247
+ const startClass = `${START_CLASS}${leftOffset}`;
248
+ const endClass = `${END_CLASS}${leftOffset + width}`;
249
+ return {
250
+ startClass,
251
+ endClass
252
+ };
253
+ };
254
+ /**
255
+ *
256
+ *
257
+ * Helper function that returns an object containing the dotCMS data attributes.
258
+ * @param {DotCMSContentlet} contentlet - The contentlet to get the attributes for
259
+ * @param {string} container - The container to get the attributes for
260
+ * @returns {DotContentletAttributes} The dotCMS data attributes
261
+ */
262
+ function getDotContentletAttributes(contentlet, container) {
263
+ return {
264
+ 'data-dot-identifier': contentlet?.identifier,
265
+ 'data-dot-basetype': contentlet?.baseType,
266
+ 'data-dot-title': contentlet?.['widgetTitle'] || contentlet?.title,
267
+ 'data-dot-inode': contentlet?.inode,
268
+ 'data-dot-type': contentlet?.contentType,
269
+ 'data-dot-container': container,
270
+ 'data-dot-on-number-of-pages': contentlet?.['onNumberOfPages']
271
+ };
272
+ }
273
+ /**
274
+ *
275
+ *
276
+ * Retrieves container data from a DotCMS page asset using the container reference.
277
+ * This function processes the container information and returns a standardized format
278
+ * for container editing.
279
+ *
280
+ * @param {DotCMSPageAsset} dotCMSPageAsset - The page asset containing all containers data
281
+ * @param {DotCMSColumnContainer} columContainer - The container reference from the layout
282
+ * @throws {Error} When page asset is invalid or container is not found
283
+ * @returns {EditableContainerData} Formatted container data for editing
284
+ *
285
+ * @example
286
+ * const containerData = getContainersData(pageAsset, containerRef);
287
+ * // Returns: { uuid: '123', identifier: 'cont1', acceptTypes: 'type1,type2', maxContentlets: 5 }
288
+ */
289
+ const getContainersData = (dotCMSPageAsset, columContainer) => {
290
+ const {
291
+ identifier,
292
+ uuid
293
+ } = columContainer;
294
+ const dotContainer = dotCMSPageAsset.containers[identifier];
295
+ if (!dotContainer) {
296
+ return null;
297
+ }
298
+ const {
299
+ containerStructures,
300
+ container
301
+ } = dotContainer;
302
+ const acceptTypes = containerStructures?.map(structure => structure.contentTypeVar).join(',') ?? '';
303
+ const variantId = container?.parentPermissionable?.variantId;
304
+ const maxContentlets = container?.maxContentlets ?? 0;
305
+ const path = container?.path;
306
+ return {
307
+ uuid,
308
+ variantId,
309
+ acceptTypes,
310
+ maxContentlets,
311
+ identifier: path ?? identifier
312
+ };
313
+ };
314
+ /**
315
+ *
316
+ *
317
+ * Retrieves the contentlets (content items) associated with a specific container.
318
+ * Handles different UUID formats and provides warning for missing contentlets.
319
+ *
320
+ * @param {DotCMSPageAsset} dotCMSPageAsset - The page asset containing all containers data
321
+ * @param {DotCMSColumnContainer} columContainer - The container reference from the layout
322
+ * @returns {DotCMSContentlet[]} Array of contentlets in the container
323
+ *
324
+ * @example
325
+ * const contentlets = getContentletsInContainer(pageAsset, containerRef);
326
+ * // Returns: [{ identifier: 'cont1', ... }, { identifier: 'cont2', ... }]
327
+ */
328
+ const getContentletsInContainer = (dotCMSPageAsset, columContainer) => {
329
+ const {
330
+ identifier,
331
+ uuid
332
+ } = columContainer;
333
+ const {
334
+ contentlets
335
+ } = dotCMSPageAsset.containers[identifier];
336
+ const contentletsInContainer = contentlets[`uuid-${uuid}`] || contentlets[`uuid-dotParser_${uuid}`] || [];
337
+ if (!contentletsInContainer) {
338
+ console.warn(`We couldn't find the contentlets for the container with the identifier ${identifier} and the uuid ${uuid} becareful by adding content to this container.\nWe recommend to change the container in the layout and add the content again.`);
339
+ }
340
+ return contentletsInContainer;
341
+ };
342
+ /**
343
+ *
344
+ *
345
+ * Generates the required DotCMS data attributes for a container element.
346
+ * These attributes are used by DotCMS for container identification and functionality.
347
+ *
348
+ * @param {EditableContainerData} params - Container data including uuid, identifier, acceptTypes, and maxContentlets
349
+ * @returns {DotContainerAttributes} Object containing all necessary data attributes
350
+ *
351
+ * @example
352
+ * const attributes = getDotContainerAttributes({
353
+ * uuid: '123',
354
+ * identifier: 'cont1',
355
+ * acceptTypes: 'type1,type2',
356
+ * maxContentlets: 5
357
+ * });
358
+ * // Returns: { 'data-dot-object': 'container', 'data-dot-identifier': 'cont1', ... }
359
+ */
360
+ function getDotContainerAttributes({
361
+ uuid,
362
+ identifier,
363
+ acceptTypes,
364
+ maxContentlets
365
+ }) {
366
+ return {
367
+ 'data-dot-object': 'container',
368
+ 'data-dot-accept-types': acceptTypes,
369
+ 'data-dot-identifier': identifier,
370
+ 'data-max-contentlets': maxContentlets.toString(),
371
+ 'data-dot-uuid': uuid
372
+ };
373
+ }
213
374
 
214
375
  /**
215
376
  * Subscribes to content changes in the UVE editor
@@ -408,13 +569,84 @@ const __UVE_EVENT_ERROR_FALLBACK__ = event => {
408
569
  event
409
570
  };
410
571
  };
572
+ /**
573
+ * Development mode
574
+ *
575
+ * @internal
576
+ */
577
+ const DEVELOPMENT_MODE = 'development';
578
+ /**
579
+ * Production mode
580
+ *
581
+ * @internal
582
+ */
583
+ const PRODUCTION_MODE = 'production';
584
+ /**
585
+ * End class
586
+ *
587
+ * @internal
588
+ */
589
+ const END_CLASS = 'col-end-';
590
+ /**
591
+ * Start class
592
+ *
593
+ * @internal
594
+ */
595
+ const START_CLASS = 'col-start-';
596
+ /**
597
+ * Empty container style for React
598
+ *
599
+ * @internal
600
+ */
601
+ const EMPTY_CONTAINER_STYLE_REACT = {
602
+ width: '100%',
603
+ backgroundColor: '#ECF0FD',
604
+ display: 'flex',
605
+ justifyContent: 'center',
606
+ alignItems: 'center',
607
+ color: '#030E32',
608
+ height: '10rem'
609
+ };
610
+ /**
611
+ * Empty container style for Angular
612
+ *
613
+ * @internal
614
+ */
615
+ const EMPTY_CONTAINER_STYLE_ANGULAR = {
616
+ width: '100%',
617
+ 'background-color': '#ECF0FD',
618
+ display: 'flex',
619
+ 'justify-content': 'center',
620
+ 'align-items': 'center',
621
+ color: '#030E32',
622
+ height: '10rem'
623
+ };
624
+ /**
625
+ * Custom no component
626
+ *
627
+ * @internal
628
+ */
629
+ const CUSTOM_NO_COMPONENT = 'CustomNoComponent';
411
630
 
631
+ exports.CUSTOM_NO_COMPONENT = CUSTOM_NO_COMPONENT;
632
+ exports.DEVELOPMENT_MODE = DEVELOPMENT_MODE;
633
+ exports.EMPTY_CONTAINER_STYLE_ANGULAR = EMPTY_CONTAINER_STYLE_ANGULAR;
634
+ exports.EMPTY_CONTAINER_STYLE_REACT = EMPTY_CONTAINER_STYLE_REACT;
635
+ exports.END_CLASS = END_CLASS;
636
+ exports.PRODUCTION_MODE = PRODUCTION_MODE;
637
+ exports.START_CLASS = START_CLASS;
412
638
  exports.__UVE_EVENTS__ = __UVE_EVENTS__;
413
639
  exports.__UVE_EVENT_ERROR_FALLBACK__ = __UVE_EVENT_ERROR_FALLBACK__;
640
+ exports.combineClasses = combineClasses;
414
641
  exports.computeScrollIsInBottom = computeScrollIsInBottom;
415
642
  exports.findDotCMSElement = findDotCMSElement;
416
643
  exports.findDotCMSVTLData = findDotCMSVTLData;
417
644
  exports.getClosestDotCMSContainerData = getClosestDotCMSContainerData;
645
+ exports.getColumnPositionClasses = getColumnPositionClasses;
646
+ exports.getContainersData = getContainersData;
647
+ exports.getContentletsInContainer = getContentletsInContainer;
418
648
  exports.getDotCMSContainerData = getDotCMSContainerData;
419
649
  exports.getDotCMSContentletsBound = getDotCMSContentletsBound;
420
650
  exports.getDotCMSPageBounds = getDotCMSPageBounds;
651
+ exports.getDotContainerAttributes = getDotContainerAttributes;
652
+ exports.getDotContentletAttributes = getDotContentletAttributes;