钩子与挂载点
该模板基于 CnLog 博客系统,使用 doAction() 函数作为钩子挂载机制,插件可通过 addAction() 注册回调来注入内容。
一、全局区域(header.php / footer.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| index_head |
<?php
addAction('index_head', function() {
echo '<style>.custom{color:red}</style>';
});
?> |
</head> 前 |
在 HTML <head> 区域输出内容,常用于注入自定义 CSS、meta 标签等 |
| head_end |
<?php
addAction('head_end', function() {
echo '<meta name="keyword" content="...">';
});
?> |
</head> 前 |
向后兼容钩子,功能同 index_head,保留旧插件兼容性 |
| header_before |
<?php
addAction('header_before', function() {
echo '<div class="notice">公告内容</div>';
});
?> |
<body> 后、<header> 前 |
页面 body 开始后、头部导航前的扩展点 |
| navbar |
<?php
addAction('navbar', function() {
echo '<a href="/custom">自定义链接</a>';
});
?> |
导航栏内(桌面端) |
在导航栏中插入自定义链接,参数为 <a href=" 和 "> 包裹格式 |
| navbar |
<?php
addAction('navbar', function() {
echo '<a href="/custom">自定义链接</a>';
});
?> |
导航栏内(移动端) |
移动端导航菜单中的扩展点,参数同上 |
| navbar_after_username |
<?php
addAction('navbar_after_username', function() {
echo '<a href="/sign">签到</a>';
});
?> |
用户名后(桌面端) |
登录用户名后的扩展钩子,常用于签到按钮等 |
| navbar_after_username |
<?php
addAction('navbar_after_username', function() {
echo '<a href="/sign">签到</a>';
});
?> |
用户名后(移动端) |
移动端登录用户名后的扩展钩子 |
| header_after |
<?php
addAction('header_after', function() {
echo '<div class="banner">广告位</div>';
});
?> |
</header> 后 |
头部导航结束后的扩展点 |
| footer_before |
<?php
addAction('footer_before', function() {
echo '<div class="links">友情链接</div>';
});
?> |
<footer> 前 |
页脚内容之前的扩展点 |
| index_footer |
<?php
addAction('index_footer', function() {
echo '<p>© 2025 版权所有</p>';
});
?> |
<footer> 内 |
页脚内部内容扩展,用于注入页脚信息 |
| footer_after |
<?php
addAction('footer_after', function() {
echo '<script src="/custom.js"></script>';
});
?> |
</footer> 后、JS 前 |
页脚之后、脚本加载前的扩展点 |
二、文章详情页(echo_log.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| article_content_before |
<?php
addAction('article_content_before', function($args) {
$article = $args['article'];
echo '<div class="article-top">置顶提示</div>';
});
?> |
文章内容前 |
文章正文输出前的扩展点,传入 ['article' => $log] |
| article_content_after |
<?php
addAction('article_content_after', function($args) {
$article = $args['article'];
echo '<div class="reward">打赏按钮</div>';
});
?> |
文章内容后 |
文章正文输出后的扩展点,传入 ['article' => $log] |
| article_content_footer |
<?php
addAction('article_content_footer', function($args) {
$article = $args['article'];
echo '<div class="copyright">版权声明</div>';
});
?> |
文章末尾(标签/点赞/分享后) |
文章底部完整信息后的扩展点,传入 ['article' => $log] |
| log_related |
<?php
addAction('log_related', function($log) {
echo '<div class="related">相关文章推荐</div>';
});
?> |
文章末尾 |
相关文章/扩展内容钩子,传入 $log,常用于相关文章推荐 |
| article_comments_before |
<?php
addAction('article_comments_before', function($args) {
echo '<div class="comment-tip">评论区公告</div>';
});
?> |
评论区前 |
评论区开始前的扩展点,传入 ['article' => $log] |
| article_comments_after |
<?php
addAction('article_comments_after', function($args) {
echo '<div class="comment-ad">评论区底部广告</div>';
});
?> |
评论区后 |
评论区结束后的扩展点,传入 ['article' => $log] |
三、文章列表页(log_list.php / log_list_products.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| index_loglist_top |
<?php
addAction('index_loglist_top', function($args) {
echo '<div class="list-top">列表顶部横幅</div>';
});
?> |
文章列表顶部 |
首页文章列表开始前的扩展点,传入 ['logs', 'page'] |
| index_loglist_bottom |
<?php
addAction('index_loglist_bottom', function($args) {
echo '<div class="list-bottom">列表底部内容</div>';
});
?> |
文章列表底部 |
首页文章列表结束后的扩展点,传入 ['logs', 'page'] |
| index_loglist_top |
<?php
addAction('index_loglist_top', function($args) {
echo '<div class="list-top">产品列表顶部</div>';
});
?> |
产品列表顶部 |
产品布局列表开始前的扩展点(同钩子名,不同模板) |
| index_loglist_bottom |
<?php
addAction('index_loglist_bottom', function($args) {
echo '<div class="list-bottom">产品列表底部</div>';
});
?> |
产品列表底部 |
产品布局列表结束后的扩展点 |
四、搜索页(search.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| search_loglist_top |
<?php
addAction('search_loglist_top', function($args) {
$keyword = $args['keyword'];
echo '<div class="search-tip">搜索: '.$keyword.'</div>';
});
?> |
搜索结果顶部 |
搜索结果列表开始前的扩展点,传入 ['logs', 'keyword', 'page'] |
| search_loglist_bottom |
<?php
addAction('search_loglist_bottom', function($args) {
echo '<div class="search-bottom">搜索页底部内容</div>';
});
?> |
搜索结果底部 |
搜索结果列表结束后的扩展点 |
五、留言板(guestbook.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| guestbook_top |
<?php
addAction('guestbook_top', function() {
echo '<div class="gb-top">留言板顶部提示</div>';
});
?> |
留言板顶部 |
留言板页面最开始的扩展点 |
| guestbook_form_before |
<?php
addAction('guestbook_form_before', function() {
echo '<p class="gb-tip">请文明留言</p>';
});
?> |
留言表单前 |
留言输入表单之前的扩展点 |
| guestbook_form_after |
<?php
addAction('guestbook_form_after', function() {
echo '<div class="gb-info">留言须知</div>';
});
?> |
留言表单后 |
留言输入表单之后的扩展点 |
| guestbook_comments_before |
<?php
addAction('guestbook_comments_before', function() {
echo '<div class="gb-list-top">留言列表顶部</div>';
});
?> |
留言列表前 |
留言列表渲染之前的扩展点 |
| guestbook_comments_after |
<?php
addAction('guestbook_comments_after', function() {
echo '<div class="gb-list-bottom">留言列表底部</div>';
});
?> |
留言列表后 |
留言列表渲染之后的扩展点 |
| guestbook_bottom |
<?php
addAction('guestbook_bottom', function() {
echo '<div class="gb-footer">留言板底部</div>';
});
?> |
留言板底部 |
留言板页面最后的扩展点 |
六、个人中心(profile.php / profile.clean.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| profile_template_override |
<?php
addAction('profile_template_override', function() {
$GLOBALS['profile_template_handled'] = true;
echo '完全接管个人中心页面';
});
?> |
模板最开头 |
插件接管钩子:插件可输出内容并设置 $GLOBALS['profile_template_handled']=true 完全接管页面渲染 |
| profile_before |
<?php
addAction('profile_before', function() {
echo '<div class="profile-banner">个人中心顶部横幅</div>';
});
?> |
页面内容前 |
个人中心主内容区域之前的扩展点 |
| profile_top |
<?php
addAction('profile_top', function() {
echo '<div class="profile-notice">系统通知</div>';
});
?> |
内容区顶部 |
个人中心内容区最顶部的扩展点 |
| profile_header |
<?php
addAction('profile_header', function() {
echo '<span class="user-badge">VIP</span>';
});
?> |
用户信息卡内 |
用户头像/昵称信息区域内的扩展点 |
| profile_tabs |
<?php
addAction('profile_tabs', function() {
echo '<li><a href="#custom">自定义Tab</a></li>';
});
?> |
Tab 导航区 |
个人中心标签页导航的扩展点,插件可添加自定义 Tab |
| profile_tabs_extra |
<?php
addAction('profile_tabs_extra', function() {
echo '<button class="tab-btn">额外按钮</button>';
});
?> |
Tab 按钮后 |
【内核标准】允许插件添加额外的 Tab 按钮 |
| profile_content |
<?php
addAction('profile_content', function() {
$GLOBALS['profile_content_rendered'] = true;
echo '<div class="custom-tab">自定义Tab内容</div>';
});
?> |
Tab 内容区 |
个人中心 Tab 内容区域的扩展点,插件可设置 $GLOBALS['profile_content_rendered']=true 接管内容渲染 |
| profile_sidebar_top |
<?php
addAction('profile_sidebar_top', function() {
echo '<div class="widget">侧边栏顶部组件</div>';
});
?> |
侧边栏顶部 |
【内核标准】允许插件在侧边栏顶部插入内容 |
| profile_sidebar_bottom |
<?php
addAction('profile_sidebar_bottom', function() {
echo '<div class="widget">侧边栏底部组件</div>';
});
?> |
侧边栏底部 |
【内核标准】允许插件在侧边栏底部插入内容 |
| profile_bottom |
<?php
addAction('profile_bottom', function() {
echo '<div class="profile-footer">个人中心底部</div>';
});
?> |
内容区底部 |
个人中心内容区底部的扩展点 |
| profile_enqueue_assets |
<?php
addAction('profile_enqueue_assets', function() {
echo '<link rel="stylesheet" href="/custom.css">';
echo '<script src="/custom.js"></script>';
});
?> |
页面最末尾 |
插件注册/输出样式与脚本的扩展点 |
七、侧边栏(sidebar.php)
| 钩子名称 |
钩子示例 |
位置 |
介绍 |
| sidebar_before |
<?php
addAction('sidebar_before', function() {
echo '<div class="widget">顶部自定义组件</div>';
});
?> |
侧边栏顶部 |
所有侧边栏组件渲染之前的扩展点 |
| widget_{name}_before |
<?php
addAction('widget_search_before', function() {
echo '<div class="widget-tip">搜索提示</div>';
});
?> |
每个组件前 |
动态钩子,每个侧边栏组件渲染前触发,如 widget_search_before、widget_blogger_before 等 |
| widget_{name}_after |
<?php
addAction('widget_search_after', function() {
echo '<div class="widget-bottom">热门搜索</div>';
});
?> |
每个组件后 |
动态钩子,每个侧边栏组件渲染后触发,如 widget_search_after、widget_blogger_after 等 |
| sidebar_after |
<?php
addAction('sidebar_after', function() {
echo '<div class="widget">底部自定义组件</div>';
});
?> |
侧边栏底部 |
所有侧边栏组件渲染之后的扩展点 |
统计概览
| 分类 |
钩子数量 |
| 全局区域(header/footer) |
9 |
| 文章详情页 |
6 |
| 文章列表页 |
4 |
| 搜索页 |
2 |
| 留言板 |
6 |
| 个人中心 |
11 |
| 侧边栏 |
4(含动态钩子) |
| 合计 |
42 |
说明:widget_{name}_before/after 为动态钩子,根据后台启用的侧边栏组件动态生成,如 widget_blogger_before、widget_search_after、widget_recent_posts_before 等。profile.clean.php 是个人中心的精简可接管版本,profile.php 是完整功能版本,两者共享部分钩子名称。