From 849c79cc0fb66338dfdda1c547977d369e5d8876 Mon Sep 17 00:00:00 2001 From: Victor Phan Date: Mon, 13 Jul 2026 19:09:44 +0700 Subject: [PATCH] feat: implement widget and menu shortcode rendering in HtmlSnippetService and update section title --- .../block_1_block-multiple-ctas.html | 2 +- .../web/service/HtmlSnippetService.java | 111 +++++++++++++++++- .../com/sisvietnamvn/web/service/sample.html | 51 ++++++++ .../templates/manage/snippets/form.html | 20 ++++ .../src/main/resources/templates/page.html | 10 +- 5 files changed, 182 insertions(+), 12 deletions(-) create mode 100644 sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/sample.html diff --git a/sisvietnamvn_main/html_snippets/content_main_blocks/block_1_block-multiple-ctas.html b/sisvietnamvn_main/html_snippets/content_main_blocks/block_1_block-multiple-ctas.html index 3e6e4e5b..ac6998c6 100644 --- a/sisvietnamvn_main/html_snippets/content_main_blocks/block_1_block-multiple-ctas.html +++ b/sisvietnamvn_main/html_snippets/content_main_blocks/block_1_block-multiple-ctas.html @@ -3,7 +3,7 @@
-

TÌM HIỂUCHUYÊN KHOA +

TÌM HIỂUKHOA ĐIỀU TRỊ

diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/HtmlSnippetService.java b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/HtmlSnippetService.java index e026d4dc..2f1e8b23 100644 --- a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/HtmlSnippetService.java +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/HtmlSnippetService.java @@ -1,7 +1,10 @@ package com.sisvietnamvn.web.service; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.sisvietnamvn.web.domain.HtmlSnippet; import com.sisvietnamvn.web.repository.HtmlSnippetRepository; +import com.sisvietnamvn.web.service.dto.WidgetDto; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,9 +19,15 @@ import java.util.Optional; public class HtmlSnippetService { private final HtmlSnippetRepository snippetRepository; + private final SettingService settingService; + private final ObjectMapper objectMapper; + private final com.sisvietnamvn.web.service.MenuService menuService; - public HtmlSnippetService(HtmlSnippetRepository snippetRepository) { + public HtmlSnippetService(HtmlSnippetRepository snippetRepository, SettingService settingService, ObjectMapper objectMapper, com.sisvietnamvn.web.service.MenuService menuService) { this.snippetRepository = snippetRepository; + this.settingService = settingService; + this.objectMapper = objectMapper; + this.menuService = menuService; } public List findAll() { @@ -50,9 +59,107 @@ public class HtmlSnippetService { if (slug == null || slug.isEmpty()) { return ""; } - return snippetRepository.findBySlug(slug) + String content = snippetRepository.findBySlug(slug) .filter(HtmlSnippet::isActive) .map(HtmlSnippet::getContent) .orElse(""); + + if (content.isEmpty()) return content; + + if (content.contains("[widgets:sidebar]")) { + content = content.replace("[widgets:sidebar]", renderWidgets("sidebar")); + } + if (content.contains("[widgets:footer]")) { + content = content.replace("[widgets:footer]", renderWidgets("footer")); + } + if (content.contains("[widgets:stats]")) { + content = content.replace("[widgets:stats]", renderWidgets("stats")); + } + + // Process shortcodes for menus, e.g., [menu:INFO] or [menu:INFO:dropdown] + // Support HTML entities [ and ] in case the WYSIWYG editor escaped them + java.util.regex.Matcher m = java.util.regex.Pattern.compile("(?:\\[|[)menu:([a-zA-Z0-9_-]+)(?::([a-zA-Z0-9_-]+))?(?:\\]|])").matcher(content); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String location = m.group(1); + String style = m.group(2) != null ? m.group(2) : "button"; + m.appendReplacement(sb, renderMenu(location, style)); + } + m.appendTail(sb); + content = sb.toString(); + + return content; + } + + private String renderMenu(String location, String style) { + return menuService.findByLocation(location).map(menu -> { + StringBuilder sb = new StringBuilder(); + + if ("dropdown".equalsIgnoreCase(style)) { + sb.append("\n"); + } else { + // Default button style + for (com.sisvietnamvn.web.domain.MenuItem item : menu.getItems()) { + if (item.getParent() == null) { + sb.append("\n"); + } + } + } + return sb.toString(); + }).orElse(""); + } + + private String renderWidgets(String area) { + String json = settingService.getValue("theme_widgets_" + area, "[]"); + try { + List widgets = objectMapper.readValue(json, new TypeReference>() {}); + StringBuilder sb = new StringBuilder(); + for (WidgetDto w : widgets) { + sb.append("
"); + if (w.getTitle() != null && !w.getTitle().isEmpty()) { + sb.append("
").append(w.getTitle()).append("
"); + } + sb.append("
").append(w.getContent()).append("
"); + sb.append("
"); + } + return sb.toString(); + } catch (Exception e) { + return ""; + } } } diff --git a/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/sample.html b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/sample.html new file mode 100644 index 00000000..c1f4844c --- /dev/null +++ b/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/service/sample.html @@ -0,0 +1,51 @@ +
+
+
+
+
+
+
+
+ Students collaborate using a driving simulator in the UMass Center for Transportation. +
+ +
+
+
+ + +
+
+
+
+
+

+ Stroke International School 2026. +

+ + [menu:INFO:dropdown] +
+
+
+
+
+
+
+
+
chỉnh \ No newline at end of file diff --git a/sisvietnamvn_main/src/main/resources/templates/manage/snippets/form.html b/sisvietnamvn_main/src/main/resources/templates/manage/snippets/form.html index 4156bd90..03649e20 100644 --- a/sisvietnamvn_main/src/main/resources/templates/manage/snippets/form.html +++ b/sisvietnamvn_main/src/main/resources/templates/manage/snippets/form.html @@ -641,6 +641,26 @@ media: '' }); + // ── DYNAMIC WIDGETS ── + bm.add('widget-sidebar', { + label: 'Sidebar Widgets', + category: 'Widgets', + content: '
[widgets:sidebar]
', + media: '' + }); + bm.add('widget-footer', { + label: 'Footer Widgets', + category: 'Widgets', + content: '
[widgets:footer]
', + media: '' + }); + bm.add('widget-stats', { + label: 'Stats Widgets', + category: 'Widgets', + content: '
[widgets:stats]
', + media: '' + }); + // ── MEDIA ── bm.add('image-gallery', { label: 'Image Gallery', diff --git a/sisvietnamvn_main/src/main/resources/templates/page.html b/sisvietnamvn_main/src/main/resources/templates/page.html index 2f27a970..0fda32e1 100644 --- a/sisvietnamvn_main/src/main/resources/templates/page.html +++ b/sisvietnamvn_main/src/main/resources/templates/page.html @@ -26,15 +26,7 @@ - -
-
- -
-
- -
-
+