develop core Hooks, remain hooks is defined but not develop

This commit is contained in:
2026-07-02 19:11:03 +07:00
parent a7dbf52eea
commit 0dd68c3649
9 changed files with 15488 additions and 7 deletions
+60
View File
@@ -0,0 +1,60 @@
import csv
import re
csv_path = '/home/x79/sisvietnamvn_01/Design/List of all WP action hooks and filters -- Adam Brown, BYU Political Science.csv'
java_path = '/home/x79/sisvietnamvn_01/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/WpHooks.java'
def sanitize_constant_name(hook_name):
# Convert {$plugin} to PLUGIN
name = re.sub(r'\{\$([a-zA-Z0-9_]+)\}', r'\1', hook_name)
name = re.sub(r'[^a-zA-Z0-9_]', '_', name).upper()
# Handle multiple underscores or leading numbers
name = re.sub(r'_+', '_', name)
name = name.strip('_')
if name and name[0].isdigit():
name = "HOOK_" + name
return name
with open(csv_path, 'r', encoding='utf-8-sig') as f:
reader = csv.reader(f)
next(reader) # Skip header
hooks = set()
for row in reader:
if len(row) > 1 and row[1].strip():
hooks.add(row[1].strip())
with open(java_path, 'w', encoding='utf-8') as f:
f.write("package com.sisvietnamvn.web.hook;\n\n")
f.write("/**\n")
f.write(" * Automatically generated dictionary of all WordPress Hooks.\n")
f.write(" * Contains " + str(len(hooks)) + " constants.\n")
f.write(" */\n")
f.write("public final class WpHooks {\n\n")
f.write(" private WpHooks() {}\n\n")
# Track written constants to avoid duplicates
written = set()
for hook in sorted(list(hooks)):
const_name = sanitize_constant_name(hook)
if not const_name:
continue
if const_name in written:
const_name = const_name + "_2" # Simple deduplication
written.add(const_name)
# Add comment with original hook name
f.write(f' /**\n')
f.write(f' * Original hook name: {hook}\n')
f.write(f' */\n')
f.write(f' public static final String {const_name} = "{hook}";\n\n')
f.write("}\n")
print(f"Generated {len(written)} hook constants in WpHooks.java")
@@ -7,6 +7,7 @@ import com.sisvietnamvn.web.domain.Page;
import com.sisvietnamvn.web.security.AuthoritiesConstants; import com.sisvietnamvn.web.security.AuthoritiesConstants;
import com.sisvietnamvn.web.security.SecurityUtils; import com.sisvietnamvn.web.security.SecurityUtils;
import com.sisvietnamvn.web.service.PageService; import com.sisvietnamvn.web.service.PageService;
import com.sisvietnamvn.web.hook.HookManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@@ -31,19 +32,25 @@ public class PageController {
private final PageService pageService; private final PageService pageService;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final HookManager hookManager;
public PageController(PageService pageService, ObjectMapper objectMapper) { public PageController(PageService pageService, ObjectMapper objectMapper, HookManager hookManager) {
this.pageService = pageService; this.pageService = pageService;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
this.hookManager = hookManager;
} }
/**
* GET /page/{slug} : Render a page dynamically by slug.
*/
@GetMapping("/page/{slug}") @GetMapping("/page/{slug}")
public String getPage(@PathVariable("slug") String slug, Model model) { public String getPage(@PathVariable("slug") String slug, Model model) {
LOG.debug("REST request to get public Page : {}", slug); LOG.debug("REST request to get public Page : {}", slug);
return renderPage(pageService.findBySlug(slug), model); Page page = pageService.findBySlug(slug)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
// Apply WordPress-style Content Filters
page.setTitle(hookManager.applyFilters("the_title", page.getTitle()));
page.setContent(hookManager.applyFilters("the_content", page.getContent()));
return renderPage(Optional.of(page), model);
} }
@GetMapping("/") @GetMapping("/")
@@ -3,6 +3,7 @@ package com.sisvietnamvn.web.controller;
import com.sisvietnamvn.web.domain.PageStatus; import com.sisvietnamvn.web.domain.PageStatus;
import com.sisvietnamvn.web.domain.Post; import com.sisvietnamvn.web.domain.Post;
import com.sisvietnamvn.web.repository.PostRepository; import com.sisvietnamvn.web.repository.PostRepository;
import com.sisvietnamvn.web.hook.HookManager;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@@ -16,9 +17,11 @@ import org.springframework.web.server.ResponseStatusException;
public class PostController { public class PostController {
private final PostRepository postRepository; private final PostRepository postRepository;
private final HookManager hookManager;
public PostController(PostRepository postRepository) { public PostController(PostRepository postRepository, HookManager hookManager) {
this.postRepository = postRepository; this.postRepository = postRepository;
this.hookManager = hookManager;
} }
@GetMapping("/{slug}") @GetMapping("/{slug}")
@@ -31,6 +34,13 @@ public class PostController {
throw new ResponseStatusException(HttpStatus.NOT_FOUND); throw new ResponseStatusException(HttpStatus.NOT_FOUND);
} }
// Apply WordPress-style Content Filters
post.setTitle(hookManager.applyFilters("the_title", post.getTitle()));
post.setContent(hookManager.applyFilters("the_content", post.getContent()));
if (post.getExcerpt() != null) {
post.setExcerpt(hookManager.applyFilters("the_excerpt", post.getExcerpt()));
}
model.addAttribute("post", post); model.addAttribute("post", post);
// Safely format the Instant to avoid Thymeleaf parsing errors // Safely format the Instant to avoid Thymeleaf parsing errors
@@ -47,6 +47,16 @@ public class HookManager {
} }
} }
/**
* Executes an action and returns an empty string.
* This is useful for invoking actions directly within Thymeleaf templates
* (e.g., <th:block th:text="${@hookManager.doActionAndReturn('wp_head')}"></th:block>).
*/
public String doActionAndReturn(String hookName, Object... args) {
doAction(hookName, args);
return "";
}
// --- Filters --- // --- Filters ---
public <T> void addFilter(String hookName, FilterCallback<T> callback, int priority) { public <T> void addFilter(String hookName, FilterCallback<T> callback, int priority) {
File diff suppressed because it is too large Load Diff
@@ -41,16 +41,20 @@ public class UserService {
private final CacheManager cacheManager; private final CacheManager cacheManager;
private final com.sisvietnamvn.web.hook.HookManager hookManager;
public UserService( public UserService(
UserRepository userRepository, UserRepository userRepository,
PasswordEncoder passwordEncoder, PasswordEncoder passwordEncoder,
AuthorityRepository authorityRepository, AuthorityRepository authorityRepository,
CacheManager cacheManager CacheManager cacheManager,
com.sisvietnamvn.web.hook.HookManager hookManager
) { ) {
this.userRepository = userRepository; this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder; this.passwordEncoder = passwordEncoder;
this.authorityRepository = authorityRepository; this.authorityRepository = authorityRepository;
this.cacheManager = cacheManager; this.cacheManager = cacheManager;
this.hookManager = hookManager;
} }
public Optional<User> activateRegistration(String key) { public Optional<User> activateRegistration(String key) {
@@ -126,6 +130,10 @@ public class UserService {
userRepository.save(newUser); userRepository.save(newUser);
this.clearUserCaches(newUser); this.clearUserCaches(newUser);
LOG.debug("Created Information for User: {}", newUser); LOG.debug("Created Information for User: {}", newUser);
// Trigger WordPress-style hook
hookManager.doAction("user_register", newUser.getId());
return newUser; return newUser;
} }
@@ -207,6 +215,10 @@ public class UserService {
userRepository.save(user); userRepository.save(user);
this.clearUserCaches(user); this.clearUserCaches(user);
LOG.debug("Changed Information for User: {}", user); LOG.debug("Changed Information for User: {}", user);
// Trigger WordPress-style hook
hookManager.doAction("profile_update", user.getId());
return user; return user;
}) })
.map(AdminUserDTO::new); .map(AdminUserDTO::new);
@@ -19,6 +19,8 @@
<!-- Project-wide CSS Variables & Custom Styles --> <!-- Project-wide CSS Variables & Custom Styles -->
<link rel="stylesheet" th:href="@{/css/custom.css}"> <link rel="stylesheet" th:href="@{/css/custom.css}">
<!-- Admin Head Hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('admin_head')}"></th:block>
</head> </head>
<body id="page-top"> <body id="page-top">
@@ -358,6 +360,9 @@
<!-- Page-specific scripts injected by child templates --> <!-- Page-specific scripts injected by child templates -->
<section layout:fragment="scripts"></section> <section layout:fragment="scripts"></section>
<!-- Admin Footer Hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('admin_footer')}"></th:block>
</body> </body>
</html> </html>
@@ -3,6 +3,11 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Default Theme</title> <title>Default Theme</title>
<!-- Theme Customizer CSS Output -->
<style th:utext="${themeCss}"></style>
<!-- wp_head hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('wp_head')}"></th:block>
</head> </head>
<body> <body>
<!-- Replace with Header Fragment --> <!-- Replace with Header Fragment -->
@@ -25,5 +30,8 @@
<!-- Replace with Footer Fragment --> <!-- Replace with Footer Fragment -->
<footer th:replace="~{themes/__${activeTheme}__/footer :: footer}"></footer> <footer th:replace="~{themes/__${activeTheme}__/footer :: footer}"></footer>
<!-- wp_footer hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('wp_footer')}"></th:block>
</body> </body>
</html> </html>
@@ -3,6 +3,11 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Modern Theme</title> <title>Modern Theme</title>
<!-- Theme Customizer CSS Output -->
<style th:utext="${themeCss}"></style>
<!-- wp_head hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('wp_head')}"></th:block>
</head> </head>
<body style="background-color: #f8f9fa; font-family: sans-serif;"> <body style="background-color: #f8f9fa; font-family: sans-serif;">
<!-- Replace with Header Fragment --> <!-- Replace with Header Fragment -->
@@ -26,5 +31,8 @@
<!-- Replace with Footer Fragment --> <!-- Replace with Footer Fragment -->
<footer th:replace="~{themes/__${activeTheme}__/footer :: footer}"></footer> <footer th:replace="~{themes/__${activeTheme}__/footer :: footer}"></footer>
<!-- wp_footer hook -->
<th:block th:utext="${@hookManager.doActionAndReturn('wp_footer')}"></th:block>
</body> </body>
</html> </html>