前提为了实现WordPress主题评论框原生支持Markdown,需要在主题的functions.php中添加处理函数,并在评论框附近添加说明。
首先下载 Markdown 解析器,下载这个文件放置于主题的目录:
👉 https://raw.githubusercontent.com/erusev/parsedown/master/Parsedown.php
/wp-content/themes/你的主题/Parsedown.php
下面步入正题简单版和美化版,一共两个版本。
1.简单版完整代码实现:
首先在主题的functions.php中添加以下代码:
/**
* WordPress评论Markdown支持
* 在主题的functions.php中添加此代码
*/
// 启用评论Markdown支持
function enable_comment_markdown() {
// 添加Markdown解析器
if ( !function_exists('wpautop') ) {
require_once(ABSPATH . WPINC . '/formatting.php');
}
// 在评论保存前解析Markdown
add_filter('preprocess_comment', 'markdown_comment_preprocess');
// 在评论显示前应用Markdown
add_filter('comment_text', 'markdown_comment_text', 7); // 优先级低于wpautop但高于其他过滤器
// 添加评论框说明
add_action('comment_form', 'add_markdown_comment_notice');
// 添加评论框快捷键提示
add_action('wp_footer', 'add_markdown_comment_shortcuts');
// 加载Markdown解析器库
if ( !class_exists('Parsedown') ) {
require_once get_template_directory() . '/Parsedown.php';
}
}
// 预处理评论(防止XSS攻击)
function markdown_comment_preprocess($commentdata) {
// 如果评论不是垃圾评论,检查内容
if ( $commentdata['comment_content'] && !wp_blacklist_check($commentdata['comment_author'], $commentdata['comment_author_email'], $commentdata['comment_author_url'], $commentdata['comment_content'], $commentdata['comment_author_IP'], $commentdata['comment_agent']) ) {
// 保存原始Markdown内容到自定义字段
$commentdata['comment_content'] = wp_strip_all_tags($commentdata['comment_content']);
}
return $commentdata;
}
// 将Markdown转换为HTML
function markdown_comment_text($content) {
// 确保只转换评论内容
if ( doing_filter('comment_text') ) {
$Parsedown = new Parsedown();
// 设置安全模式以防止XSS
$Parsedown->setSafeMode(true);
// 启用Markdown解析
$content = $Parsedown->text($content);
// 应用wpautop以获得正确的段落格式
$content = wpautop($content);
}
return $content;
}
// 在评论框上方添加说明
function add_markdown_comment_notice() {
echo '<p class="comment-markdown-notice">';
echo '<strong>Markdown支持:</strong> ';
echo '*斜体* **粗体** `代码` [链接](url) > 引用 - 列表 # 标题 1/2/3';
echo ' <a href="#" onclick="return show_markdown_help();" style="float:right;">更多格式</a>';
echo '</p>';
// 添加帮助面板(隐藏状态)
echo '<div id="markdown-help-panel" style="display:none; background:#f9f9f9; padding:15px; margin:10px 0; border:1px solid #ddd; border-radius:4px;">';
echo '<h4>Markdown 格式指南</h4>';
echo '<table style="width:100%; border-collapse:collapse;">';
echo '<tr><th style="width:30%;">输入</th><th>效果</th></tr>';
echo '<tr><td><code>**粗体**</code></td><td><strong>粗体</strong></td></tr>';
echo '<tr><td><code>*斜体*</code> 或 <code>_斜体_</code></td><td><em>斜体</em></td></tr>';
echo '<tr><td><code>`代码`</code></td><td><code>代码</code></td></tr>';
echo '<tr><td><code>```语言<br>代码块<br>```</code></td><td>代码块(支持语法高亮)</td></tr>';
echo '<tr><td><code>[链接文字](http://example.com)</code></td><td><a href="#">链接</a></td></tr>';
echo '<tr><td><code></code></td><td>图片</td></tr>';
echo '<tr><td><code>> 引用文字</code></td><td>引用样式</td></tr>';
echo '<tr><td><code>- 列表项</code></td><td>无序列表</td></tr>';
echo '<tr><td><code>1. 列表项</code></td><td>有序列表</td></tr>';
echo '<tr><td><code># 标题1</code></td><td><h1>标题1</h1>(谨慎使用)</td></tr>';
echo '<tr><td><code>## 标题2</code></td><td><h2>标题2</h2></td></tr>';
echo '<tr><td><code>### 标题3</code></td><td><h3>标题3</h3></td></tr>';
echo '<tr><td><code>---</code></td><td>水平分割线</td></tr>';
echo '</table>';
echo '<p style="text-align:right;"><a href="#" onclick="return hide_markdown_help();">关闭</a></p>';
echo '</div>';
}
// 添加快捷键提示和帮助面板切换脚本
function add_markdown_comment_shortcuts() {
if ( is_singular() ) : ?>
<script type="text/javascript">
// Markdown帮助面板显示/隐藏
function show_markdown_help() {
document.getElementById('markdown-help-panel').style.display = 'block';
return false;
}
function hide_markdown_help() {
document.getElementById('markdown-help-panel').style.display = 'none';
return false;
}
// 评论框Markdown快捷键
document.addEventListener('DOMContentLoaded', function() {
var commentField = document.getElementById('comment');
if (!commentField) return;
commentField.addEventListener('keydown', function(e) {
// Ctrl+B 或 Cmd+B: 粗体
if ((e.ctrlKey || e.metaKey) && e.key === 'b') {
e.preventDefault();
insertMarkdown(this, '**', '**', '粗体');
}
// Ctrl+I 或 Cmd+I: 斜体
if ((e.ctrlKey || e.metaKey) && e.key === 'i') {
e.preventDefault();
insertMarkdown(this, '*', '*', '斜体');
}
// Ctrl+K 或 Cmd+K: 链接
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
var url = prompt('请输入链接URL:', 'http://');
if (url) {
var text = prompt('请输入链接文字:', '链接文字');
if (text) {
insertText(this, '[' + text + '](' + url + ')');
}
}
}
// Ctrl+` 或 Cmd+`: 代码
if ((e.ctrlKey || e.metaKey) && e.key === '`') {
e.preventDefault();
insertMarkdown(this, '`', '`', '代码');
}
});
// 插入Markdown标签
function insertMarkdown(field, prefix, suffix, defaultText) {
var start = field.selectionStart;
var end = field.selectionEnd;
var text = field.value;
var selected = text.substring(start, end) || defaultText;
field.value = text.substring(0, start) + prefix + selected + suffix + text.substring(end);
// 设置光标位置
if (text.substring(start, end)) {
field.setSelectionRange(start + prefix.length, end + prefix.length);
} else {
field.setSelectionRange(start + prefix.length, start + prefix.length + defaultText.length);
}
field.focus();
}
function insertText(field, textToInsert) {
var start = field.selectionStart;
var end = field.selectionEnd;
var text = field.value;
field.value = text.substring(0, start) + textToInsert + text.substring(end);
field.setSelectionRange(start + textToInsert.length, start + textToInsert.length);
field.focus();
}
});
</script>
<?php endif;
}
// 如果存在Parsedown类,加载它
if ( !class_exists('Parsedown') ) {
class Parsedown {
// 简化的Parsedown实现或要求用户安装
// 建议从 https://github.com/erusev/parsedown 下载完整版本
public function setSafeMode($mode) {
$this->safeMode = $mode;
return $this;
}
public function text($text) {
// 基本的Markdown解析(简化版)
// 注意:这只是一个基本实现,建议使用完整的Parsedown库
// 转义HTML标签(安全模式)
if ($this->safeMode) {
$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
// 简单的Markdown转换
$text = preg_replace('/\*\*(.+?)\*\*/s', '<strong>$1</strong>', $text);
$text = preg_replace('/\*(.+?)\*/s', '<em>$1</em>', $text);
$text = preg_replace('/__(.+?)__/s', '<strong>$1</strong>', $text);
$text = preg_replace('/_(.+?)_/s', '<em>$1</em>', $text);
$text = preg_replace('/`(.+?)`/s', '<code>$1</code>', $text);
$text = preg_replace('/\[(.+?)\]\((.+?)\)/s', '<a href="$2" rel="nofollow">$1</a>', $text);
// 简化版的引用
$lines = explode("\n", $text);
$inBlockquote = false;
$output = '';
foreach ($lines as $line) {
if (preg_match('/^> (.+)/', $line, $matches)) {
if (!$inBlockquote) {
$output .= '<blockquote>';
$inBlockquote = true;
}
$output .= $matches[1] . "<br>";
} else {
if ($inBlockquote) {
$output = rtrim($output, "<br>") . '</blockquote>';
$inBlockquote = false;
}
$output .= $line . "\n";
}
}
if ($inBlockquote) {
$output .= '</blockquote>';
}
return $output;
}
}
}
// 初始化
add_action('init', 'enable_comment_markdown');
在主题中添加CSS样式(可选,添加到style.css):
/* Markdown评论样式 */
.comment-markdown-notice {
background: #f5f5f5;
padding: 8px 12px;
border-radius: 4px;
margin: 10px 0;
font-size: 13px;
color: #666;
border-left: 3px solid #0073aa;
}
.comment-markdown-notice a {
color: #0073aa;
text-decoration: none;
}
.comment-markdown-notice a:hover {
text-decoration: underline;
}
#markdown-help-panel {
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 15px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
#markdown-help-panel h4 {
margin-top: 0;
color: #333;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
#markdown-help-panel table {
font-size: 13px;
}
#markdown-help-panel th {
text-align: left;
background: #f5f5f5;
padding: 8px;
}
#markdown-help-panel td {
padding: 8px;
border-bottom: 1px solid #eee;
}
#markdown-help-panel code {
background: #f0f0f0;
padding: 2px 5px;
border-radius: 3px;
font-size: 12px;
}
/* 评论内容中的Markdown样式 */
.comment-content code {
background: #f0f0f0;
padding: 2px 5px;
border-radius: 3px;
font-family: Consolas, Monaco, 'Courier New', monospace;
}
.comment-content pre {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
border: 1px solid #ddd;
}
.comment-content pre code {
background: none;
padding: 0;
}
.comment-content blockquote {
border-left: 4px solid #0073aa;
margin: 10px 0;
padding: 10px 15px;
background: #f9f9f9;
font-style: italic;
}
.comment-content h1,
.comment-content h2,
.comment-content h3 {
margin: 1em 0 0.5em;
}
.comment-content ul,
.comment-content ol {
margin: 0 0 1em 2em;
}
.comment-content hr {
border: 0;
height: 1px;
background: #ddd;
margin: 20px 0;
}
至此简单版实现WordPress评论框原生支持Markdown代码功能,这样评论框就能完整支持Markdown语法,包括代码块、表格等高级功能。
2.美化版继续搞起
以下代码粘贴复制在主题的functions.php内
/**
* WordPress评论Markdown支持
* 在主题的functions.php中添加此代码
*/
// 启用评论Markdown支持
function enable_comment_markdown() {
// 添加Markdown解析器
if ( !function_exists('wpautop') ) {
require_once(ABSPATH . WPINC . '/formatting.php');
}
// 在评论保存前解析Markdown
add_filter('preprocess_comment', 'markdown_comment_preprocess');
// 在评论显示前应用Markdown
add_filter('comment_text', 'markdown_comment_text', 7);
// 在评论框上方添加说明 - 同时支持登录和未登录用户
add_action('comment_form_top', 'add_markdown_comment_notice');
// 添加评论框快捷键提示(在页脚加载)
add_action('wp_footer', 'add_markdown_comment_scripts');
// 加载Markdown解析器库
if ( !class_exists('Parsedown') ) {
$parsedown_path = get_template_directory() . '/Parsedown.php';
if (file_exists($parsedown_path)) {
require_once $parsedown_path;
}
}
}
// 预处理评论(防止XSS攻击)
function markdown_comment_preprocess($commentdata) {
// 如果评论不是垃圾评论,检查内容
if ( isset($commentdata['comment_content']) && !wp_blacklist_check($commentdata['comment_author'], $commentdata['comment_author_email'], $commentdata['comment_author_url'], $commentdata['comment_content'], $commentdata['comment_author_IP'], $commentdata['comment_agent']) ) {
// 清理内容但保留Markdown语法
$commentdata['comment_content'] = wp_strip_all_tags($commentdata['comment_content'], true);
}
return $commentdata;
}
// 将Markdown转换为HTML
function markdown_comment_text($content) {
// 确保只转换评论内容
if ( doing_filter('comment_text') && !empty($content) ) {
// 检查Parsedown类是否存在
if ( class_exists('Parsedown') ) {
$Parsedown = new Parsedown();
// 设置安全模式以防止XSS
$Parsedown->setSafeMode(true);
// 启用Markdown解析
$content = $Parsedown->text($content);
} else {
// 降级处理:如果没有Parsedown,使用基本Markdown解析
$content = basic_markdown_parse($content);
}
// 应用wpautop以获得正确的段落格式
$content = wpautop($content);
}
return $content;
}
// 基本Markdown解析函数(降级方案)
function basic_markdown_parse($text) {
if (empty($text)) return $text;
// 转义HTML标签(安全模式)
$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
// 处理代码块 (必须优先处理)
$text = preg_replace_callback('/```(.*?)\n(.*?)```/s', function($matches) {
$language = trim($matches[1]);
$code = htmlspecialchars($matches[2], ENT_QUOTES, 'UTF-8');
$lang_class = $language ? ' class="language-' . $language . '"' : '';
return '<pre><code' . $lang_class . '>' . $code . '</code></pre>';
}, $text);
// 处理行内代码
$text = preg_replace('/`(.*?)`/', '<code>$1</code>', $text);
// 处理粗体和斜体
$text = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $text);
$text = preg_replace('/__(.*?)__/', '<strong>$1</strong>', $text);
$text = preg_replace('/\*(.*?)\*/', '<em>$1</em>', $text);
$text = preg_replace('/_(.*?)_/', '<em>$1</em>', $text);
$text = preg_replace('/~~(.*?)~~/', '<del>$1</del>', $text);
// 处理链接
$text = preg_replace('/\[(.*?)\]\((.*?)\)/', '<a href="$2" rel="nofollow">$1</a>', $text);
// 处理图片
$text = preg_replace('/!\[(.*?)\]\((.*?)\)/', '<img src="$2" alt="$1" style="max-width:100%;height:auto;">', $text);
// 处理引用
$lines = explode("\n", $text);
$inBlockquote = false;
$output = '';
foreach ($lines as $line) {
if (preg_match('/^> (.*)/', $line, $matches)) {
if (!$inBlockquote) {
$output .= '<blockquote>';
$inBlockquote = true;
}
$output .= $matches[1] . "<br>";
} else {
if ($inBlockquote) {
$output = rtrim($output, "<br>") . '</blockquote>';
$inBlockquote = false;
}
$output .= $line . "\n";
}
}
if ($inBlockquote) {
$output .= '</blockquote>';
}
// 处理标题
$output = preg_replace('/^###### (.*?)$/m', '<h6>$1</h6>', $output);
$output = preg_replace('/^##### (.*?)$/m', '<h5>$1</h5>', $output);
$output = preg_replace('/^#### (.*?)$/m', '<h4>$1</h4>', $output);
$output = preg_replace('/^### (.*?)$/m', '<h3>$1</h3>', $output);
$output = preg_replace('/^## (.*?)$/m', '<h2>$1</h2>', $output);
$output = preg_replace('/^# (.*?)$/m', '<h1>$1</h1>', $output);
// 处理水平线
$output = preg_replace('/^---$/m', '<hr>', $output);
$output = preg_replace('/^\*\*\*$/m', '<hr>', $output);
$output = preg_replace('/^___$/m', '<hr>', $output);
return $output;
}
// 在评论框上方添加说明(兼容所有浏览器)
function add_markdown_comment_notice() {
// 获取当前文章ID
$post_id = get_the_ID();
if (!$post_id) return;
?>
<div class="comment-markdown-wrapper" id="markdown-wrapper-<?php echo $post_id; ?>">
<div class="comment-markdown-notice">
<div class="markdown-badges">
<span class="markdown-badge" data-markdown="bold" title="粗体 Ctrl+B"><strong>B</strong></span>
<span class="markdown-badge" data-markdown="italic" title="斜体 Ctrl+I"><em>I</em></span>
<span class="markdown-badge" data-markdown="link" title="链接 Ctrl+K">🔗</span>
<span class="markdown-badge" data-markdown="code" title="代码 Ctrl+`"><code></></code></span>
<span class="markdown-badge" data-markdown="quote" title="引用">❝</span>
<span class="markdown-badge" data-markdown="list" title="列表">•</span>
<span class="markdown-badge" data-markdown="heading" title="标题">H</span>
<span class="markdown-badge" data-markdown="image" title="图片">🖼️</span>
<span class="markdown-badge" data-markdown="codeblock" title="代码块">```</span>
<span class="markdown-badge" data-markdown="strikethrough" title="删除线 Ctrl+D">~~</span>
</div>
<div class="markdown-shortcuts">
<span class="shortcut-key"><kbd>Ctrl</kbd>+<kbd>B</kbd></span>
<span class="shortcut-key"><kbd>Ctrl</kbd>+<kbd>I</kbd></span>
<span class="shortcut-key"><kbd>Ctrl</kbd>+<kbd>K</kbd></span>
<span class="shortcut-key"><kbd>Ctrl</kbd>+<kbd>`</kbd></span>
<span class="shortcut-key"><kbd>Ctrl</kbd>+<kbd>D</kbd></span>
<a href="#" onclick="return false;" class="markdown-help-link" id="markdown-help-toggle">格式指南</a>
</div>
</div>
<!-- 帮助面板(初始隐藏) -->
<div id="markdown-help-panel" style="display:none;">
<h4>Markdown 格式指南</h4>
<div class="help-grid">
<div class="help-item">
<code>**粗体**</code> → <strong>粗体</strong>
</div>
<div class="help-item">
<code>*斜体*</code> → <em>斜体</em>
</div>
<div class="help-item">
<code>`代码`</code> → <code>代码</code>
</div>
<div class="help-item">
<code>~~删除线~~</code> → <del>删除线</del>
</div>
<div class="help-item">
<code>[链接](url)</code> → <a href="#">链接</a>
</div>
<div class="help-item">
<code></code> → 图片
</div>
<div class="help-item">
<code>> 引用</code> → 引用样式
</div>
<div class="help-item">
<code>- 列表</code> → 无序列表
</div>
<div class="help-item">
<code>1. 列表</code> → 有序列表
</div>
<div class="help-item">
<code># 标题</code> → 标题1
</div>
<div class="help-item">
<code>## 标题</code> → 标题2
</div>
<div class="help-item">
<code>```代码块```</code> → 代码块
</div>
<div class="help-item">
<code>---</code> → 分割线
</div>
</div>
<p style="text-align:right; margin-bottom:0;">
<a href="#" onclick="return false;" class="markdown-help-close">关闭</a>
</p>
</div>
</div>
<!-- 非侵入式浏览器检测脚本(仅用于功能降级) -->
<script type="text/javascript">
(function() {
// 检测浏览器特性而不是特定浏览器
var isIE = /*@cc_on!@*/false || !!document.documentMode;
var isEdge = !isIE && !!window.StyleMedia;
var isOldBrowser = !document.addEventListener || !window.JSON;
// 如果是IE或旧浏览器,添加标识类
if (isIE || isOldBrowser) {
document.documentElement.className += ' old-browser';
}
})();
</script>
<?php
}
// 添加所有JavaScript脚本(兼容所有浏览器)
function add_markdown_comment_scripts() {
if ( !is_singular() ) return;
// 使用内联脚本确保最大兼容性
?>
<script type="text/javascript">
(function() {
'use strict';
// 兼容旧版浏览器的事件监听函数
function addEvent(element, event, handler) {
if (element.addEventListener) {
element.addEventListener(event, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + event, handler);
} else {
element['on' + event] = handler;
}
}
// 兼容旧版浏览器的选择器函数
function $(selector, context) {
context = context || document;
if (context.querySelectorAll) {
return context.querySelectorAll(selector);
}
return [];
}
// 获取元素ID
function getElement(id) {
return document.getElementById(id) || null;
}
// 设置显示状态
function setDisplay(element, show) {
if (!element) return;
if (element.style) {
element.style.display = show ? 'block' : 'none';
}
}
// 获取选中文本
function getSelectedText(textarea) {
if (textarea.selectionStart !== undefined) {
return {
start: textarea.selectionStart,
end: textarea.selectionEnd,
text: textarea.value.substring(textarea.selectionStart, textarea.selectionEnd)
};
} else if (document.selection) { // IE兼容
var range = document.selection.createRange();
var storedRange = range.duplicate();
storedRange.moveToElementText(textarea);
storedRange.setEndPoint('EndToEnd', range);
return {
start: storedRange.text.length - range.text.length,
end: storedRange.text.length,
text: range.text
};
}
return { start: 0, end: 0, text: '' };
}
// 插入文本(兼容IE)
function insertText(textarea, textToInsert, prefix, suffix, defaultText) {
var value = textarea.value;
var selected = getSelectedText(textarea);
var newText;
if (prefix !== undefined && suffix !== undefined) {
var insertText = selected.text || defaultText || '';
newText = value.substring(0, selected.start) + prefix + insertText + suffix + value.substring(selected.end);
} else {
newText = value.substring(0, selected.start) + textToInsert + value.substring(selected.end);
}
textarea.value = newText;
// 设置光标位置
try {
var newCursorPos = selected.start + (textToInsert ? textToInsert.length : (prefix.length + (selected.text || defaultText || '').length + suffix.length));
if (textarea.setSelectionRange) {
textarea.setSelectionRange(newCursorPos, newCursorPos);
} else if (textarea.createTextRange) { // IE兼容
var range = textarea.createTextRange();
range.collapse(true);
range.moveEnd('character', newCursorPos);
range.moveStart('character', selected.start);
range.select();
}
} catch (e) {}
textarea.focus();
}
// 页面加载完成后执行
function initMarkdown() {
var commentField = getElement('comment');
if (!commentField) {
// 如果评论框不存在,延迟再次尝试
setTimeout(initMarkdown, 500);
return;
}
var helpPanel = getElement('markdown-help-panel');
var helpToggle = getElement('markdown-help-toggle');
var helpClose = document.querySelector('.markdown-help-close');
// 帮助面板切换
if (helpToggle && helpPanel) {
addEvent(helpToggle, 'click', function(e) {
if (e.preventDefault) e.preventDefault();
setDisplay(helpPanel, helpPanel.style.display !== 'block');
return false;
});
}
// 关闭帮助面板
if (helpClose && helpPanel) {
addEvent(helpClose, 'click', function(e) {
if (e.preventDefault) e.preventDefault();
setDisplay(helpPanel, false);
return false;
});
}
// 点击徽章插入Markdown
var badges = $('.markdown-badge');
for (var i = 0; i < badges.length; i++) {
(function(badge, index) {
addEvent(badge, 'click', function(e) {
if (e.preventDefault) e.preventDefault();
var type = badge.getAttribute('data-markdown') || '';
switch(type) {
case 'bold':
insertText(commentField, null, '**', '**', '粗体');
break;
case 'italic':
insertText(commentField, null, '*', '*', '斜体');
break;
case 'link':
var url = prompt('请输入链接URL:', 'https://');
if (url) {
var text = prompt('请输入链接文字:', '链接文字');
if (text) {
insertText(commentField, '[' + text + '](' + url + ')');
}
}
break;
case 'code':
insertText(commentField, null, '`', '`', '代码');
break;
case 'codeblock':
var lang = prompt('请输入代码语言 (如: php, javascript):', '');
insertText(commentField, '```' + lang + '\n\n```');
break;
case 'quote':
insertText(commentField, null, '> ', '', '引用文字');
break;
case 'list':
insertText(commentField, null, '- ', '', '列表项');
break;
case 'heading':
var level = prompt('请输入标题级别 (1-3):', '2');
var prefix = '#'.repeat(parseInt(level) || 2) + ' ';
insertText(commentField, null, prefix, '', '标题');
break;
case 'image':
var imgUrl = prompt('请输入图片URL:', 'https://');
if (imgUrl) {
var alt = prompt('请输入图片说明:', '图片');
if (alt) {
insertText(commentField, '');
}
}
break;
case 'strikethrough':
insertText(commentField, null, '~~', '~~', '删除线');
break;
}
return false;
});
})(badges[i], i);
}
// 快捷键支持
addEvent(commentField, 'keydown', function(e) {
var evt = e || window.event;
var ctrlPressed = evt.ctrlKey || evt.metaKey;
var key = evt.key || String.fromCharCode(evt.keyCode || evt.which);
if (!ctrlPressed) return;
var handled = true;
switch(key.toLowerCase()) {
case 'b':
insertText(commentField, null, '**', '**', '粗体');
break;
case 'i':
insertText(commentField, null, '*', '*', '斜体');
break;
case 'k':
var url = prompt('请输入链接URL:', 'https://');
if (url) {
var text = prompt('请输入链接文字:', '链接文字');
if (text) {
insertText(commentField, '[' + text + '](' + url + ')');
}
}
break;
case '`':
insertText(commentField, null, '`', '`', '代码');
break;
case 'd':
insertText(commentField, null, '~~', '~~', '删除线');
break;
default:
handled = false;
}
if (handled) {
if (evt.preventDefault) evt.preventDefault();
if (evt.stopPropagation) evt.stopPropagation();
return false;
}
});
}
// 等待DOM加载完成
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', initMarkdown);
} else {
// IE兼容
var oldOnload = window.onload;
window.onload = function() {
if (oldOnload) oldOnload();
initMarkdown();
};
}
})();
</script>
<?php
}
// 初始化
add_action('init', 'enable_comment_markdown');
?>
更新CSS样式(添加到主题的style.css):
/* Markdown评论框上方样式 - 兼容所有浏览器 */
.comment-markdown-wrapper {
margin-bottom: 15px;
clear: both;
}
.comment-markdown-notice {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 10px 15px;
margin: 0 0 10px 0;
zoom: 1; /* IE兼容 */
overflow: hidden; /* 清除浮动 */
font-size: 13px;
color: #495057;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
/* 徽章样式 - 使用浮动实现兼容性 */
.markdown-badges {
float: left;
margin-right: 15px;
}
.markdown-badge {
display: inline-block;
*display: inline; /* IE7兼容 */
*zoom: 1;
min-width: 28px;
height: 28px;
line-height: 26px;
text-align: center;
background: #ffffff;
border: 1px solid #ced4da;
border-radius: 4px;
color: #495057;
font-size: 13px;
cursor: pointer;
margin-right: 5px;
padding: 0 6px;
vertical-align: middle;
transition: all 0.2s ease;
}
.markdown-badge:hover {
background: #e9ecef;
border-color: #adb5bd;
}
/* 快捷键区域 */
.markdown-shortcuts {
float: right;
text-align: right;
}
.shortcut-key {
display: inline-block;
*display: inline;
*zoom: 1;
margin-left: 10px;
color: #6c757d;
font-size: 12px;
}
.shortcut-key kbd {
display: inline-block;
*display: inline;
*zoom: 1;
background: #ffffff;
border: 1px solid #ced4da;
border-radius: 3px;
padding: 2px 6px;
font-size: 11px;
font-family: Consolas, Monaco, 'Courier New', monospace;
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
margin: 0 2px;
line-height: 1.4;
}
.markdown-help-link {
display: inline-block;
*display: inline;
*zoom: 1;
color: #007bff;
text-decoration: none;
font-size: 12px;
padding: 4px 8px;
background: #e7f1ff;
border-radius: 4px;
margin-left: 10px;
}
.markdown-help-link:hover {
background: #cfe2ff;
color: #0056b3;
text-decoration: none;
}
/* 帮助面板 */
#markdown-help-panel {
background: #ffffff;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 15px;
margin: 0 0 15px 0;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
clear: both;
}
#markdown-help-panel h4 {
margin: 0 0 15px 0;
color: #333;
font-size: 16px;
border-bottom: 2px solid #007bff;
padding-bottom: 8px;
}
/* 网格布局 - 使用浮动实现兼容性 */
.help-grid {
overflow: hidden;
margin: 0 -10px;
}
.help-item {
float: left;
width: 25%;
padding: 0 10px;
margin-bottom: 12px;
box-sizing: border-box;
}
.help-item code {
display: inline-block;
*display: inline;
*zoom: 1;
background: #f1f3f5;
padding: 2px 5px;
border-radius: 3px;
font-size: 12px;
color: #d63384;
border: 1px solid #dee2e6;
margin-right: 5px;
}
/* IE6-8 兼容 */
.old-browser .help-item {
width: 24.9%;
*width: 24.9%;
}
.old-browser .markdown-badge {
filter: none;
background: #fff;
}
/* 评论内容样式 - 保持原样 */
.comment-content {
line-height: 1.6;
word-wrap: break-word;
}
.comment-content code {
background: #f1f3f5;
padding: 2px 5px;
border-radius: 3px;
font-family: Consolas, Monaco, 'Courier New', monospace;
font-size: 13px;
color: #d63384;
border: 1px solid #dee2e6;
}
.comment-content pre {
background: #f8f9fa;
padding: 12px;
border-radius: 6px;
overflow-x: auto;
border: 1px solid #dee2e6;
margin: 10px 0;
max-width: 100%;
overflow: auto;
}
.comment-content pre code {
background: none;
padding: 0;
border: none;
color: #212529;
font-size: 13px;
}
.comment-content blockquote {
border-left: 4px solid #007bff;
margin: 10px 0;
padding: 10px 15px;
background: #f8f9fa;
font-style: italic;
color: #495057;
}
.comment-content h1,
.comment-content h2,
.comment-content h3 {
margin: 1.2em 0 0.6em;
font-weight: 600;
line-height: 1.3;
}
.comment-content h1 { font-size: 1.8em; }
.comment-content h2 { font-size: 1.5em; }
.comment-content h3 { font-size: 1.3em; }
.comment-content ul,
.comment-content ol {
margin: 0 0 1em 2em;
padding: 0;
}
.comment-content hr {
border: 0;
height: 2px;
background: #dee2e6;
margin: 20px 0;
}
.comment-content table {
border-collapse: collapse;
width: 100%;
margin: 10px 0;
}
.comment-content th,
.comment-content td {
border: 1px solid #dee2e6;
padding: 8px;
text-align: left;
}
.comment-content th {
background: #f8f9fa;
font-weight: 600;
}
.comment-content img {
max-width: 100%;
height: auto;
border-radius: 4px;
margin: 10px 0;
}
.comment-content del {
color: #868e96;
}
/* 清除浮动 */
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1; /* IE6-7 */
}
/* 响应式调整 */
@media (max-width: 768px) {
.markdown-badges,
.markdown-shortcuts {
float: none;
text-align: left;
margin: 5px 0;
}
.markdown-shortcuts {
margin-top: 10px;
}
.shortcut-key {
margin-left: 0;
margin-right: 10px;
}
.help-item {
width: 50%;
}
}
@media (max-width: 480px) {
.help-item {
width: 100%;
float: none;
}
.markdown-badge {
margin-bottom: 5px;
}
}
美化版主要改进点:
浏览器兼容性:
- IE6-11 支持:使用
*display: inline、*zoom: 1等CSS hack - 事件兼容:同时支持
addEventListener和attachEvent - 选择器兼容:提供备选的选择器方案
- 光标处理:兼容IE的
createTextRange方法 - 特性检测:检测浏览器特性而不是特定浏览器
访客模式支持:
- 使用
comment_form_top钩子确保在登录和未登录状态下都显示 - 移除了对登录状态的依赖
- 脚本在页面加载时自动初始化
功能增强:
- 添加了降级处理:如果没有Parsedown库,使用内置的简单解析器
- 增加了删除线支持(
~~) - 改进了代码块处理
- 添加了更多格式选项
风格保持:
- 保持了原有的颜色方案
- 使用浮动实现布局,确保旧浏览器兼容
- 保留了所有原有的样式细节
- 添加了针对旧浏览器的特殊样式
这样修改后,Markdown提示框会在所有浏览器中正确显示,并且对访客(未登录用户)同样生效,同时保持了原有的视觉风格。