
7折
减价出售
¥799
WordPress的预览功能是内容创作流程中至关重要的组成部分,它允许用户在内容发布前查看实际展示效果。这一功能的实现基于WordPress的修订系统和非公开内容存储机制。
当用户点击预览按钮时,WordPress主题会执行以下关键步骤:
// 典型的预览请求处理流程示例
add_action('wp_ajax_get-preview', '_wp_get_preview_ajax_response');
function _wp_get_preview_ajax_response() {
// 验证用户权限
if (!current_user_can('edit_posts')) {
wp_send_json_error('无预览权限');
}
$post_id = absint($_POST['post_id']);
$revision_id = $this->create_preview_revision($post_id);
// 生成预览链接
$preview_link = $this->generate_preview_link($post_id, $revision_id);
wp_send_json_success([
'preview_url' => $preview_link,
'expires' => time() + 3600 // 1小时后过期
]);
}
function create_preview_revision($post_id) {
// 获取当前编辑的内容
$post_data = get_post($post_id, ARRAY_A);
$content = $_POST['content'] ?? $post_data['post_content'];
// 创建临时修订版本
$revision = [
'post_parent' => $post_id,
'post_type' => 'revision',
'post_content' => $content,
'post_status' => 'inherit'
];
return wp_insert_post($revision);
}
WordPress采用多重安全措施保护预览内容:
function generate_preview_link($post_id, $revision_id) {
// 创建安全令牌
$nonce = wp_create_nonce('post_preview_' . $post_id);
// 构建预览URL
return add_query_arg([
'preview' => true,
'preview_nonce' => $nonce,
'p' => $post_id,
'revision' => $revision_id,
'preview_version' => time() // 防止缓存
], home_url('/'));
}
对于需要更复杂预览功能的场景,可以扩展WordPress默认的预览系统:
class Enhanced_Preview_Handler {
public function __construct() {
// 修改预览链接生成逻辑
add_filter('preview_post_link', [$this, 'enhance_preview_link'], 10, 2);
// 处理预览请求
add_action('template_redirect', [$this, 'handle_preview_request']);
// 预览内容过滤器
add_filter('the_preview', [$this, 'filter_preview_content'], 10, 2);
}
public function enhance_preview_link($preview_link, $post) {
// 添加设备预览参数
return add_query_arg([
'device' => 'desktop', // 默认桌面视图
'theme' => get_option('stylesheet') // 当前主题
], $preview_link);
}
public function handle_preview_request() {
if (!isset($_GET['preview']) || !isset($_GET['preview_nonce'])) {
return;
}
$post_id = absint($_GET['p']);
$nonce = $_GET['preview_nonce'];
// 验证nonce
if (!wp_verify_nonce($nonce, 'post_preview_' . $post_id)) {
wp_die('预览链接已过期');
}
// 设置预览模式标志
if (!defined('IS_PREVIEW')) {
define('IS_PREVIEW', true);
}
// 加载预览数据
$this->load_preview_data($post_id);
}
private function load_preview_data($post_id) {
global $preview_data;
// 从修订版本或临时存储中获取预览数据
if (isset($_GET['revision'])) {
$revision = get_post(absint($_GET['revision']));
if ($revision && $revision->post_parent == $post_id) {
$preview_data = $revision;
}
}
// 如果没有找到修订版本,使用自动保存的草稿
if (empty($preview_data)) {
$autosave = wp_get_post_autosave($post_id);
if ($autosave) {
$preview_data = $autosave;
}
}
}
}
现代网站需要在不同设备上保持良好显示效果,扩展预览系统支持多设备预览:
class Multi_Device_Preview {
public function __construct() {
add_action('wp_head', [$this, 'add_device_preview_switcher']);
add_filter('the_preview', [$this, 'apply_device_styles']);
}
public function add_device_preview_switcher() {
if (!isset($_GET['preview']) || !$_GET['preview']) {
return;
}
$current_device = $_GET['device'] ?? 'desktop';
echo '
<div class="preview-device-switcher">
<button class="device-btn desktop" data-device="desktop" '.($current_device=='desktop'?'disabled':'').'>桌面</button>
<button class="device-btn tablet" data-device="tablet" '.($current_device=='tablet'?'disabled':'').'>平板</button>
<button class="device-btn mobile" data-device="mobile" '.($current_device=='mobile'?'disabled':'').'>手机</button>
</div>
<style>
.preview-device-switcher {
position: fixed;
top: 10px;
right: 10px;
z-index: 9999;
background: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.preview-device-switcher button {
padding: 5px 10px;
margin: 0 5px;
cursor: pointer;
}
.preview-device-switcher button[disabled] {
background: #0073aa;
color: white;
cursor: default;
}
</style>
';
}
public function apply_device_styles($content) {
$device = $_GET['device'] ?? 'desktop';
switch ($device) {
case 'tablet':
return '<div class="preview-tablet-view">' . $content . '</div>';
case 'mobile':
return '<div class="preview-mobile-view">' . $content . '</div>';
default:
return $content;
}
}
}
结合WordPress的REST API和前端技术,实现编辑时实时预览:
class LiveContentPreview {
constructor() {
this.previewFrame = null;
this.debounceTimer = null;
this.init();
}
init() {
// 设置预览iframe
this.setupPreviewFrame();
// 监听内容变化
this.setupContentWatchers();
}
setupPreviewFrame() {
this.previewFrame = document.createElement('iframe');
this.previewFrame.id = 'live-preview-frame';
this.previewFrame.style.width = '100%';
this.previewFrame.style.height = '600px';
this.previewFrame.style.border = '1px solid #ddd';
const previewContainer = document.getElementById('preview-container') ||
document.querySelector('.block-editor') ||
document.body;
previewContainer.appendChild(this.previewFrame);
}
setupContentWatchers() {
// 监听标题变化
const titleInput = document.getElementById('title');
if (titleInput) {
titleInput.addEventListener('input', () => {
this.debouncedUpdate();
});
}
// 监听古腾堡编辑器变化
if (typeof wp !== 'undefined' && wp.data) {
wp.data.subscribe(() => {
const content = wp.data.select('core/editor').getEditedPostContent();
this.debouncedUpdate(content);
});
}
// 经典编辑器支持
if (typeof tinymce !== 'undefined') {
tinymce.editors.forEach(editor => {
editor.on('keyup', () => {
this.debouncedUpdate();
});
});
}
}
debouncedUpdate = _.debounce(() => {
this.updatePreview();
}, 500);
async updatePreview() {
const postId = this.getPostId();
const content = this.getCurrentContent();
try {
const response = await fetch(`/wp-json/wp/v2/posts/${postId}/preview`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce
},
body: JSON.stringify({
content: content,
title: document.getElementById('title')?.value || ''
})
});
const data = await response.json();
if (data.preview_url) {
this.previewFrame.src = data.preview_url;
}
} catch (error) {
console.error('预览更新失败:', error);
}
}
}
对于主题和样式更改的实时预览:
add_action('admin_enqueue_scripts', function() {
if (is_admin() && get_current_screen()->base === 'post') {
wp_enqueue_script('live-style-preview', get_template_directory_uri() . '/js/live-preview.js', ['jquery', 'wp-api'], null, true);
// 传递当前样式设置
wp_localize_script('live-style-preview', 'styleSettings', [
'primaryColor' => get_theme_mod('primary_color', '#0073aa'),
'fontFamily' => get_theme_mod('body_font', 'Arial, sans-serif'),
'previewNonce' => wp_create_nonce('style_preview')
]);
}
});
对应的前端JavaScript:
class StylePreviewManager {
constructor(settings) {
this.settings = settings;
this.previewWindow = null;
this.initControls();
}
initControls() {
// 颜色选择器
$('#color-picker').on('change', (e) => {
this.settings.primaryColor = e.target.value;
this.updatePreview();
});
// 字体选择器
$('#font-selector').on('change', (e) => {
this.settings.fontFamily = e.target.value;
this.updatePreview();
});
}
openPreview() {
if (!this.previewWindow || this.previewWindow.closed) {
this.previewWindow = window.open('about:blank', 'stylepreview');
this.updatePreview();
}
}
async updatePreview() {
if (!this.previewWindow) return;
try {
const response = await fetch('/wp-json/theme/v1/preview', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': this.settings.previewNonce
},
body: JSON.stringify(this.settings)
});
const html = await response.text();
this.previewWindow.document.write(html);
this.previewWindow.document.close();
} catch (error) {
console.error('样式预览更新失败:', error);
}
}
}
// 初始化
jQuery(document).ready(function($) {
if (typeof styleSettings !== 'undefined') {
window.stylePreview = new StylePreviewManager(styleSettings);
}
});
构建支持多用户同时预览和评论的系统:
class Collaborative_Preview {
public function __construct() {
add_action('wp_ajax_start_collab_preview', [$this, 'start_collab_session']);
add_action('wp_ajax_join_collab_preview', [$this, 'join_collab_session']);
add_action('wp_ajax_submit_preview_comment', [$this, 'handle_comment']);
}
public function start_collab_session() {
check_ajax_referer('collab_preview', 'nonce');
$post_id = absint($_POST['post_id']);
$session_id = uniqid('preview_');
// 存储会话数据
set_transient('collab_preview_' . $session_id, [
'post_id' => $post_id,
'creator' => get_current_user_id(),
'participants' => [get_current_user_id()],
'created' => time(),
'expires' => time() + 3600 // 1小时后过期
], 3600);
// 生成参与链接
$join_url = add_query_arg([
'collab_preview' => $session_id,
'join_token' => wp_create_nonce('join_preview_' . $session_id)
], home_url('/'));
wp_send_json_success([
'session_id' => $session_id,
'join_url' => $join_url
]);
}
public function join_collab_session() {
$session_id = sanitize_text_field($_POST['session_id']);
$token = $_POST['token'];
if (!wp_verify_nonce($token, 'join_preview_' . $session_id)) {
wp_send_json_error('无效的加入令牌');
}
$session = get_transient('collab_preview_' . $session_id);
if (!$session) {
wp_send_json_error('会话已过期');
}
// 添加当前用户到参与者列表
if (!in_array(get_current_user_id(), $session['participants'])) {
$session['participants'][] = get_current_user_id();
set_transient('collab_preview_' . $session_id, $session, 3600);
}
wp_send_json_success([
'post_id' => $session['post_id'],
'participants' => $session['participants']
]);
}
}
实现当前编辑内容与已发布版本的对比功能:
class Version_Compare_Preview {
public function __construct() {
add_action('admin_menu', [$this, 'add_version_compare_meta_box']);
add_action('wp_ajax_get_version_diff', [$this, 'get_version_diff']);
}
public function add_version_compare_meta_box() {
add_meta_box(
'version-compare',
'版本对比',
[$this, 'render_compare_interface'],
null,
'side'
);
}
public function render_compare_interface($post) {
$revisions = wp_get_post_revisions($post->ID);
echo '<div class="version-compare-interface">';
echo '<select id="compare-base-version">';
echo '<option value="current">当前已发布版本</option>';
foreach ($revisions as $revision) {
$date = wp_post_revision_title($revision, false);
echo '<option value="' . esc_attr($revision->ID) . '">' . esc_html($date) . '</option>';
}
echo '</select>';
echo '<button id="compare-versions" class="button">对比版本</button>';
echo '<div id="version-diff-result"></div>';
echo '</div>';
}
public function get_version_diff() {
$post_id = absint($_POST['post_id']);
$base_id = absint($_POST['base_id']);
$current_content = $_POST['current_content'];
$base_content = $base_id === 0 ?
get_post($post_id)->post_content :
get_post($base_id)->post_content;
// 使用WP的文本差异引擎
require_once ABSPATH . WPINC . '/wp-diff.php';
$diff = new Text_Diff(
explode("\n", $base_content),
explode("\n", $current_content)
);
$renderer = new WP_Text_Diff_Renderer_table();
wp_send_json_success([
'diff_html' => $renderer->render($diff)
]);
}
}
通过以上技术实现,WordPress的预览功能可以从简单的”所见即所得”发展为强大的内容创作协作工具,满足从个人博客到企业级内容团队的各种需求。
减价出售
减价出售
减价出售
减价出售
电话咨询
1855-626-3292
微信咨询