hoàn thành phần tạo theme
This commit is contained in:
+44
@@ -0,0 +1,44 @@
|
||||
package com.sisvietnamvn.web.controller;
|
||||
|
||||
import com.sisvietnamvn.web.service.SettingService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides global model attributes for all frontend controllers.
|
||||
*/
|
||||
@ControllerAdvice(basePackages = "com.sisvietnamvn.web.controller")
|
||||
public class GlobalControllerAdvice {
|
||||
|
||||
private final SettingService settingService;
|
||||
private final PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
public GlobalControllerAdvice(SettingService settingService) {
|
||||
this.settingService = settingService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the 'activeTheme' variable available to all Thymeleaf templates handled by controllers in this package.
|
||||
*/
|
||||
@ModelAttribute("activeTheme")
|
||||
public String getActiveTheme() {
|
||||
Map<String, String> settings = settingService.getAllAsMap();
|
||||
String activeTheme = settings.getOrDefault("active_theme", "default");
|
||||
|
||||
// Validate that the layout actually exists to prevent Thymeleaf TemplateInputException crashes
|
||||
try {
|
||||
Resource[] resources = resourceResolver.getResources("classpath*:templates/themes/" + activeTheme + "/layout.html");
|
||||
if (resources == null || resources.length == 0) {
|
||||
return "default"; // Fallback to safe layout
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "default";
|
||||
}
|
||||
|
||||
return activeTheme;
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.sisvietnamvn.web.controller.manage;
|
||||
|
||||
import com.sisvietnamvn.web.service.SettingService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import com.sisvietnamvn.web.security.AuthoritiesConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Controller for the admin Themes page.
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/manage/themes")
|
||||
@PreAuthorize("hasAnyAuthority(\"" + AuthoritiesConstants.ADMIN + "\", \"" + AuthoritiesConstants.EDITOR + "\")")
|
||||
public class ManageThemeController {
|
||||
|
||||
private final SettingService settingService;
|
||||
private final PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
public ManageThemeController(SettingService settingService) {
|
||||
this.settingService = settingService;
|
||||
}
|
||||
|
||||
private List<String> getAvailableLayouts() {
|
||||
List<String> layouts = new ArrayList<>();
|
||||
try {
|
||||
Resource[] resources = resourceResolver.getResources("classpath*:templates/themes/*/layout.html");
|
||||
for (Resource res : resources) {
|
||||
String path = res.getURL().toString();
|
||||
java.util.regex.Matcher m = java.util.regex.Pattern.compile("themes/([^/]+)/layout\\.html$").matcher(path);
|
||||
if (m.find()) {
|
||||
layouts.add(m.group(1));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore if directory doesn't exist
|
||||
}
|
||||
|
||||
// Ensure we always have at least a fallback if empty
|
||||
if (layouts.isEmpty()) {
|
||||
layouts.add("default");
|
||||
}
|
||||
return layouts;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String listThemes(Model model) {
|
||||
Map<String, String> settings = settingService.getAllAsMap();
|
||||
String activeTheme = settings.getOrDefault("active_theme", "default");
|
||||
|
||||
model.addAttribute("activeTheme", activeTheme);
|
||||
model.addAttribute("availableThemes", getAvailableLayouts());
|
||||
return "manage/themes/list";
|
||||
}
|
||||
|
||||
private boolean isThemeComplete(String themeKey) {
|
||||
try {
|
||||
Resource[] layouts = resourceResolver.getResources("classpath*:templates/themes/" + themeKey + "/layout.html");
|
||||
Resource[] headers = resourceResolver.getResources("classpath*:templates/themes/" + themeKey + "/header.html");
|
||||
Resource[] footers = resourceResolver.getResources("classpath*:templates/themes/" + themeKey + "/footer.html");
|
||||
|
||||
return layouts.length > 0 && headers.length > 0 && footers.length > 0;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/activate")
|
||||
public String activateTheme(@RequestParam("themeKey") String themeKey, RedirectAttributes redirectAttributes) {
|
||||
List<String> validThemes = getAvailableLayouts();
|
||||
|
||||
if (!validThemes.contains(themeKey)) {
|
||||
redirectAttributes.addFlashAttribute("errorMessage", "Invalid theme selected.");
|
||||
return "redirect:/manage/themes";
|
||||
}
|
||||
|
||||
if (!isThemeComplete(themeKey)) {
|
||||
redirectAttributes.addFlashAttribute("errorMessage", "Cannot activate theme: Missing required files (layout.html, header.html, or footer.html).");
|
||||
return "redirect:/manage/themes";
|
||||
}
|
||||
|
||||
settingService.setValue("active_theme", themeKey);
|
||||
redirectAttributes.addFlashAttribute("successMessage", "New theme activated successfully.");
|
||||
return "redirect:/manage/themes";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user