Skip to content

Commit 1afe08a

Browse files
committed
Improve editing content blocks with any fallback html
1 parent d3d2c32 commit 1afe08a

5 files changed

Lines changed: 211 additions & 50 deletions

File tree

src/main/java/com/simisinc/platform/presentation/widgets/cms/PageContentBlocksJsonService.java

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.simisinc.platform.presentation.widgets.cms;
1818

1919
import java.util.ArrayList;
20+
import java.util.LinkedHashMap;
2021
import java.util.LinkedHashSet;
2122
import java.util.List;
2223
import java.util.Map;
@@ -83,41 +84,59 @@ public WidgetContext execute(WidgetContext context) {
8384
return writeError(context, "Page not found");
8485
}
8586

86-
// Collect unique content IDs from the page layout
87-
Set<String> uniqueIds = new LinkedHashSet<>();
88-
extractContentUniqueIds(webPage, link, uniqueIds);
87+
// Collect unique content IDs from the page layout with fallback HTML
88+
Map<String, String> uniqueIdToFallbackHtml = new LinkedHashMap<>();
89+
extractContentUniqueIds(webPage, link, uniqueIdToFallbackHtml);
8990

9091
// Load content records and build response
9192
List<Content> contentBlocks = new ArrayList<>();
92-
for (String uniqueId : uniqueIds) {
93+
for (String uniqueId : uniqueIdToFallbackHtml.keySet()) {
9394
Content content = LoadContentCommand.loadContentByUniqueId(uniqueId);
9495
if (content != null) {
9596
contentBlocks.add(content);
9697
// Also check for embedded ${uniqueId:...} directives (1 level deep)
97-
extractEmbeddedDirectives(content.getContent(), uniqueIds);
98+
extractEmbeddedDirectives(content.getContent(), uniqueIdToFallbackHtml);
9899
}
99100
}
100101

101-
// Re-load any newly discovered content from embedded directives
102+
// Re-load any newly discovered content from embedded directives and track which uniqueIds have records
102103
List<Content> allContentBlocks = new ArrayList<>();
103-
for (String uniqueId : uniqueIds) {
104+
Set<String> existingUniqueIds = new LinkedHashSet<>();
105+
for (String uniqueId : uniqueIdToFallbackHtml.keySet()) {
104106
Content content = LoadContentCommand.loadContentByUniqueId(uniqueId);
105107
if (content != null) {
106108
allContentBlocks.add(content);
109+
existingUniqueIds.add(uniqueId);
107110
}
108111
}
109112

110-
// Build JSON response
113+
// Build JSON response including both existing content and "new" referenced blocks
111114
StringBuilder dataJson = new StringBuilder();
112115
dataJson.append("[");
113116
boolean first = true;
117+
118+
// Add existing content blocks
114119
for (Content content : allContentBlocks) {
115120
if (!first) {
116121
dataJson.append(",");
117122
}
118123
first = false;
119124
appendContentJson(dataJson, content);
120125
}
126+
127+
// Add referenced blocks that don't have records yet (marked as "new")
128+
for (Map.Entry<String, String> entry : uniqueIdToFallbackHtml.entrySet()) {
129+
String uniqueId = entry.getKey();
130+
if (!existingUniqueIds.contains(uniqueId)) {
131+
if (!first) {
132+
dataJson.append(",");
133+
}
134+
first = false;
135+
String fallbackHtml = entry.getValue();
136+
appendNewContentJson(dataJson, uniqueId, fallbackHtml);
137+
}
138+
}
139+
121140
dataJson.append("]");
122141

123142
return writeOk(context, dataJson.toString(), null);
@@ -131,7 +150,7 @@ public WidgetContext execute(WidgetContext context) {
131150
/**
132151
* Extract content uniqueIds from the page's XML layout by traversing the widget hierarchy
133152
*/
134-
private void extractContentUniqueIds(WebPage webPage, String link, Set<String> uniqueIds) {
153+
private void extractContentUniqueIds(WebPage webPage, String link, Map<String, String> uniqueIdToFallbackHtml) {
135154
try {
136155
// Use the page layout command to get the parsed Page object
137156
Page page = WebPageXmlLayoutCommand.retrievePageForRequest(webPage, link);
@@ -152,13 +171,14 @@ private void extractContentUniqueIds(WebPage webPage, String link, Set<String> u
152171
if (StringUtils.isBlank(uniqueId)) {
153172
uniqueId = prefs.get("contentUniqueId");
154173
}
174+
// Get fallback HTML from the html preference
175+
String fallbackHtml = prefs.get("html");
155176
if (StringUtils.isNotBlank(uniqueId)) {
156-
uniqueIds.add(uniqueId);
177+
uniqueIdToFallbackHtml.put(uniqueId, StringUtils.defaultString(fallbackHtml));
157178
}
158179
// Check for embedded directives in html preference
159-
String html = prefs.get("html");
160-
if (StringUtils.isNotBlank(html)) {
161-
extractEmbeddedDirectives(html, uniqueIds);
180+
if (StringUtils.isNotBlank(fallbackHtml)) {
181+
extractEmbeddedDirectives(fallbackHtml, uniqueIdToFallbackHtml);
162182
}
163183
}
164184
}
@@ -172,15 +192,16 @@ private void extractContentUniqueIds(WebPage webPage, String link, Set<String> u
172192
/**
173193
* Extract uniqueId references from ${uniqueId:...} directives in content HTML
174194
*/
175-
private void extractEmbeddedDirectives(String html, Set<String> uniqueIds) {
195+
private void extractEmbeddedDirectives(String html, Map<String, String> uniqueIdToFallbackHtml) {
176196
if (StringUtils.isBlank(html)) {
177197
return;
178198
}
179199
Matcher matcher = DIRECTIVE_PATTERN.matcher(html);
180200
while (matcher.find()) {
181201
String embeddedId = matcher.group(1).trim();
182202
if (StringUtils.isNotBlank(embeddedId)) {
183-
uniqueIds.add(embeddedId);
203+
// Use putIfAbsent so embedded directives don't overwrite existing fallback HTML
204+
uniqueIdToFallbackHtml.putIfAbsent(embeddedId, "");
184205
}
185206
}
186207
}
@@ -192,6 +213,7 @@ private void appendContentJson(StringBuilder json, Content content) {
192213
json.append("{");
193214
json.append("\"id\":").append(content.getId()).append(",");
194215
json.append("\"uniqueId\":\"").append(JsonCommand.toJson(content.getUniqueId())).append("\",");
216+
json.append("\"isNew\":false,");
195217

196218
String snippet = StringUtils.truncate(content.getContentAsText(), 120);
197219
json.append("\"snippet\":\"").append(JsonCommand.toJson(snippet)).append("\",");
@@ -222,6 +244,28 @@ private void appendContentJson(StringBuilder json, Content content) {
222244
json.append("}");
223245
}
224246

247+
/**
248+
* Append a "new" content block (referenced but no record exists yet) as JSON
249+
*/
250+
private void appendNewContentJson(StringBuilder json, String uniqueId, String fallbackHtml) {
251+
json.append("{");
252+
json.append("\"id\":-1,");
253+
json.append("\"uniqueId\":\"").append(JsonCommand.toJson(uniqueId)).append("\",");
254+
json.append("\"isNew\":true,");
255+
256+
// Use fallback HTML for snippet if available
257+
String snippet = StringUtils.isNotBlank(fallbackHtml) ? StringUtils.truncate(fallbackHtml, 120) : "No content yet";
258+
json.append("\"snippet\":\"").append(JsonCommand.toJson(snippet)).append("\",");
259+
260+
// Include the full fallback HTML
261+
json.append("\"fallbackHtml\":\"").append(JsonCommand.toJson(StringUtils.defaultString(fallbackHtml))).append("\",");
262+
263+
json.append("\"hasDraft\":false,");
264+
json.append("\"modified\":\"\",");
265+
json.append("\"modifiedBy\":\"\"");
266+
json.append("}");
267+
}
268+
225269
private WidgetContext writeOk(WidgetContext context, String dataJson, String metaJson) {
226270
StringBuilder json = new StringBuilder();
227271
json.append("{");

src/main/webapp/css/visual-content-editor.css

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,16 @@ textarea.property-input {
24312431
text-transform: uppercase;
24322432
}
24332433

2434+
.content-block-new-badge {
2435+
font-size: 10px;
2436+
padding: 1px 6px;
2437+
border-radius: 3px;
2438+
background: #28a745;
2439+
color: white;
2440+
font-weight: 600;
2441+
text-transform: uppercase;
2442+
}
2443+
24342444
.content-block-snippet {
24352445
font-size: 12px;
24362446
color: var(--editor-text-muted);
@@ -2449,11 +2459,11 @@ textarea.property-input {
24492459

24502460
/* Content Block Editor Modal */
24512461
#content-block-editor-modal {
2452-
z-index: 100000;
2462+
z-index: 11;
24532463
}
24542464

24552465
.content-block-editor-modal-content {
2456-
max-width: 900px;
2466+
max-width: 64em;
24572467
width: 90vw;
24582468
height: 80vh;
24592469
display: flex;

0 commit comments

Comments
 (0)