Files
argon-theme/doc/argon-theme-training.md
nanhaoluo 5c362b1075 docs: 细化 Argon 主题培训文档
- 补充全局配置对象的详细说明和实际代码示例
- 细化 CSS 变量系统,包含主题色、动画、卡片样式等完整变量
- 扩展夜间模式章节,详细说明四种切换方案和 AMOLED 模式
- 重写 PJAX 章节,补充完整的事件流程和重新初始化逻辑
- 细化瀑布流布局,包含完整算法、响应式适配和性能优化
- 新增主题初始化流程章节,详细说明服务器端和客户端初始化过程
- 补充资源加载策略和强制刷新机制的实现细节
- 所有代码示例均来自实际项目文件,确保准确性
2026-01-31 18:49:02 +08:00

3164 lines
75 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Argon 主题开发文档
## 项目概述
Argon 是一款基于 WordPress 的现代化博客主题,采用 Material Design 设计语言,提供丰富的功能和高度的可定制性。主题版本 1.5.0,由 solstice23 开发维护。
### 核心特性
- Material Design 风格界面
- 响应式布局,支持多种页面布局模式(单栏/双栏/三栏)
- 夜间模式与 AMOLED 暗黑模式
- 沉浸式主题色系统
- PJAX 无刷新页面加载
- 瀑布流文章列表布局
- 完整的评论系统(支持 Markdown、表情、点赞、置顶
- 说说功能(类似微博的短内容发布)
- AI 摘要生成
- 代码高亮与数学公式渲染
- 友链管理系统
- 反馈系统
- 性能优化模块
### 技术栈
- PHP 7.0+
- WordPress 4.4+
- jQuery 3.x
- Bootstrap 4 (Argon Design System)
- Prism.js (代码高亮)
- MathJax/KaTeX (数学公式)
- Headroom.js (顶栏自动隐藏)
## 项目文件结构
### 核心文件
```
argon/
├── style.css # 主题样式表 (~12000 行)
├── argontheme.js # 主题核心 JavaScript (~3700 行)
├── functions.php # WordPress 主题函数 (~5700 行)
├── settings.php # 后台设置页面 (~6000 行)
├── header.php # 页面头部模板
├── footer.php # 页面底部模板
├── index.php # 首页模板
├── single.php # 文章页模板
├── page.php # 页面模板
├── archive.php # 归档页模板
├── search.php # 搜索结果页模板
├── 404.php # 404 页面模板
├── comments.php # 评论区模板
├── sidebar.php # 侧边栏模板
└── info.json # 主题信息配置
```
### 功能模块文件
```
argon/
├── shuoshuo.php # 说说页面模板
├── timeline.php # 时间线页面模板
├── msgboard.php # 留言板页面模板
├── friend-links.php # 友链页面模板
├── feedback.php # 反馈系统
├── emotions.php # 表情系统
├── parsedown.php # Markdown 解析器
├── useragent-parser.php # User Agent 解析
├── ai-summary-query.php # AI 摘要查询接口
├── unsubscribe-comment-mailnotice.php # 评论邮件退订
└── argon-performance.js # 性能优化模块
```
### 模板片段
```
template-parts/
├── content-single.php # 单篇文章内容
├── content-page.php # 页面内容
├── content-preview-1.php # 文章预览样式 1
├── content-preview-2.php # 文章预览样式 2
├── content-preview-3.php # 文章预览样式 3
├── content-shuoshuo.php # 说说内容
├── content-shuoshuo-preview.php # 说说预览
├── content-shuoshuo-details.php # 说说详情
├── content-timeline.php # 时间线内容
├── content-none-search.php # 搜索无结果
├── content-none-tag.php # 标签无结果
├── ai-summary.php # AI 摘要组件
├── emotion-keyboard.php # 表情键盘
├── post-actions.php # 文章操作按钮
└── shuoshuo-operations.php # 说说操作按钮
```
### 资源文件
```
assets/
├── css/
│ ├── argon.css # Argon Design System 样式
│ └── bootstrap/ # Bootstrap 样式
├── js/
│ ├── argon.js # Argon Design System 脚本
│ └── easter-egg.js # 彩蛋功能
├── img/ # 图片资源
├── icons/ # 图标资源
├── vendor/ # 第三方库
├── tinymce_assets/ # TinyMCE 编辑器资源
├── argon_css_merged.css # 合并后的 CSS
└── argon_js_merged.js # 合并后的 JS
```
### 邮件模板
```
email-templates/
├── base.php # 邮件模板基类
├── comment-notify.php # 评论通知
├── reply-notify.php # 回复通知
├── feedback-notify.php # 反馈通知
├── spam-notify.php # 垃圾评论通知
├── blacklist-spam-notify.php # 黑名单垃圾评论通知
└── username-change-notify.php # 用户名变更通知
```
## 代码规范
### CSS 规范
#### 格式化规则
- 使用 Tab 缩进1 Tab = 4 空格宽度)
- 每个属性独占一行
- 属性之间不要有空行
- 规则块之间保留一个空行
- 选择器与 `{` 之间有一个空格
- 属性值后的 `;` 前不要有空格
#### 示例
```css
/* 正确 */
.selector {
property: value;
another-property: value;
}
.another-selector {
property: value;
}
/* 错误 - 属性之间有空行 */
.selector {
property: value;
another-property: value;
}
```
#### 注释规范
```css
/* ==========================================================================
大区块标题
========================================================================== */
/* ---------- 小区块标题 ---------- */
/* 普通注释 */
```
### JavaScript 规范
#### 格式化规则
- 使用 Tab 缩进
- 字符串优先使用单引号 `'`
- 比较运算符使用严格相等 `===``!==`
- 语句末尾必须有分号 `;`
- 函数名与括号之间无空格
- 关键字后有空格if, for, while, function 等)
#### 变量声明
- 优先使用 `let``const`
- 避免使用 `var`(除非需要函数作用域或全局变量)
#### 全局变量(需保留 var
以下全局变量必须使用 `var` 声明以确保跨作用域访问:
- `argonConfig` - 主题配置对象
- `translation` - 多语言翻译表
- `pjaxLoading` - PJAX 加载状态
- `headroom` - Headroom 实例
#### 注释规范
```javascript
// ==========================================================================
// 大区块标题
// ==========================================================================
// ---------- 小区块标题 ----------
/**
* 函数说明
* @param {string} param - 参数说明
* @returns {boolean} 返回值说明
*/
function functionName(param) {
// 单行注释
if (param === 'value') {
return true;
}
return false;
}
```
### PHP 规范
#### 格式化规则
- 使用 Tab 缩进
- 字符串优先使用单引号
- 数组使用短语法 `[]`
- 类名使用 PascalCase
- 函数名使用 snake_case遵循 WordPress 规范)
- 箭头操作符 `->` 前后不要有空格
#### WordPress 特定
- 使用 `esc_html()`, `esc_attr()` 等函数转义输出
- 使用 `wp_nonce_field()` 进行安全验证
- 遵循 WordPress Coding Standards
#### 示例
```php
// 正确
$theme->Version
get_option('argon_theme_color')
// 错误
$theme -> Version
```
## 核心架构
### 主题初始化流程
主题的初始化分为服务器端PHP和客户端JavaScript两个阶段。
#### 服务器端初始化
1. **functions.php 加载**WordPress 加载主题时执行)
```php
// functions.php
// 检查 WordPress 版本兼容性
if (version_compare($GLOBALS['wp_version'], '4.4-alpha', '<')) {
echo "<div style='...'>Argon 主题不支持 Wordpress 4.4 以下版本</div>";
}
// 设置主题支持功能
function theme_slug_setup() {
add_theme_support('title-tag'); // 标题标签
add_theme_support('post-thumbnails'); // 特色图片
load_theme_textdomain('argon', get_template_directory() . '/languages'); // 多语言
}
add_action('after_setup_theme','theme_slug_setup');
// 设置全局变量
$argon_version = !(wp_get_theme()->Template) ? wp_get_theme()->Version : wp_get_theme(wp_get_theme()->Template)->Version;
$GLOBALS['theme_version'] = $argon_version;
$GLOBALS['assets_path'] = get_bloginfo('template_url');
```
2. **header.php 渲染**(输出 HTML 头部)
```php
// header.php
// 1. 生成 HTML 类名(根据后台设置)
$htmlclasses = "";
if (get_option('argon_page_layout') == "single"){
$htmlclasses .= "single-column ";
}
if (get_option('argon_enable_immersion_color') == "true"){
$htmlclasses .= "immersion-color ";
}
// ... 更多类名
// 2. 获取主题色配置
$themecolor = get_option("argon_theme_color", "#5e72e4");
if (isset($_COOKIE["argon_custom_theme_color"])){
if (checkHEX($_COOKIE["argon_custom_theme_color"]) &&
get_option('argon_show_customize_theme_color_picker') != 'false'){
$themecolor = $_COOKIE["argon_custom_theme_color"];
}
}
// 3. 输出 HTML 文档头
?>
<html <?php language_attributes(); ?> class="no-js <?php echo $htmlclasses;?>">
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="theme-color" content="<?php echo $themecolor; ?>">
<!-- 预加载用户样式设置 - 避免样式跳变 -->
<script>
(function() {
var html = document.documentElement;
var ls = localStorage;
// 字体设置
if (ls.getItem('Argon_Use_Serif') === 'true') {
html.classList.add('use-serif');
}
// 阴影设置
if (ls.getItem('Argon_Use_Big_Shadow') === 'true') {
html.classList.add('use-big-shadow');
}
// ... 更多设置
})();
</script>
<?php
// 4. 加载 CSS 和 JavaScript
$assets_version = argon_get_assets_version();
wp_enqueue_style("argon_css_merged", $GLOBALS['assets_path'] . "/assets/argon_css_merged.css", array(), $assets_version, 'all');
wp_enqueue_style("style", $GLOBALS['assets_path'] . "/style.css", array('argon_css_merged'), $assets_version, 'all');
wp_enqueue_script("argon_js_merged", $GLOBALS['assets_path'] . "/assets/argon_js_merged.js", array(), $assets_version, false);
?>
<?php wp_head(); ?>
<!-- 5. 输出动态 CSS 变量 -->
<style id="themecolor_css">
:root{
--themecolor: <?php echo $themecolor; ?>;
--themecolor-R: <?php echo $RGB['R']; ?>;
--themecolor-G: <?php echo $RGB['G']; ?>;
--themecolor-B: <?php echo $RGB['B']; ?>;
--themecolor-H: <?php echo $HSL['H']; ?>;
--themecolor-S: <?php echo $HSL['S']; ?>;
--themecolor-L: <?php echo $HSL['L']; ?>;
}
</style>
<!-- 6. 输出全局配置对象 -->
<script>
document.documentElement.classList.remove("no-js");
var argonConfig = {
wp_path: "<?php echo $GLOBALS['wp_path']; ?>",
language: "<?php echo argon_get_locate(); ?>",
// ... 更多配置
};
</script>
<!-- 7. 夜间模式初始化脚本 -->
<script>
var darkmodeAutoSwitch = "<?php echo get_option("argon_darkmode_autoswitch");?>";
function setDarkmode(enable){ /* ... */ }
function toggleDarkmode(){ /* ... */ }
// ... 夜间模式逻辑
</script>
</head>
```
#### 客户端初始化
1. **兼容性修复**argontheme.js 开头)
```javascript
// argontheme.js
// 确保 Prism 存在
if (typeof window.Prism === 'undefined') {
window.Prism = {
highlightAll: function() {},
highlightElement: function() {},
plugins: {}
};
}
// 确保 jQuery 插件存在
if (typeof jQuery !== 'undefined') {
(function($) {
// 修复空选择器问题
if (!$.fn._argonInit) {
$.fn._argonInit = $.fn.init;
$.fn.init = function(selector, context, root) {
if (typeof selector === 'string') {
let trimmed = selector.trim();
if (trimmed === '' || trimmed === '#') {
return new $.fn._argonInit();
}
}
return $.fn._argonInit.call(this, selector, context, root);
};
$.fn.init.prototype = $.fn;
}
})(jQuery);
}
```
2. **工具函数定义**
```javascript
// argontheme.js
// Cookie 操作
function setCookie(cname, cvalue, exdays) { /* ... */ }
function getCookie(cname) { /* ... */ }
// 多语言翻译
var translation = {};
translation['en_US'] = { /* ... */ };
translation['ru_RU'] = { /* ... */ };
function __(text) {
if (typeof translation[argonConfig.language] !== 'undefined' &&
typeof translation[argonConfig.language][text] !== 'undefined') {
return translation[argonConfig.language][text];
}
return text;
}
```
3. **DOM 加载完成后初始化**
```javascript
// argontheme.js
$(document).ready(function() {
// 初始化顶栏
initNavbar();
// 初始化侧边栏
initSidebar();
// 初始化瀑布流
waterflowInit();
// 初始化懒加载
if (argonConfig.lazyload) {
initLazyload();
}
// 初始化图片缩放
if (argonConfig.zoomify) {
$('.post-content img').zoomify(argonConfig.zoomify);
}
// 初始化代码高亮
if (argonConfig.code_highlight.enable) {
initCodeHighlight();
}
// 初始化评论系统
initCommentSystem();
// 初始化浮动按钮
initFloatButtons();
// 初始化 PJAX
if (!argonConfig.disable_pjax) {
initPjax();
}
// 移除加载类
$('#float_action_buttons').removeClass('fabtns-unloaded');
});
```
#### 资源加载策略
1. **CSS 加载顺序**
```php
// header.php
// 1. 合并的 CSS包含 Bootstrap 和 Argon Design System
wp_enqueue_style("argon_css_merged", ".../argon_css_merged.css");
// 2. 主题样式(依赖合并的 CSS
wp_enqueue_style("style", ".../style.css", array('argon_css_merged'));
```
2. **JavaScript 加载顺序**
```php
// header.php
// 1. 资源加载器(用于备用资源加载)
wp_enqueue_script("resource_loader", ".../resource-loader.js");
// 2. 合并的 JS包含 jQuery 和其他库)- 在头部同步加载
wp_enqueue_script("argon_js_merged", ".../argon_js_merged.js", array(), $assets_version, false);
// 3. Argon 修复补丁(必须在 wp_head() 之后)
<script src="<?php echo get_template_directory_uri(); ?>/assets/js/argon.min.js"></script>
// 4. 主题核心脚本(在 footer.php 中加载)
wp_enqueue_script("argontheme", ".../argontheme.js", array('argon_js_merged'));
```
3. **按需加载**
```javascript
// argontheme.js
// Google Fonts 按需加载
if (typeof ArgonResourceLoader !== "undefined") {
ArgonResourceLoader.smartLoad("//fonts.googleapis.com/css?family=...", "css");
}
// 数学公式渲染库按需加载(在 footer.php 中)
<?php if (get_option('argon_mathjax_option') != 'disabled'): ?>
<script src="//cdn.jsdelivr.net/npm/mathjax@3/..."></script>
<?php endif; ?>
```
#### 强制刷新机制
当主题更新后,可能需要清除客户端缓存:
```php
// functions.php
function argon_is_force_refresh_enabled() {
$enabled_time = get_option('argon_force_refresh_enabled_time', 0);
if ($enabled_time == 0) {
return false;
}
// 1 小时后自动关闭
if (time() - $enabled_time > 3600) {
update_option('argon_force_refresh_enabled_time', 0);
return false;
}
return true;
}
function argon_get_assets_version() {
if (argon_is_force_refresh_enabled()) {
$enabled_time = get_option('argon_force_refresh_enabled_time', 0);
return $GLOBALS['theme_version'] . '.r' . $enabled_time;
}
return $GLOBALS['theme_version'];
}
```
强制刷新时header.php 会输出清除缓存的脚本:
```javascript
// header.php
<?php if (argon_is_force_refresh_enabled()): ?>
<script>
(function() {
var forceRefreshKey = 'argon_force_refresh_version';
var currentVersion = '<?php echo get_option('argon_force_refresh_enabled_time', 0); ?>';
var lastVersion = localStorage.getItem(forceRefreshKey);
if (lastVersion !== currentVersion) {
localStorage.setItem(forceRefreshKey, currentVersion);
if (lastVersion !== null) {
// 清除所有缓存
if ('caches' in window) {
caches.keys().then(function(names) {
return Promise.all(names.map(function(name) {
return caches.delete(name);
}));
});
}
// 重新加载页面
window.location.reload();
}
}
})();
</script>
<?php endif; ?>
```
### 全局配置对象
`argonConfig` 是主题的核心配置对象,在 header.php 中通过 PHP 动态生成并输出到页面:
```javascript
var argonConfig = {
wp_path: "/", // WordPress 安装路径
language: "zh_CN", // 当前语言代码
dateFormat: "YMD", // 日期显示格式
// 图片缩放配置Zoomify
zoomify: {
duration: 200, // 缩放动画时长(毫秒)
easing: "cubic-bezier(0.4,0,0,1)", // 缓动函数
scale: 0.9 // 缩放比例
},
// 如果禁用则为 false
pangu: "false", // 盘古之白(中英文间自动加空格)
// 懒加载配置
lazyload: true, // 是否启用懒加载
lazyload_effect: "fadeIn", // 懒加载显示效果
lazyload_threshold: 800, // 提前加载阈值(像素)
fold_long_comments: false, // 是否折叠长评论
fold_long_shuoshuo: false, // 是否折叠长说说
// PJAX 配置
disable_pjax: false, // 是否禁用 PJAX
pjax_animation_durtion: 600, // PJAX 切换动画时长(毫秒)
headroom: "false", // 顶栏自动隐藏模式false/true/absolute
// 文章列表布局
waterflow_columns: "1", // 瀑布流列数1/2/3
article_list_layout_mobile: "1", // 移动端文章列表布局样式
// 代码高亮配置
code_highlight: {
enable: false, // 是否启用代码高亮
hide_linenumber: false, // 是否隐藏行号
transparent_linenumber: false, // 行号是否透明
break_line: false // 是否自动折行
}
};
```
配置对象的值从 WordPress 后台设置中读取,通过 PHP 的 `get_option()` 函数获取。例如:
```php
// header.php
lazyload: <?php echo (get_option('argon_enable_lazyload', 'true') == 'false' ? 'false' : 'true'); ?>,
```
### CSS 变量系统
主题使用 CSS 自定义属性CSS Variables实现动态主题色和样式配置。这些变量在 header.php 中通过 PHP 动态生成。
#### 主题色变量
```php
// header.php - 获取主题色
$themecolor = get_option("argon_theme_color", "#5e72e4");
// 支持用户自定义主题色(通过 Cookie
if (isset($_COOKIE["argon_custom_theme_color"])) {
if (checkHEX($_COOKIE["argon_custom_theme_color"]) &&
get_option('argon_show_customize_theme_color_picker') != 'false') {
$themecolor = $_COOKIE["argon_custom_theme_color"];
}
}
// 转换为 RGB 和 HSL 值
$RGB = hexstr2rgb($themecolor);
$HSL = rgb2hsl($RGB['R'], $RGB['G'], $RGB['B']);
```
生成的 CSS 变量:
```css
:root {
/* 主题色 - 十六进制 */
--themecolor: #5e72e4;
/* 主题色 - RGB 分量(用于 rgba() 函数)*/
--themecolor-R: 94;
--themecolor-G: 114;
--themecolor-B: 228;
/* 主题色 - HSL 分量(用于生成色调变体)*/
--themecolor-H: 231;
--themecolor-S: 71;
--themecolor-L: 63;
}
```
#### 动画系统变量
```css
:root {
/* 动画时长 - 遵循 Material Design 3 规范 */
--animation-fast: 150ms; //
--animation-normal: 250ms; //
--animation-slow: 400ms; //
/* 缓动函数 - 融合 Material 3 + Apple 风格 */
--ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1); //
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); //
}
```
#### 卡片样式变量
```css
:root {
--card-radius: 4px; //
--card-opacity: 0.7; //
--card-blur: 20px; //
--card-saturate: 180%; //
--toolbar-blur: 12px; // 60%
--page-background-opacity: 1; //
}
```
这些值可以通过后台设置动态调整:
```php
// header.php
$card_opacity = get_option('argon_post_background_opacity', '0.7');
$card_blur = get_option('argon_card_blur', '20');
$card_saturate = get_option('argon_card_saturate', '180');
```
#### 颜色变量
```css
:root {
/* 日间模式颜色 */
--color-background: #f4f5f7; //
--color-foreground: #fff; //
--color-widgets: #fff; //
--color-border: #dce0e5; //
--color-text-deeper: #212529; //
}
```
夜间模式通过 `html.darkmode` 类切换颜色变量:
```css
html.darkmode body {
--color-background: #282828; //
--color-foreground: #424242; //
--color-widgets: #555; //
--color-text-deeper: #eee; //
}
```
AMOLED 暗黑模式提供更深的黑色:
```css
html.darkmode.amoled-dark body {
--color-background: #111; //
--color-foreground: #000; //
--color-widgets: #151515; //
}
```
## 核心功能模块
### 1. 主题色系统
#### 实现原理
主题色通过 PHP 动态生成 CSS 变量,支持用户自定义:
```php
// header.php
$themecolor = get_option("argon_theme_color", "#5e72e4");
if (isset($_COOKIE["argon_custom_theme_color"])) {
$themecolor = $_COOKIE["argon_custom_theme_color"];
}
$RGB = hexstr2rgb($themecolor);
$HSL = rgb2hsl($RGB['R'], $RGB['G'], $RGB['B']);
```
生成的 CSS 变量:
```css
:root {
--themecolor: #5e72e4;
--themecolor-R: 94;
--themecolor-G: 114;
--themecolor-B: 228;
--themecolor-H: 231;
--themecolor-S: 71;
--themecolor-L: 63;
}
```
#### 沉浸式主题色
开启沉浸式主题色后,页面背景和卡片会使用主题色的浅色变体:
```css
html.immersion-color body {
--color-background: rgb(var(--color-tint-86));
--color-foreground: rgb(var(--color-tint-92));
}
```
### 2. 夜间模式
#### 切换方案
主题支持四种夜间模式切换方案,通过后台设置 `argon_darkmode_autoswitch` 选项控制:
1. **false默认** - 手动切换,不自动切换
2. **system** - 跟随系统,通过 `prefers-color-scheme` 媒体查询
3. **time** - 根据时间自动切换22:00-7:00
4. **alwayson** - 始终开启夜间模式
#### 实现代码
夜间模式的核心实现在 header.php 中:
```javascript
// header.php
var darkmodeAutoSwitch = "<?php echo (get_option("argon_darkmode_autoswitch") == '' ? 'false' : get_option("argon_darkmode_autoswitch"));?>";
// 设置夜间模式
function setDarkmode(enable){
// 添加过渡类以启用平滑切换动画
document.documentElement.classList.add("theme-transitioning");
if (enable == true){
document.documentElement.classList.add("darkmode");
}else{
document.documentElement.classList.remove("darkmode");
}
// 过渡完成后移除过渡类300ms 后)
setTimeout(function() {
document.documentElement.classList.remove("theme-transitioning");
}, 300);
// 触发滚动事件以更新顶栏状态
if (typeof jQuery !== 'undefined') {
jQuery(window).trigger("scroll");
} else {
window.dispatchEvent(new Event('scroll'));
}
// 触发自定义事件,供其他模块监听
document.dispatchEvent(new CustomEvent('argon:theme-switched', {
detail: { darkmode: enable }
}));
}
// 切换夜间模式
function toggleDarkmode(){
if (document.documentElement.classList.contains("darkmode")){
setDarkmode(false);
sessionStorage.setItem("Argon_Enable_Dark_Mode", "false");
}else{
setDarkmode(true);
sessionStorage.setItem("Argon_Enable_Dark_Mode", "true");
}
}
```
#### 跟随系统方案
使用 `matchMedia` API 监听系统主题变化:
```javascript
// header.php
function toggleDarkmodeByPrefersColorScheme(media){
// 如果用户手动设置过,则不自动切换
if (sessionStorage.getItem('Argon_Enable_Dark_Mode') == "false" ||
sessionStorage.getItem('Argon_Enable_Dark_Mode') == "true"){
return;
}
if (media.matches){
setDarkmode(true);
}else{
setDarkmode(false);
}
}
if (darkmodeAutoSwitch == 'system'){
var darkmodeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
darkmodeMediaQuery.addListener(toggleDarkmodeByPrefersColorScheme);
toggleDarkmodeByPrefersColorScheme(darkmodeMediaQuery);
}
```
#### 根据时间方案
```javascript
// header.php
function toggleDarkmodeByTime(){
// 如果用户手动设置过,则不自动切换
if (sessionStorage.getItem('Argon_Enable_Dark_Mode') == "false" ||
sessionStorage.getItem('Argon_Enable_Dark_Mode') == "true"){
return;
}
let hour = new Date().getHours();
// 默认22:00-7:00 开启夜间模式
// 可通过过滤器 argon_darkmode_time_check 自定义时间范围
if (<?php echo apply_filters("argon_darkmode_time_check", "hour < 7 || hour >= 22")?>){
setDarkmode(true);
}else{
setDarkmode(false);
}
}
if (darkmodeAutoSwitch == 'time'){
toggleDarkmodeByTime();
}
```
#### AMOLED 暗黑模式
AMOLED 模式提供更深的黑色背景,适合 AMOLED 屏幕节省电量:
```javascript
// header.php
function toggleAmoledDarkMode(){
document.documentElement.classList.toggle("amoled-dark");
if (document.documentElement.classList.contains("amoled-dark")){
localStorage.setItem("Argon_Enable_Amoled_Dark_Mode", "true");
}else{
localStorage.setItem("Argon_Enable_Amoled_Dark_Mode", "false");
}
}
// 页面加载时恢复 AMOLED 模式设置
if (localStorage.getItem("Argon_Enable_Amoled_Dark_Mode") == "true"){
document.documentElement.classList.add("amoled-dark");
}else if (localStorage.getItem("Argon_Enable_Amoled_Dark_Mode") == "false"){
document.documentElement.classList.remove("amoled-dark");
}
```
#### 用户偏好存储
夜间模式的用户选择存储在 `sessionStorage`AMOLED 模式存储在 `localStorage` 中:
- `sessionStorage.Argon_Enable_Dark_Mode` - 夜间模式开关(会话级别)
- `localStorage.Argon_Enable_Amoled_Dark_Mode` - AMOLED 模式开关(持久化)
这样设计的原因:
- 夜间模式使用 sessionStorage每次打开浏览器都会根据设置重新判断
- AMOLED 模式使用 localStorage用户设置会永久保存
### 3. PJAX 无刷新加载
#### 配置与初始化
PJAX 使用 jquery-pjax 库实现页面无刷新加载。配置在 argontheme.js 中:
```javascript
// argontheme.js
$.pjax.defaults.timeout = 10000; // 超时时间 10 秒
$.pjax.defaults.container = ['#content', '#leftbar', '#rightbar']; // 要替换的容器
$.pjax.defaults.fragment = ['#content', '#leftbar', '#rightbar']; // 从响应中提取的片段
```
#### 链接拦截
主题会自动拦截站内链接的点击事件:
```javascript
// argontheme.js
$(document).on('click', 'a[href^="' + argonConfig.wp_path + '"]:not([no-pjax]):not([target])', function(event) {
// 排除特殊链接
if ($(this).attr('href').indexOf('#') !== -1) return; // 锚点链接
if ($(this).attr('href').indexOf('wp-admin') !== -1) return; // 后台链接
if ($(this).attr('href').indexOf('wp-login') !== -1) return; // 登录链接
// 使用 PJAX 加载
$.pjax.click(event, {
container: ['#content', '#leftbar', '#rightbar'],
fragment: ['#content', '#leftbar', '#rightbar'],
timeout: 10000
});
});
```
#### 页面切换流程
PJAX 加载过程中会触发一系列事件:
```javascript
// argontheme.js
// 1. 开始发送请求
$(document).on('pjax:send', function() {
// 设置加载状态
pjaxLoading = true;
// 显示加载动画
$('#content').addClass('pjax-loading');
// 添加淡出效果
$('#content, #leftbar, #rightbar').css('opacity', '0');
});
// 2. 请求成功,内容已替换
$(document).on('pjax:complete', function() {
// 清除加载状态
pjaxLoading = false;
// 移除加载动画
$('#content').removeClass('pjax-loading');
// 添加淡入效果
$('#content, #leftbar, #rightbar').animate({
opacity: 1
}, argonConfig.pjax_animation_durtion);
// 滚动到顶部
$('html, body').animate({
scrollTop: 0
}, argonConfig.pjax_animation_durtion);
// 重新初始化各功能模块
reinitAfterPjax();
});
// 3. 请求失败
$(document).on('pjax:error', function(xhr, textStatus, error) {
console.error('PJAX 加载失败:', error);
// 失败时会自动回退到普通页面跳转
});
// 4. 超时
$(document).on('pjax:timeout', function(event) {
// 阻止默认的超时处理(会中断请求)
event.preventDefault();
});
```
#### 重新初始化
PJAX 加载完成后,需要重新初始化页面功能:
```javascript
// argontheme.js
function reinitAfterPjax() {
// 重新初始化代码高亮
if (typeof Prism !== 'undefined') {
Prism.highlightAll();
}
// 重新初始化图片懒加载
if (argonConfig.lazyload) {
initLazyload();
}
// 重新初始化瀑布流布局
if (argonConfig.waterflow_columns != '1') {
waterflowInit();
}
// 重新初始化图片缩放
if (argonConfig.zoomify) {
$('.post-content img').zoomify(argonConfig.zoomify);
}
// 重新绑定评论表单事件
bindCommentFormEvents();
// 重新初始化数学公式渲染
if (typeof MathJax !== 'undefined') {
MathJax.typesetPromise();
} else if (typeof renderMathInElement !== 'undefined') {
renderMathInElement(document.body);
}
// 触发自定义事件
$(document).trigger('argon:pjax-complete');
}
```
#### 禁用 PJAX
可以通过以下方式禁用 PJAX
1. 后台设置中禁用(`argon_pjax_disabled` 选项)
2. 给链接添加 `no-pjax` 属性:
```html
<a href="/page" no-pjax>普通跳转</a>
```
3. 给链接添加 `target` 属性:
```html
<a href="/page" target="_blank">新窗口打开</a>
```
#### 浏览器历史记录
PJAX 会自动更新浏览器历史记录,支持前进后退按钮:
```javascript
// argontheme.js
$(window).on('popstate', function() {
// 浏览器前进/后退时PJAX 会自动加载对应页面
});
```
#### 性能优化
PJAX 加载时的性能优化措施:
1. 只替换必要的容器content、leftbar、rightbar
2. 使用 CSS 动画而非 JavaScript 动画
3. 延迟初始化非关键功能
4. 复用已加载的资源CSS、JS
```javascript
// argontheme.js
// 动画时长可配置,设为 0 可禁用动画
pjax_animation_durtion: <?php echo (get_option("argon_disable_pjax_animation") == 'true' ? '0' : '600'); ?>
```
### 4. 瀑布流布局
#### 实现原理
瀑布流布局通过 JavaScript 动态计算每个文章卡片的位置,实现类似 Pinterest 的多列布局。
#### 核心算法
```javascript
// argontheme.js
function waterflowInit() {
// 如果设置为单列,直接返回
if (argonConfig.waterflow_columns == "1") {
return;
}
// 监听图片加载,加载完成后重新计算布局
$("#main.article-list img").each(function(index, ele){
ele.onload = function(){
waterflowInit();
}
});
// 确定列数
let columns;
if (argonConfig.waterflow_columns == "2and3") {
// 自适应 2-3 列
if ($("#main").outerWidth() > 1000) {
columns = 3;
} else {
columns = 2;
}
}else{
columns = parseInt(argonConfig.waterflow_columns);
}
// 响应式适配:窄屏幕时强制单列
if ($("#main").outerWidth() < 650 && columns == 2) {
columns = 1;
}else if ($("#main").outerWidth() < 800 && columns == 3) {
columns = 1;
}
// 记录每列的高度
let heights = [0, 0, 0];
// 获取当前最矮列的索引
function getMinHeightPosition(){
let res = 0, minn = 2147483647;
for (var i = 0; i < columns; i++) {
if (heights[i] < minn) {
minn = heights[i];
res = i;
}
}
return res;
}
// 获取最高列的高度
function getMaxHeight(){
let res = 0;
for (let i in heights) {
res = Math.max(res, heights[i]);
}
return res;
}
// 添加瀑布流类
$("#primary").css("transition", "none").addClass("waterflow");
let $container = $("#main.article-list");
if (!$container.length){
return;
}
// 获取所有文章卡片
let $items = $container.find("article.post:not(.no-results), .shuoshuo-preview-container");
// 列数不能超过文章数量
columns = Math.max(Math.min(columns, $items.length), 1);
if (columns == 1) {
// 单列模式:移除瀑布流样式
$container.removeClass("waterflow");
$items.css("transition", "")
.css("position", "")
.css("width", "")
.css("top", "")
.css("left", "")
.css("margin", "");
$(".waterflow-placeholder").remove();
}else{
// 多列模式:计算每个卡片的位置
$container.addClass("waterflow");
$items.each(function(index, item) {
let $item = $(item);
// 设置卡片宽度(平分容器宽度,减去间距)
$item.css("transition", "none")
.css("position", "absolute")
.css("width", "calc(" + (100 / columns) + "% - " + (10 * (columns - 1) / columns) + "px)")
.css("margin", 0);
// 计算卡片高度(包含 10px 间距)
let itemHeight = $item.outerHeight() + 10;
// 找到最矮的列
let pos = getMinHeightPosition();
// 设置卡片位置
$item.css("top", heights[pos] + "px")
.css("left", (pos * $item.outerWidth() + 10 * pos) + "px");
// 更新该列的高度
heights[pos] += itemHeight;
});
}
// 创建占位元素,撑开容器高度
if ($(".waterflow-placeholder").length) {
$(".waterflow-placeholder").css("height", getMaxHeight() + "px");
}else{
$container.prepend("<div class='waterflow-placeholder' style='height: " + getMaxHeight() +"px;'></div>");
}
}
```
#### 初始化与监听
```javascript
// argontheme.js
// 页面加载时初始化
waterflowInit();
// 非单列模式下监听窗口大小变化
if (argonConfig.waterflow_columns != "1") {
// 窗口大小改变时重新计算
$(window).resize(function(){
waterflowInit();
});
// 监听 DOM 变化(如 PJAX 加载新内容)
new MutationObserver(function(mutations, observer){
waterflowInit();
}).observe(document.querySelector("#primary"), {
'childList': true
});
}
```
#### 移动端布局切换
移动端可以使用不同的文章列表布局样式:
```javascript
// argontheme.js
!function(){
var mobileLayout = argonConfig.article_list_layout_mobile || "1";
var isMobile = window.innerWidth <= 900;
function applyMobileLayout() {
var nowMobile = window.innerWidth <= 900;
if (nowMobile) {
// 添加移动端布局类
$("html").addClass("mobile-layout-" + mobileLayout);
} else {
// 移除移动端布局类
$("html").removeClass("mobile-layout-1 mobile-layout-2 mobile-layout-3");
}
}
applyMobileLayout();
$(window).resize(applyMobileLayout);
}();
```
#### 配置选项
瀑布流列数通过后台设置 `argon_article_list_waterflow` 控制:
- `"1"` - 单列(默认)
- `"2"` - 双列
- `"3"` - 三列
- `"2and3"` - 自适应 2-3 列(宽屏 3 列,窄屏 2 列)
#### 性能优化
1. 图片加载完成后才计算布局,避免高度计算错误
2. 使用 `MutationObserver` 监听 DOM 变化,而非轮询
3. 窗口大小改变时使用防抖,避免频繁计算
4. 单列模式下不监听事件,减少性能开销
#### CSS 配合
```css
/* style.css */
#main.article-list.waterflow {
position: relative;
}
#main.article-list.waterflow article.post {
position: absolute;
transition: top 0.3s ease, left 0.3s ease;
}
.waterflow-placeholder {
width: 100%;
pointer-events: none;
}
```
### 5. 评论系统
#### 数据库结构
评论数据存储在 WordPress 标准的 `wp_comments` 表中,扩展字段通过 `wp_commentmeta` 表存储:
- `comment_upvote` - 点赞数
- `comment_is_private` - 是否私密评论
- `comment_use_markdown` - 是否使用 Markdown
- `comment_edit_history` - 编辑历史JSON 格式)
- `comment_pinned` - 是否置顶
#### AJAX 发送评论
```javascript
// argontheme.js
function postComment() {
$.ajax({
type: 'POST',
url: argonConfig.wp_path + "wp-admin/admin-ajax.php",
dataType: "json",
data: {
action: "ajax_post_comment",
comment_post_ID: postID,
author: name,
email: email,
url: url,
comment: content,
comment_parent: replyID,
// ... 其他参数
},
success: function(result) {
if (result.status == "success") {
// 插入新评论到页面
insertComment(result.comment_html);
}
}
});
}
```
#### PHP 处理函数
```php
// functions.php
function ajax_post_comment() {
// 验证 nonce
check_ajax_referer('post_comment', 'nonce');
// 验证验证码
if (argon_is_comment_captcha_enabled()) {
verify_captcha();
}
// 过滤内容
$comment_content = wp_filter_kses($_POST['comment']);
// 构建评论数据
$commentdata = array(
'comment_post_ID' => $post_id,
'comment_author' => $author,
'comment_author_email' => $email,
'comment_content' => $comment_content,
'comment_parent' => $parent,
'user_id' => get_current_user_id()
);
// 插入评论
$comment_id = wp_new_comment($commentdata);
// 保存扩展字段
if ($_POST['is_private'] == 'true') {
update_comment_meta($comment_id, 'comment_is_private', 'true');
}
// 发送邮件通知
send_comment_notification($comment_id);
// 返回结果
wp_send_json(array(
'status' => 'success',
'comment_html' => get_comment_html($comment_id)
));
}
add_action('wp_ajax_ajax_post_comment', 'ajax_post_comment');
add_action('wp_ajax_nopriv_ajax_post_comment', 'ajax_post_comment');
```
#### 评论格式化
```php
// functions.php
function argon_comment_format($comment, $args, $depth) {
$GLOBALS['comment'] = $comment;
?>
<li id="comment-<?php comment_ID(); ?>" <?php comment_class(); ?>>
<div class="comment-item">
<div class="comment-avatar">
<?php echo get_avatar($comment, 48); ?>
</div>
<div class="comment-body">
<div class="comment-item-title">
<span class="comment-name">
<?php echo get_comment_author_link(); ?>
</span>
<?php if (get_comment_meta($comment->comment_ID, 'comment_is_private', true) == 'true'): ?>
<span class="badge badge-secondary badge-private-comment">
私密
</span>
<?php endif; ?>
</div>
<div class="comment-item-text">
<?php comment_text(); ?>
</div>
<div class="comment-item-meta">
<span class="comment-time">
<?php echo get_comment_date('Y-m-d H:i'); ?>
</span>
<a class="comment-reply" data-id="<?php comment_ID(); ?>">
回复
</a>
</div>
</div>
</div>
</li>
<?php
}
```
#### 评论编辑功能
支持用户编辑自己的评论,保留编辑历史:
```php
// functions.php
function user_edit_comment() {
check_ajax_referer('edit_comment', 'nonce');
$comment_id = intval($_POST['id']);
$comment = get_comment($comment_id);
// 权限检查
if (!current_user_can('edit_comment', $comment_id) &&
$comment->user_id != get_current_user_id()) {
wp_send_json(array('status' => 'failed', 'reason' => '权限不足'));
}
// 保存编辑历史
$history = get_comment_meta($comment_id, 'comment_edit_history', true);
if (!$history) $history = array();
$history[] = array(
'content' => $comment->comment_content,
'time' => current_time('timestamp')
);
update_comment_meta($comment_id, 'comment_edit_history', $history);
// 更新评论内容
wp_update_comment(array(
'comment_ID' => $comment_id,
'comment_content' => $_POST['content']
));
wp_send_json(array('status' => 'success'));
}
add_action('wp_ajax_user_edit_comment', 'user_edit_comment');
```
#### 评论点赞
```php
// functions.php
function upvote_comment() {
$comment_id = intval($_POST['id']);
$upvote_key = 'comment_upvote_' . $comment_id;
// 检查是否已点赞
if (isset($_COOKIE[$upvote_key])) {
wp_send_json(array('status' => 'failed', 'reason' => '已点赞'));
}
// 增加点赞数
$upvotes = intval(get_comment_meta($comment_id, 'comment_upvote', true));
update_comment_meta($comment_id, 'comment_upvote', $upvotes + 1);
// 设置 Cookie 防止重复点赞
setcookie($upvote_key, '1', time() + 86400 * 365, '/');
wp_send_json(array(
'status' => 'success',
'upvotes' => $upvotes + 1
));
}
add_action('wp_ajax_upvote_comment', 'upvote_comment');
add_action('wp_ajax_nopriv_upvote_comment', 'upvote_comment');
```
### 6. 说说功能
#### 自定义文章类型
说说是一个独立的自定义文章类型,类似微博的短内容发布功能:
```php
// functions.php
add_action('init', 'init_shuoshuo');
function init_shuoshuo(){
$labels = array(
'name' => __('说说', 'argon'),
'singular_name' => __('说说', 'argon'),
'add_new' => __('发表说说', 'argon'),
'add_new_item' => __('发表说说', 'argon'),
'edit_item' => __('编辑说说', 'argon'),
'new_item' => __('新说说', 'argon'),
'view_item' => __('查看说说', 'argon'),
'search_items' => __('搜索说说', 'argon'),
'not_found' => __('暂无说说', 'argon'),
'not_found_in_trash' => __('没有已遗弃的说说', 'argon'),
'parent_item_colon' => '',
'menu_name' => __('说说', 'argon')
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'exclude_from_search' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'shuoshuo',
'with_front' => false
),
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => false,
'menu_position' => null,
'menu_icon' => 'dashicons-format-quote',
'supports' => array('editor', 'author', 'title', 'custom-fields', 'comments')
);
register_post_type('shuoshuo', $args);
}
```
#### 页面模板
说说页面使用独立的模板文件 `shuoshuo.php`
```php
// shuoshuo.php
/*
Template Name: 说说
*/
query_posts("post_type=shuoshuo&post_status=publish&posts_per_page=-1");
```
#### 说说内容模板
说说内容通过 `template-parts/content-shuoshuo.php` 渲染:
```php
<div class="shuoshuo-item card">
<div class="card-body">
<div class="shuoshuo-author">
<?php echo get_avatar(get_the_author_meta('ID'), 40); ?>
<span class="shuoshuo-author-name">
<?php the_author(); ?>
</span>
</div>
<div class="shuoshuo-content">
<?php the_content(); ?>
</div>
<div class="shuoshuo-meta">
<span class="shuoshuo-time">
<?php echo get_the_date('Y-m-d H:i'); ?>
</span>
<span class="shuoshuo-comment-count">
<?php comments_number('0 条评论', '1 条评论', '% 条评论'); ?>
</span>
</div>
</div>
</div>
```
#### 说说操作按钮
支持点赞、评论、分享等操作,通过 `template-parts/shuoshuo-operations.php` 实现。
#### 折叠长说说
当说说内容超过一定长度时自动折叠:
```javascript
// argontheme.js
if (argonConfig.fold_long_shuoshuo) {
$('.shuoshuo-content').each(function() {
let $content = $(this);
if ($content.height() > 300) {
$content.addClass('folded');
$content.after('<a class="unfold-btn">展开</a>');
}
});
}
```
### 7. AI 摘要功能
#### 功能概述
AI 摘要功能允许为文章自动生成摘要,支持多种 AI 服务提供商。
#### 查询接口
通过独立的 PHP 文件 `ai-summary-query.php` 处理 AI 摘要请求:
```php
// ai-summary-query.php
$wp_load_path = dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
if (!file_exists($wp_load_path)) $wp_load_path = $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php';
require_once($wp_load_path);
```
#### 安全防护
实现了完善的 IP 访问限制机制:
```php
/**
* 获取客户端真实 IP
* 优先级CF-Connecting-IP > X-Real-IP > X-Forwarded-For > REMOTE_ADDR
*/
function argon_ai_query_get_client_ip() {
$ip = '';
// Cloudflare
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
// Nginx proxy_pass 或其他反向代理
elseif (!empty($_SERVER['HTTP_X_REAL_IP'])) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
// 通过代理转发(取第一个 IP
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
}
// 直连 IP
else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return trim($ip);
}
```
#### 访问频率限制
```php
/**
* 检查 IP 访问频率限制
* @return bool|string true 表示允许访问,字符串表示错误信息
*/
function argon_ai_query_check_rate_limit() {
$client_ip = argon_ai_query_get_client_ip();
if (empty($client_ip)) {
return __('无法获取客户端 IP', 'argon');
}
$transient_key = 'ai_query_lock_' . md5($client_ip);
$rate_limit_key = 'ai_query_rate_' . md5($client_ip);
// 检查是否有正在进行的查询(单线程限制)
if (get_transient($transient_key)) {
return __('请等待上一次查询完成', 'argon');
}
// 检查访问频率60秒内最多10次
$access_count = get_transient($rate_limit_key);
if ($access_count === false) {
set_transient($rate_limit_key, 1, 60);
} else {
if ($access_count >= 10) {
return __('访问过于频繁,请稍后再试', 'argon');
}
set_transient($rate_limit_key, $access_count + 1, 60);
}
// 设置查询锁3秒超时
set_transient($transient_key, 1, 3);
return true;
}
```
#### AI 服务配置
在后台设置页面配置 AI 服务:
- API 端点 URL
- API 密钥
- 模型名称
- 请求参数(温度、最大 token 数等)
- 超时设置
#### 前端调用
```javascript
// argontheme.js
function loadAISummary(postId) {
$.ajax({
url: argonConfig.wp_path + '?argon_ai_query=1',
type: 'POST',
data: {
post_id: postId
},
success: function(response) {
$('#ai-summary-content').html(response.summary);
}
});
}
```
### 8. 后台设置系统
#### 设置页面结构
`settings.php` 是主题的后台设置页面,包含约 6000 行代码,提供完整的主题配置界面。
#### 设置分类
设置页面分为多个选项卡:
1. 外观设置 - 主题色、布局、卡片样式
2. 功能设置 - PJAX、懒加载、代码高亮
3. 文章设置 - 文章列表样式、摘要长度
4. 评论设置 - 评论验证码、邮件通知
5. 说说设置 - 说说页面配置
6. AI 设置 - AI 摘要服务配置
7. 性能优化 - 资源合并、缓存控制
8. 高级设置 - 自定义 CSS/JS、SEO
#### 选项存储
所有设置通过 WordPress Options API 存储:
```php
// 保存设置
update_option('argon_theme_color', $_POST['argon_theme_color']);
// 读取设置
$theme_color = get_option('argon_theme_color', '#5e72e4');
```
#### 设置验证
提交设置时进行安全验证:
```php
// settings.php
if (isset($_POST['save'])) {
// 验证 nonce
check_admin_referer('argon_theme_options');
// 验证权限
if (!current_user_can('manage_options')) {
wp_die(__('权限不足', 'argon'));
}
// 保存设置
foreach ($_POST as $key => $value) {
if (strpos($key, 'argon_') === 0) {
update_option($key, sanitize_text_field($value));
}
}
echo '<div class="updated"><p>设置已保存</p></div>';
}
```
#### 动态设置界面
设置页面使用 jQuery 实现动态交互:
```javascript
// settings.php 内嵌脚本
$(document).ready(function() {
// 选项卡切换
$('.nav-tab').click(function() {
let target = $(this).data('target');
$('.nav-tab').removeClass('nav-tab-active');
$(this).addClass('nav-tab-active');
$('.settings-section').hide();
$('#' + target).show();
});
// 颜色选择器
$('.color-picker').wpColorPicker();
// 拖拽排序
dragula([$('#sortable-list')[0]]);
});
```
#### AI API 配置表格
支持配置多个 AI 服务提供商:
```php
<table class="argon-ai-api-table">
<thead>
<tr>
<th>服务名称</th>
<th>API 端点</th>
<th>API 密钥</th>
<th>模型</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="argon-unified-api-list">
<?php
$api_list = get_option('argon_ai_api_list', []);
foreach ($api_list as $api) {
echo '<tr>';
echo '<td>' . esc_html($api['name']) . '</td>';
echo '<td>' . esc_html($api['endpoint']) . '</td>';
echo '<td>***</td>';
echo '<td>' . esc_html($api['model']) . '</td>';
echo '<td>' . ($api['enabled'] ? '启用' : '禁用') . '</td>';
echo '<td><button class="edit-api">编辑</button></td>';
echo '</tr>';
}
?>
</tbody>
</table>
```
### 9. 性能优化
#### 资源合并
主题支持将多个 CSS 和 JS 文件合并为单个文件:
```php
// functions.php
function argon_merge_assets() {
$css_files = [
'assets/css/bootstrap/bootstrap.min.css',
'assets/css/argon.min.css',
'style.css'
];
$merged_css = '';
foreach ($css_files as $file) {
$merged_css .= file_get_contents(get_template_directory() . '/' . $file);
}
file_put_contents(
get_template_directory() . '/assets/argon_css_merged.css',
$merged_css
);
}
```
#### 懒加载
图片懒加载通过 Lazy Load 库实现:
```javascript
// argontheme.js
function initLazyload() {
if (!argonConfig.lazyload) return;
$('img[data-src]').lazyload({
effect: argonConfig.lazyload_effect,
threshold: argonConfig.lazyload_threshold,
failure_limit: 10
});
}
```
#### 强制刷新缓存
提供强制刷新功能,用于更新后清除客户端缓存:
```php
// functions.php
function argon_is_force_refresh_enabled() {
$enabled_time = get_option('argon_force_refresh_enabled_time', 0);
if ($enabled_time == 0) {
return false;
}
// 检查是否超过 1 小时
if (time() - $enabled_time > 3600) {
// 自动关闭
update_option('argon_force_refresh_enabled_time', 0);
return false;
}
return true;
}
function argon_get_assets_version() {
if (argon_is_force_refresh_enabled()) {
$enabled_time = get_option('argon_force_refresh_enabled_time', 0);
return $GLOBALS['theme_version'] . '.r' . $enabled_time;
}
return $GLOBALS['theme_version'];
}
```
#### 缓存控制
针对不同类型的资源设置不同的缓存策略:
```php
// functions.php
function argon_static_resource_headers() {
if (is_admin() || argon_is_force_refresh_enabled()) {
return;
}
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
$static_extensions = array('.css', '.js', '.jpg', '.jpeg', '.png', '.gif', '.svg', '.woff', '.woff2', '.ttf', '.eot', '.ico');
$is_static = false;
foreach ($static_extensions as $ext) {
if (strpos($request_uri, $ext) !== false) {
$is_static = true;
break;
}
}
if ($is_static && !headers_sent()) {
// 静态资源缓存 1 年
header('Cache-Control: public, max-age=31536000, immutable', true);
}
}
add_action('send_headers', 'argon_static_resource_headers', 30);
```
#### 移动端缓存控制
禁止移动端浏览器缓存 HTML 页面,避免内容更新不及时:
```php
// functions.php
function argon_prevent_mobile_cache() {
if (wp_is_mobile() && !is_admin()) {
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
}
}
add_action('send_headers', 'argon_prevent_mobile_cache');
```
### 10. 安全机制
#### HTTP 安全头部
设置安全相关的 HTTP 头部:
```php
// functions.php
function argon_security_headers() {
if (is_admin()) {
return;
}
if (!headers_sent()) {
// 使用 Content-Security-Policy 替代 X-Frame-Options
// 允许同源嵌入,防止点击劫持
header("Content-Security-Policy: frame-ancestors 'self'", false);
// 移除 X-Frame-Options如果存在
header_remove('X-Frame-Options');
}
}
add_action('send_headers', 'argon_security_headers', 20);
```
#### AJAX 请求验证
所有 AJAX 请求都需要验证 nonce
```php
// functions.php
function ajax_post_comment() {
// 验证 nonce
check_ajax_referer('post_comment', 'nonce');
// 验证验证码
if (argon_is_comment_captcha_enabled()) {
verify_captcha();
}
// 处理评论...
}
add_action('wp_ajax_ajax_post_comment', 'ajax_post_comment');
add_action('wp_ajax_nopriv_ajax_post_comment', 'ajax_post_comment');
```
#### 内容过滤
使用 WordPress 内置函数过滤用户输入:
```php
// 过滤 HTML 标签
$comment_content = wp_filter_kses($_POST['comment']);
// 转义输出
echo esc_html($user_name);
echo esc_attr($user_email);
echo esc_url($user_url);
```
#### 权限检查
在执行敏感操作前检查用户权限:
```php
// functions.php
function user_edit_comment() {
check_ajax_referer('edit_comment', 'nonce');
$comment_id = intval($_POST['id']);
$comment = get_comment($comment_id);
// 权限检查:管理员或评论作者本人
if (!current_user_can('edit_comment', $comment_id) &&
$comment->user_id != get_current_user_id()) {
wp_send_json(array('status' => 'failed', 'reason' => '权限不足'));
}
// 执行编辑操作...
}
```
#### 验证码系统
评论支持多种验证码方案:
- 算术验证码
- Google reCAPTCHA
- hCaptcha
- Cloudflare Turnstile
```php
// functions.php
function argon_is_comment_captcha_enabled() {
$captcha_type = get_option('argon_comment_captcha_type', 'none');
return $captcha_type !== 'none';
}
function verify_captcha() {
$captcha_type = get_option('argon_comment_captcha_type', 'none');
switch ($captcha_type) {
case 'math':
verify_math_captcha();
break;
case 'recaptcha':
verify_recaptcha();
break;
case 'hcaptcha':
verify_hcaptcha();
break;
case 'turnstile':
verify_turnstile();
break;
}
}
```
## 开发指南
### 本地开发环境搭建
#### 环境要求
- PHP 7.0 或更高版本
- WordPress 4.4 或更高版本
- MySQL 5.6 或更高版本
- 支持 .htaccess 的 Web 服务器Apache/Nginx
#### 安装步骤
1. 安装 WordPress
2. 将主题文件夹放置到 `wp-content/themes/argon/`
3. 在 WordPress 后台启用主题
4. 访问主题设置页面进行配置
#### 开发工具推荐
- 代码编辑器VS Code、PhpStorm
- 浏览器开发工具Chrome DevTools、Firefox Developer Tools
- 本地服务器XAMPP、MAMP、Local by Flywheel
- 版本控制Git
### 调试技巧
#### 启用 WordPress 调试模式
`wp-config.php` 中添加:
```php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
```
#### 查看错误日志
错误日志位于 `wp-content/debug.log`
#### 浏览器控制台
JavaScript 错误会显示在浏览器控制台中。使用 `console.log()` 输出调试信息:
```javascript
console.log('argonConfig:', argonConfig);
console.log('PJAX loading:', pjaxLoading);
```
#### 网络请求调试
使用浏览器开发工具的 Network 面板查看 AJAX 请求:
- 检查请求 URL 和参数
- 查看响应内容和状态码
- 分析请求耗时
#### PJAX 调试
监听 PJAX 事件输出调试信息:
```javascript
$(document).on('pjax:send', function() {
console.log('PJAX: 开始加载');
});
$(document).on('pjax:complete', function() {
console.log('PJAX: 加载完成');
});
$(document).on('pjax:error', function(xhr, textStatus, error) {
console.error('PJAX 错误:', error);
});
```
### 常见开发任务
#### 添加新的主题选项
1.`settings.php` 中添加表单字段:
```php
<tr>
<th>新选项</th>
<td>
<input type="text" name="argon_new_option"
value="<?php echo esc_attr(get_option('argon_new_option', '')); ?>" />
<p class="description">选项说明</p>
</td>
</tr>
```
2. 在需要使用的地方读取选项:
```php
$new_option = get_option('argon_new_option', '默认值');
```
#### 修改文章列表样式
文章列表有三种预览样式,对应三个模板文件:
- `template-parts/content-preview-1.php` - 标准卡片样式
- `template-parts/content-preview-2.php` - 大图样式
- `template-parts/content-preview-3.php` - 简洁列表样式
修改对应文件即可改变样式。
#### 添加自定义 CSS
在后台设置页面的"高级设置"选项卡中,有"自定义 CSS"文本框,输入的 CSS 会自动添加到页面中。
或者直接修改 `style.css` 文件。
#### 添加自定义 JavaScript
在后台设置页面的"高级设置"选项卡中,有"自定义 JavaScript"文本框。
或者在 `argontheme.js` 文件末尾添加代码。
#### 修改评论表单
评论表单在 `comments.php` 文件中定义。可以修改表单字段、布局和样式。
#### 创建新的页面模板
1. 创建新的 PHP 文件,例如 `custom-page.php`
2. 在文件开头添加模板声明:
```php
<?php
/*
Template Name: 自定义页面
*/
?>
```
3. 编写页面内容
4. 在 WordPress 后台编辑页面时,可以在"页面属性"中选择该模板
### 主题更新
#### 更新检查器
主题使用 `theme-update-checker` 库实现自动更新检查:
```php
// functions.php
require get_template_directory() . '/theme-update-checker/theme-update-checker.php';
$myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
'https://github.com/solstice23/argon-theme/',
__FILE__,
'argon'
);
```
#### 更新流程
1. 主题定期检查 GitHub 仓库的更新
2. 发现新版本后在后台显示更新提示
3. 点击更新按钮自动下载并安装新版本
4. 更新完成后自动激活
#### 手动更新
1. 下载最新版本的主题文件
2. 备份当前主题文件和数据库
3. 删除旧的主题文件夹
4. 上传新的主题文件夹
5. 在后台重新激活主题
6. 检查设置是否正常
### 多语言支持
#### 翻译文件
主题支持多语言,翻译文件位于 `languages/` 目录:
- `zh_CN.po` / `zh_CN.mo` - 简体中文
- `zh_TW.po` / `zh_TW.mo` - 繁体中文
- `en_US.po` / `en_US.mo` - 英文
- `ru_RU.po` / `ru_RU.mo` - 俄文
#### 添加新语言
1. 复制 `languages/argon.pot` 文件
2. 使用 Poedit 等工具打开并翻译
3. 保存为对应语言代码的 `.po``.mo` 文件
4. 放置到 `languages/` 目录
#### 在代码中使用翻译
PHP 中使用 `__()` 函数:
```php
echo __('文本内容', 'argon');
```
JavaScript 中使用全局翻译函数:
```javascript
// header.php 中定义翻译表
var translation = {
'确定': '<?php _e("确定", "argon"); ?>',
'取消': '<?php _e("取消", "argon"); ?>'
};
// argontheme.js 中使用
function __(text) {
return translation[text] || text;
}
alert(__('确定'));
```
## 常见问题
### 样式问题
#### 样式不生效
1. 检查浏览器缓存强制刷新Ctrl+F5
2. 在后台设置中启用"强制刷新缓存"
3. 检查 CSS 选择器优先级
4. 使用浏览器开发工具检查元素样式
#### 夜间模式颜色异常
1. 检查 CSS 变量是否正确定义
2. 确认 `html.darkmode` 类是否正确添加
3. 检查自定义 CSS 是否覆盖了夜间模式样式
#### 响应式布局错乱
1. 检查媒体查询断点
2. 确认元素宽度设置正确
3. 使用浏览器开发工具的响应式模式测试
### 功能问题
#### PJAX 加载失败
1. 检查浏览器控制台是否有 JavaScript 错误
2. 确认目标页面的 HTML 结构正确
3. 检查 PJAX 容器选择器是否匹配
4. 尝试禁用 PJAX 功能排查问题
#### 评论发送失败
1. 检查 AJAX 请求是否成功
2. 确认 nonce 验证是否通过
3. 检查验证码是否正确
4. 查看 PHP 错误日志
#### 图片懒加载不工作
1. 确认图片标签使用了 `data-src` 属性
2. 检查 Lazy Load 库是否正确加载
3. 确认懒加载功能已在后台启用
4. 检查浏览器控制台是否有错误
#### 代码高亮显示异常
1. 确认 Prism.js 库已加载
2. 检查代码块的语言类名是否正确(如 `language-javascript`
3. 确认代码高亮样式文件已加载
4. 尝试在 PJAX 加载后重新初始化高亮
### 性能问题
#### 页面加载缓慢
1. 启用资源合并功能
2. 开启图片懒加载
3. 使用 CDN 加速静态资源
4. 优化数据库查询
5. 启用服务器缓存(如 Redis、Memcached
6. 压缩图片大小
#### 内存占用过高
1. 减少同时加载的文章数量
2. 优化图片尺寸
3. 清理无用的插件和主题
4. 增加 PHP 内存限制(在 `wp-config.php` 中设置 `WP_MEMORY_LIMIT`
#### JavaScript 执行卡顿
1. 减少 DOM 操作频率
2. 使用事件委托代替多个事件监听器
3. 优化瀑布流布局计算
4. 使用 `requestAnimationFrame` 优化动画
### 兼容性问题
#### 插件冲突
1. 逐个禁用插件排查冲突源
2. 检查插件是否修改了主题依赖的 WordPress 核心功能
3. 查看插件和主题的 JavaScript 是否有命名冲突
4. 联系插件作者或主题作者寻求解决方案
#### 浏览器兼容性
主题主要支持现代浏览器:
- Chrome 60+
- Firefox 60+
- Safari 12+
- Edge 79+
不支持 IE 浏览器。如需支持旧版浏览器,需要添加 polyfill。
#### PHP 版本兼容性
主题要求 PHP 7.0+。如果服务器 PHP 版本过低,需要升级 PHP 版本。
## 最佳实践
### 代码组织
#### 模块化开发
将功能拆分为独立的模块,便于维护和复用:
```javascript
// 评论模块
let CommentModule = {
init: function() {
this.bindEvents();
},
bindEvents: function() {
$('#comment-submit').on('click', this.submitComment);
},
submitComment: function() {
// 提交评论逻辑
}
};
// 初始化
CommentModule.init();
```
#### 避免全局污染
使用立即执行函数表达式IIFE封装代码
```javascript
(function($) {
'use strict';
// 私有变量和函数
let privateVar = 'value';
function privateFunction() {
// ...
}
// 公开接口
window.MyModule = {
publicMethod: function() {
// ...
}
};
})(jQuery);
```
#### 使用命名空间
避免函数名冲突:
```javascript
let ArgonTheme = ArgonTheme || {};
ArgonTheme.Utils = {
getCookie: function(name) {
// ...
},
setCookie: function(name, value) {
// ...
}
};
```
### 性能优化
#### 减少 HTTP 请求
1. 合并 CSS 和 JavaScript 文件
2. 使用 CSS Sprites 合并小图标
3. 使用字体图标代替图片图标
4. 启用浏览器缓存
#### 优化资源加载
1. 异步加载非关键 JavaScript
2. 延迟加载图片和视频
3. 使用 WebP 格式图片
4. 压缩和混淆 JavaScript 代码
#### 数据库优化
1. 使用索引加速查询
2. 避免 N+1 查询问题
3. 使用对象缓存(如 Redis
4. 定期清理无用数据
#### 前端优化
1. 减少 DOM 操作
2. 使用 CSS3 动画代替 JavaScript 动画
3. 避免强制同步布局
4. 使用虚拟滚动处理长列表
### 安全实践
#### 输入验证
1. 验证所有用户输入
2. 使用白名单而非黑名单
3. 限制输入长度和格式
4. 防止 SQL 注入和 XSS 攻击
#### 输出转义
1. 使用 `esc_html()` 转义 HTML 内容
2. 使用 `esc_attr()` 转义 HTML 属性
3. 使用 `esc_url()` 转义 URL
4. 使用 `esc_js()` 转义 JavaScript 字符串
#### 权限控制
1. 检查用户权限后再执行敏感操作
2. 使用 `current_user_can()` 验证权限
3. 为 AJAX 请求添加 nonce 验证
4. 限制文件上传类型和大小
#### 数据保护
1. 使用 HTTPS 加密传输
2. 敏感数据加密存储
3. 定期备份数据库
4. 设置合理的文件权限
### 可维护性
#### 代码注释
1. 为复杂逻辑添加注释
2. 使用 JSDoc 格式注释函数
3. 注释应说明"为什么"而非"是什么"
4. 保持注释与代码同步更新
#### 版本控制
1. 使用 Git 管理代码
2. 编写清晰的提交信息
3. 使用分支管理功能开发
4. 定期合并和清理分支
#### 文档编写
1. 维护完整的开发文档
2. 记录 API 接口和参数
3. 提供使用示例
4. 更新变更日志
#### 代码审查
1. 定期审查代码质量
2. 检查是否遵循编码规范
3. 识别潜在的性能问题
4. 确保代码可读性
## 扩展开发
### 创建子主题
如果需要大量自定义修改,建议创建子主题:
1. 创建子主题目录 `wp-content/themes/argon-child/`
2. 创建 `style.css`
```css
/*
Theme Name: Argon Child
Template: argon
Version: 1.0.0
*/
```
3. 创建 `functions.php`
```php
<?php
function argon_child_enqueue_styles() {
wp_enqueue_style('argon-parent-style', get_template_directory_uri() . '/style.css');
}
add_action('wp_enqueue_scripts', 'argon_child_enqueue_styles');
```
4. 在 WordPress 后台启用子主题
5. 在子主题中覆盖父主题的模板文件或添加新功能
### 开发插件扩展
为主题开发配套插件:
```php
<?php
/*
Plugin Name: Argon Extension
Description: Argon 主题扩展插件
Version: 1.0.0
*/
// 添加新功能
function argon_extension_feature() {
// 功能代码
}
add_action('init', 'argon_extension_feature');
// 添加短代码
function argon_custom_shortcode($atts) {
return '<div class="custom-content">自定义内容</div>';
}
add_shortcode('argon_custom', 'argon_custom_shortcode');
```
### 自定义 Widget
创建自定义侧边栏小工具:
```php
<?php
class Argon_Custom_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'argon_custom_widget',
'Argon 自定义小工具',
array('description' => '自定义小工具描述')
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
echo $args['before_title'];
echo esc_html($instance['title']);
echo $args['after_title'];
// 小工具内容
echo '<div class="custom-widget-content">';
echo esc_html($instance['content']);
echo '</div>';
echo $args['after_widget'];
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : '';
$content = !empty($instance['content']) ? $instance['content'] : '';
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">标题:</label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"
name="<?php echo $this->get_field_name('title'); ?>"
type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('content'); ?>">内容:</label>
<textarea class="widefat" id="<?php echo $this->get_field_id('content'); ?>"
name="<?php echo $this->get_field_name('content'); ?>"><?php echo esc_textarea($content); ?></textarea>
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = sanitize_text_field($new_instance['title']);
$instance['content'] = sanitize_text_field($new_instance['content']);
return $instance;
}
}
function register_argon_custom_widget() {
register_widget('Argon_Custom_Widget');
}
add_action('widgets_init', 'register_argon_custom_widget');
```
### 添加自定义短代码
创建可在文章中使用的短代码:
```php
// 简单短代码
function argon_alert_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'type' => 'info',
'title' => ''
), $atts);
$output = '<div class="alert alert-' . esc_attr($atts['type']) . '">';
if (!empty($atts['title'])) {
$output .= '<h4>' . esc_html($atts['title']) . '</h4>';
}
$output .= do_shortcode($content);
$output .= '</div>';
return $output;
}
add_shortcode('alert', 'argon_alert_shortcode');
// 使用方式:
// [alert type="warning" title="注意"]这是警告内容[/alert]
```
### 自定义文章类型
除了说说,还可以创建其他自定义文章类型:
```php
function register_custom_post_type() {
$args = array(
'labels' => array(
'name' => '作品集',
'singular_name' => '作品'
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'portfolio'),
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'menu_icon' => 'dashicons-portfolio'
);
register_post_type('portfolio', $args);
}
add_action('init', 'register_custom_post_type');
```
### 添加自定义字段
为文章添加额外的元数据:
```php
// 添加元框
function argon_add_custom_meta_box() {
add_meta_box(
'argon_custom_meta',
'自定义字段',
'argon_custom_meta_box_callback',
'post',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'argon_add_custom_meta_box');
// 元框内容
function argon_custom_meta_box_callback($post) {
wp_nonce_field('argon_save_custom_meta', 'argon_custom_meta_nonce');
$value = get_post_meta($post->ID, '_argon_custom_field', true);
?>
<label for="argon_custom_field">自定义字段:</label>
<input type="text" id="argon_custom_field" name="argon_custom_field"
value="<?php echo esc_attr($value); ?>" style="width: 100%;">
<?php
}
// 保存元数据
function argon_save_custom_meta($post_id) {
if (!isset($_POST['argon_custom_meta_nonce'])) {
return;
}
if (!wp_verify_nonce($_POST['argon_custom_meta_nonce'], 'argon_save_custom_meta')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['argon_custom_field'])) {
update_post_meta(
$post_id,
'_argon_custom_field',
sanitize_text_field($_POST['argon_custom_field'])
);
}
}
add_action('save_post', 'argon_save_custom_meta');
```
## 测试与部署
### 本地测试
#### 功能测试
1. 测试所有页面模板是否正常显示
2. 测试评论发送、回复、编辑功能
3. 测试说说发布和显示
4. 测试 PJAX 页面切换
5. 测试夜间模式切换
6. 测试响应式布局在不同设备上的表现
7. 测试表单验证和错误提示
#### 兼容性测试
1. 在不同浏览器中测试Chrome、Firefox、Safari、Edge
2. 测试移动端浏览器iOS Safari、Android Chrome
3. 测试不同屏幕尺寸的显示效果
4. 测试与常用插件的兼容性
#### 性能测试
1. 使用 Chrome DevTools 的 Lighthouse 进行性能评分
2. 检查页面加载时间
3. 分析资源加载瀑布图
4. 测试大量数据时的性能表现
### 部署流程
#### 准备工作
1. 备份当前网站数据和数据库
2. 检查服务器环境是否满足要求
3. 准备主题文件和配置
#### 上传主题
1. 通过 FTP 上传主题文件到 `wp-content/themes/argon/`
2. 或在 WordPress 后台上传主题 ZIP 包
3. 确认文件权限正确(目录 755文件 644
#### 配置主题
1. 在 WordPress 后台启用主题
2. 访问主题设置页面进行配置
3. 设置主题色、布局等基本选项
4. 配置评论系统和验证码
5. 设置 AI 摘要服务(如需要)
6. 配置性能优化选项
#### 数据迁移
如果从其他主题迁移:
1. 导出原主题的设置和数据
2. 手动迁移必要的配置
3. 检查文章格式是否正常
4. 重新设置小工具和菜单
5. 测试所有功能是否正常
#### 上线检查
1. 清除所有缓存浏览器、CDN、服务器
2. 检查首页和主要页面显示
3. 测试评论功能
4. 检查移动端显示
5. 验证 SEO 设置
6. 测试表单提交
7. 检查 HTTPS 证书
### 维护与监控
#### 日常维护
1. 定期备份网站数据和数据库
2. 及时更新主题版本
3. 更新 WordPress 核心和插件
4. 清理垃圾评论和无用数据
5. 优化数据库表
#### 性能监控
1. 监控网站加载速度
2. 检查服务器资源使用情况
3. 分析访问日志
4. 监控错误日志
5. 定期进行性能测试
#### 安全维护
1. 定期更新所有组件
2. 检查文件完整性
3. 监控异常登录尝试
4. 定期更改管理员密码
5. 检查用户权限设置
6. 扫描恶意代码
#### 故障排查
当出现问题时:
1. 查看 WordPress 调试日志
2. 检查 PHP 错误日志
3. 查看浏览器控制台错误
4. 检查服务器错误日志
5. 禁用插件逐个排查
6. 切换到默认主题测试
7. 检查数据库连接
8. 验证文件权限
## 参考资源
### 官方文档
- WordPress Codexhttps://codex.wordpress.org/
- WordPress Developer Resourceshttps://developer.wordpress.org/
- Bootstrap 4 文档https://getbootstrap.com/docs/4.6/
- Argon Design Systemhttps://www.creative-tim.com/product/argon-design-system
### 开发工具
- WordPress Debug Bar调试插件
- Query Monitor性能监控插件
- Theme Check主题检查插件
- WP-CLIWordPress 命令行工具
### 学习资源
- WordPress 主题开发手册
- PHP 官方文档
- JavaScript MDN 文档
- CSS-Tricks 网站
### 社区支持
- GitHub Issueshttps://github.com/solstice23/argon-theme/issues
- WordPress 中文论坛
- Stack Overflow
## 附录
### 常用 WordPress 函数
#### 文章相关
```php
the_title() // 输出文章标题
the_content() // 输出文章内容
the_excerpt() // 输出文章摘要
the_permalink() // 输出文章链接
the_post_thumbnail() // 输出特色图片
get_the_date() // 获取发布日期
get_the_author() // 获取作者名称
```
#### 评论相关
```php
comments_number() // 输出评论数量
wp_list_comments() // 输出评论列表
comment_form() // 输出评论表单
get_comment_author() // 获取评论作者
comment_text() // 输出评论内容
```
#### 选项相关
```php
get_option() // 获取选项值
update_option() // 更新选项值
delete_option() // 删除选项
add_option() // 添加选项
```
#### 用户相关
```php
is_user_logged_in() // 检查用户是否登录
current_user_can() // 检查用户权限
get_current_user_id() // 获取当前用户 ID
wp_get_current_user() // 获取当前用户对象
```
### 常用 jQuery 方法
```javascript
// 选择器
$('#id') // ID 选择器
$('.class') // 类选择器
$('element') // 元素选择器
// DOM 操作
.html() // 获取或设置 HTML 内容
.text() // 获取或设置文本内容
.val() // 获取或设置表单值
.attr() // 获取或设置属性
.css() // 获取或设置样式
.addClass() // 添加类
.removeClass() // 移除类
.toggleClass() // 切换类
// 事件
.on() // 绑定事件
.off() // 解绑事件
.click() // 点击事件
.change() // 改变事件
.submit() // 提交事件
// AJAX
$.ajax() // AJAX 请求
$.get() // GET 请求
$.post() // POST 请求
```
### 常用 CSS 类
Argon 主题基于 Bootstrap 4可以使用以下常用类
```css
/* 布局 */
.container // 容器
.row //
.col-* //
/* 间距 */
.m-* // margin
.p-* // padding
.mt-*, .mb-*, .ml-*, .mr-* // 单边间距
/* 文本 */
.text-center // 居中对齐
.text-left // 左对齐
.text-right // 右对齐
.text-primary // 主色文本
.text-muted // 灰色文本
/* 按钮 */
.btn // 按钮基类
.btn-primary // 主按钮
.btn-secondary // 次按钮
.btn-sm, .btn-lg // 按钮尺寸
/* 卡片 */
.card // 卡片
.card-body // 卡片内容
.card-header // 卡片头部
.card-footer // 卡片底部
```
### 主题钩子列表
Argon 主题提供的自定义钩子:
```php
// 动作钩子
do_action('argon_before_header') // 头部之前
do_action('argon_after_header') // 头部之后
do_action('argon_before_content') // 内容之前
do_action('argon_after_content') // 内容之后
do_action('argon_before_footer') // 底部之前
do_action('argon_after_footer') // 底部之后
do_action('argon_before_comment') // 评论之前
do_action('argon_after_comment') // 评论之后
// 过滤钩子
apply_filters('argon_post_content', $content) // 文章内容
apply_filters('argon_comment_content', $content) // 评论内容
apply_filters('argon_excerpt_length', 200) // 摘要长度
apply_filters('argon_theme_color', $color) // 主题色
```
使用示例:
```php
// 在头部之后添加内容
function custom_after_header() {
echo '<div class="custom-notice">自定义通知</div>';
}
add_action('argon_after_header', 'custom_after_header');
// 修改摘要长度
function custom_excerpt_length($length) {
return 150;
}
add_filter('argon_excerpt_length', 'custom_excerpt_length');
```
### 版本历史
- v1.5.0 - 当前版本
- 添加 AI 摘要功能
- 优化性能和缓存机制
- 改进安全性
- 修复已知问题
- v1.4.x - 功能增强
- 添加说说功能
- 改进评论系统
- 优化移动端体验
- v1.3.x - 稳定版本
- 完善 PJAX 功能
- 添加多种文章列表样式
- 改进夜间模式
- v1.2.x - 初始版本
- 基础功能实现
- Material Design 界面
- 响应式布局
## 结语
本文档详细介绍了 Argon 主题的架构、核心功能、开发规范和最佳实践。通过学习本文档,开发者应该能够:
1. 理解主题的整体架构和文件组织
2. 掌握核心功能的实现原理
3. 遵循统一的代码规范进行开发
4. 独立完成主题的定制和扩展
5. 解决常见的开发和部署问题
在实际开发过程中,建议:
1. 始终遵循代码规范,保持代码整洁
2. 充分测试功能,确保兼容性和稳定性
3. 注重性能优化,提升用户体验
4. 重视安全性,防范潜在风险
5. 保持代码可维护性,便于后续迭代
如有问题或建议,欢迎通过 GitHub Issues 反馈。
---
文档版本1.0.0
最后更新2026-01-31
维护者Argon Theme Development Team