文章目录
-
- 在当今数字化时代,网站设计已成为品牌形象和用户体验的重要组成部分。字体作为视觉传达的核心元素之一,直接影响着网站的可读性、美观性和品牌识别度。然而,对于许多网站管理员和设计师来说,字体管理一直是一个挑战——如何在保持网站性能的同时,提供丰富的字体选择?如何让用户能够实时预览字体效果?如何高效管理自定义字库? 本文将详细介绍如何通过WordPress代码二次开发,集成在线字体预览与个性化字库管理工具到您的网站中。我们将从基础概念讲起,逐步深入到具体实现步骤,帮助您打造一个功能完善、用户友好的字体管理系统。
-
- WordPress默认提供有限的字体选择,通常依赖于主题预设或Google Fonts等外部服务。虽然这些方案简单易用,但存在以下局限性: 字体选择受限,难以满足个性化需求 缺乏实时预览功能,用户无法直观感受字体效果 外部字体服务可能影响页面加载速度 难以管理自定义品牌字体
- 在开始开发之前,请确保您已准备好以下环境: 本地开发环境:推荐使用XAMPP、MAMP或Local by Flywheel WordPress安装:建议使用最新版本的WordPress 代码编辑器:如VS Code、Sublime Text或PHPStorm 浏览器开发者工具:用于调试和测试 FTP客户端:用于将文件上传到生产环境
- 为了避免直接修改主题文件导致更新时丢失更改,我们首先创建一个子主题: 在WordPress的wp-content/themes/目录下创建新文件夹,命名为my-font-manager-theme 在该文件夹中创建style.css文件,添加以下内容: /* Theme Name: My Font Manager Theme Template: twentytwentythree // 根据您使用的父主题修改 Version: 1.0.0 Description: 子主题用于集成字体管理功能 */ 创建functions.php文件,用于添加自定义功能
-
- 字体预览功能需要直观展示不同字体的效果。我们将创建一个简单的预览界面: // 在functions.php中添加字体预览短代码 function font_preview_shortcode($atts) { $atts = shortcode_atts(array( 'text' => '预览文本', 'size' => '24px', 'color' => '#333333', 'font' => 'Arial, sans-serif' ), $atts); $output = '<div class="font-preview-container">'; $output .= '<div class="font-preview-controls">'; $output .= '<input type="text" class="font-preview-text" value="' . esc_attr($atts['text']) . '" placeholder="输入预览文本">'; $output .= '<input type="range" class="font-preview-size" min="12" max="72" value="' . str_replace('px', '', $atts['size']) . '">'; $output .= '<input type="color" class="font-preview-color" value="' . esc_attr($atts['color']) . '">'; $output .= '<select class="font-preview-select">'; $output .= '<option value="Arial, sans-serif"' . selected($atts['font'], 'Arial, sans-serif', false) . '>Arial</option>'; $output .= '<option value="Georgia, serif"' . selected($atts['font'], 'Georgia, serif', false) . '>Georgia</option>'; // 更多字体选项将在后续添加 $output .= '</select>'; $output .= '</div>'; $output .= '<div class="font-preview-display" style="font-family: ' . esc_attr($atts['font']) . '; font-size: ' . esc_attr($atts['size']) . '; color: ' . esc_attr($atts['color']) . ';">'; $output .= esc_html($atts['text']); $output .= '</div>'; $output .= '</div>'; return $output; } add_shortcode('font_preview', 'font_preview_shortcode');
- 通过JavaScript实现实时预览效果: // 创建js/font-preview.js文件 jQuery(document).ready(function($) { $('.font-preview-container').each(function() { var $container = $(this); var $display = $container.find('.font-preview-display'); var $textInput = $container.find('.font-preview-text'); var $sizeInput = $container.find('.font-preview-size'); var $colorInput = $container.find('.font-preview-color'); var $fontSelect = $container.find('.font-preview-select'); // 更新预览文本 $textInput.on('input', function() { $display.text($(this).val()); }); // 更新字体大小 $sizeInput.on('input', function() { $display.css('font-size', $(this).val() + 'px'); }); // 更新字体颜色 $colorInput.on('input', function() { $display.css('color', $(this).val()); }); // 更新字体族 $fontSelect.on('change', function() { $display.css('font-family', $(this).val()); }); }); });
- 为了提供更多字体选择,我们可以集成Google Fonts API: // 在functions.php中添加Google Fonts集成 function enqueue_google_fonts() { wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&family=Open+Sans:wght@300;400;600&family=Montserrat:wght@400;700&display=swap'); } add_action('wp_enqueue_scripts', 'enqueue_google_fonts'); // 扩展字体选择选项 function get_available_fonts() { $fonts = array( '系统字体' => array( 'Arial, sans-serif' => 'Arial', 'Georgia, serif' => 'Georgia', 'Times New Roman, serif' => 'Times New Roman', 'Verdana, sans-serif' => 'Verdana' ), 'Google字体' => array( 'Roboto, sans-serif' => 'Roboto', 'Open Sans, sans-serif' => 'Open Sans', 'Montserrat, sans-serif' => 'Montserrat', 'Lato, sans-serif' => 'Lato', 'Poppins, sans-serif' => 'Poppins' ) ); return $fonts; } // 更新短代码以包含更多字体选项 function font_preview_shortcode_enhanced($atts) { $atts = shortcode_atts(array( 'text' => '预览文本', 'size' => '24px', 'color' => '#333333', 'font' => 'Arial, sans-serif' ), $atts); $fonts = get_available_fonts(); $output = '<div class="font-preview-container">'; $output .= '<div class="font-preview-controls">'; $output .= '<input type="text" class="font-preview-text" value="' . esc_attr($atts['text']) . '" placeholder="输入预览文本">'; $output .= '<input type="range" class="font-preview-size" min="12" max="72" value="' . str_replace('px', '', $atts['size']) . '">'; $output .= '<input type="color" class="font-preview-color" value="' . esc_attr($atts['color']) . '">'; $output .= '<select class="font-preview-select">'; foreach ($fonts as $category => $font_list) { $output .= '<optgroup label="' . esc_attr($category) . '">'; foreach ($font_list as $font_value => $font_name) { $selected = $font_value === $atts['font'] ? 'selected' : ''; $output .= '<option value="' . esc_attr($font_value) . '" ' . $selected . '>' . esc_html($font_name) . '</option>'; } $output .= '</optgroup>'; } $output .= '</select>'; $output .= '</div>'; $output .= '<div class="font-preview-display" style="font-family: ' . esc_attr($atts['font']) . '; font-size: ' . esc_attr($atts['size']) . '; color: ' . esc_attr($atts['color']) . ';">'; $output .= esc_html($atts['text']); $output .= '</div>'; $output .= '</div>'; return $output; } add_shortcode('font_preview_enhanced', 'font_preview_shortcode_enhanced');
-
- 为了管理自定义字体,我们需要创建数据库表来存储字体信息: // 创建字体数据库表 function create_fonts_table() { global $wpdb; $table_name = $wpdb->prefix . 'custom_fonts'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, font_name varchar(100) NOT NULL, font_family varchar(100) NOT NULL, font_file_woff2 varchar(255), font_file_woff varchar(255), font_file_ttf varchar(255), font_license text, upload_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL, is_active tinyint(1) DEFAULT 1 NOT NULL, PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } register_activation_hook(__FILE__, 'create_fonts_table');
- 我们将创建一个WordPress管理页面来管理自定义字体: // 添加字体管理菜单 function add_font_management_menu() { add_menu_page( '字体管理', '字体管理', 'manage_options', 'font-management', 'font_management_page', 'dashicons-editor-textcolor', 30 ); add_submenu_page( 'font-management', '添加新字体', '添加新字体', 'manage_options', 'add-new-font', 'add_new_font_page' ); } add_action('admin_menu', 'add_font_management_menu'); // 字体管理主页面 function font_management_page() { global $wpdb; $table_name = $wpdb->prefix . 'custom_fonts'; $fonts = $wpdb->get_results("SELECT * FROM $table_name ORDER BY upload_date DESC"); echo '<div class="wrap">'; echo '<h1>自定义字体管理</h1>'; echo '<a href="' . admin_url('admin.php?page=add-new-font') . '" class="button button-primary">添加新字体</a>'; echo '<hr>'; if (empty($fonts)) { echo '<p>暂无自定义字体。请点击上方按钮添加字体。</p>'; } else { echo '<table class="wp-list-table widefat fixed striped">'; echo '<thead><tr>'; echo '<th>ID</th><th>字体名称</th><th>字体族</th><th>文件格式</th><th>上传日期</th><th>状态</th><th>操作</th>'; echo '</tr></thead>'; echo '<tbody>'; foreach ($fonts as $font) { $formats = array(); if ($font->font_file_woff2) $formats[] = 'WOFF2'; if ($font->font_file_woff) $formats[] = 'WOFF'; if ($font->font_file_ttf) $formats[] = 'TTF'; echo '<tr>'; echo '<td>' . $font->id . '</td>'; echo '<td>' . esc_html($font->font_name) . '</td>'; echo '<td>' . esc_html($font->font_family) . '</td>'; echo '<td>' . implode(', ', $formats) . '</td>'; echo '<td>' . $font->upload_date . '</td>'; echo '<td>' . ($font->is_active ? '启用' : '禁用') . '</td>'; echo '<td>'; echo '<a href="#" class="button button-small preview-font" data-font-id="' . $font->id . '">预览</a> '; echo '<a href="#" class="button button-small toggle-font" data-font-id="' . $font->id . '" data-status="' . $font->is_active . '">' . ($font->is_active ? '禁用' : '启用') . '</a> '; echo '<a href="#" class="button button-small delete-font" data-font-id="' . $font->id . '">删除</a>'; echo '</td>'; echo '</tr>'; } echo '</tbody>'; echo '</table>'; } echo '</div>'; } // 添加新字体页面 function add_new_font_page() { echo '<div class="wrap">'; echo '<h1>添加新字体</h1>'; echo '<form method="post" enctype="multipart/form-data" id="font-upload-form">'; echo '<table class="form-table">'; echo '<tr>'; echo '<th><label for="font_name">字体名称</label></th>'; echo '<td><input type="text" id="font_name" name="font_name" class="regular-text" required></td>'; echo '</tr>'; echo '<tr>'; echo '<th><label for="font_family">字体族名称</label></th>'; echo '<td><input type="text" id="font_family" name="font_family" class="regular-text" required>'; echo '<p class="description">用于CSS font-family属性的名称,如 "MyCustomFont"</p></td>'; echo '</tr>'; echo '<tr>'; echo '<th><label for="font_license">字体许可证</label></th>'; echo '<td><textarea id="font_license" name="font_license" rows="4" class="large-text"></textarea>'; echo '<p class="description">请确保您有权使用和分发此字体</p></td>'; echo '</tr>'; echo '<tr>'; echo '<th><label>字体文件</label></th>'; echo '<td>'; echo '<p><label><input type="checkbox" name="font_formats[]" value="woff2"> WOFF2格式</label>'; echo '<input type="file" name="font_file_woff2" accept=".woff2"></p>'; echo '<p><label><input type="checkbox" name="font_formats[]" value="woff"> WOFF格式</label>'; echo '<input type="file" name="font_file_woff" accept=".woff"></p>'; echo '<p><label><input type="checkbox" name="font_formats[]" value="ttf"> TTF格式</label>'; echo '<input type="file" name="font_file_ttf" accept=".ttf"></p>'; echo '</td>'; echo '</tr>'; echo '</table>'; echo '<p class="submit">'; echo '<input type="submit" name="submit_font" class="button button-primary" value="上传字体">'; echo '</p>'; echo '</form>'; echo '</div>'; // 处理字体上传 if (isset($_POST['submit_font'])) { handle_font_upload(); } } // 处理字体上传 function handle_font_upload() { if (!current_user_can('manage_options')) { wp_die('权限不足'); } global $wpdb; $table_name = $wpdb->prefix . 'custom_fonts'; $font_name = sanitize_text_field($_POST['font_name']); $font_family = sanitize_text_field($_POST['font_family']); $font_license = sanitize_textarea_field($_POST['font_license']); // 创建字体目录 $upload_dir = wp_upload_dir(); $font_dir = $upload_dir['basedir'] . '/custom-fonts/' . sanitize_title($font_family); if (!file_exists($font_dir)) { wp_mkdir_p($font_dir); } $font_data = array( 'font_name' => $font_name, 'font_family' => $font_family, 'font_license' => $font_license ); // 处理上传的文件 $formats = array('woff2', 'woff', 'ttf'); foreach ($formats as $format) { $file_key = 'font_file_' . $format; if (isset($_FILES[$file_key]) && $_FILES[$file_key]['error'] === 0) { $file = $_FILES[$file_key]; $filename = sanitize_file_name($font_family . '.' . $format); $filepath = $font_dir . '/' . $filename; if (move_uploaded_file($file['tmp_name'], $filepath)) { $font_data['font_file_' . $format] = $upload_dir['baseurl'] . '/custom-fonts/' . sanitize_title($font_family) . '/' . $filename; } } } // 保存到数据库 $wpdb->insert($table_name, $font_data);
-
- 为了让用户能够在前端预览和管理字体,我们需要创建一个用户友好的界面: // 创建字体预览器页面模板 function font_previewer_page_template($template) { if (is_page('font-previewer')) { $new_template = locate_template(array('page-font-previewer.php')); if (!empty($new_template)) { return $new_template; } } return $template; } add_filter('template_include', 'font_previewer_page_template'); // 创建字体预览器页面内容 function create_font_previewer_page() { $page_title = '字体预览器'; $page_content = '[font_previewer]'; $page_check = get_page_by_title($page_title); if (!$page_check) { $page_data = array( 'post_title' => $page_title, 'post_content' => $page_content, 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'font-previewer' ); wp_insert_post($page_data); } } register_activation_hook(__FILE__, 'create_font_previewer_page'); // 字体预览器短代码 function font_previewer_shortcode() { ob_start(); ?> <div class="font-previewer-container"> <div class="font-previewer-header"> <h1>在线字体预览器</h1> <p>预览和管理您的字体库,实时查看字体效果</p> </div> <div class="font-previewer-controls"> <div class="control-group"> <label for="preview-text">预览文本:</label> <input type="text" id="preview-text" value="字体的艺术在于表达" class="preview-control"> </div> <div class="control-group"> <label for="font-size">字体大小:</label> <input type="range" id="font-size" min="12" max="120" value="48" class="preview-control"> <span id="font-size-value">48px</span> </div> <div class="control-group"> <label for="font-color">字体颜色:</label> <input type="color" id="font-color" value="#333333" class="preview-control"> </div> <div class="control-group"> <label for="background-color">背景颜色:</label> <input type="color" id="background-color" value="#ffffff" class="preview-control"> </div> <div class="control-group"> <label for="font-weight">字重:</label> <select id="font-weight" class="preview-control"> <option value="300">细体 (300)</option> <option value="400" selected>常规 (400)</option> <option value="600">中等 (600)</option> <option value="700">粗体 (700)</option> <option value="900">特粗 (900)</option> </select> </div> <div class="control-group"> <label for="text-align">对齐方式:</label> <select id="text-align" class="preview-control"> <option value="left">左对齐</option> <option value="center" selected>居中</option> <option value="right">右对齐</option> <option value="justify">两端对齐</option> </select> </div> </div> <div class="font-previewer-main"> <div class="font-selector-sidebar"> <div class="font-categories"> <button class="category-btn active" data-category="all">全部字体</button> <button class="category-btn" data-category="system">系统字体</button> <button class="category-btn" data-category="google">Google字体</button> <button class="category-btn" data-category="custom">自定义字体</button> <button class="category-btn" data-category="favorites">收藏夹</button> </div> <div class="font-search"> <input type="text" id="font-search" placeholder="搜索字体..."> </div> <div class="font-list" id="font-list"> <!-- 字体列表将通过AJAX加载 --> <div class="loading-fonts">加载字体中...</div> </div> </div> <div class="font-preview-area"> <div class="preview-display" id="preview-display"> <div class="preview-text" id="preview-text-display"> 字体的艺术在于表达 </div> </div> <div class="preview-info"> <h3>字体信息</h3> <div class="info-grid"> <div class="info-item"> <span class="info-label">字体名称:</span> <span id="current-font-name">Arial</span> </div> <div class="info-item"> <span class="info-label">字体族:</span> <span id="current-font-family">Arial, sans-serif</span> </div> <div class="info-item"> <span class="info-label">字体大小:</span> <span id="current-font-size">48px</span> </div> <div class="info-item"> <span class="info-label">字重:</span> <span id="current-font-weight">400</span> </div> </div> <div class="preview-actions"> <button id="apply-font" class="button button-primary">应用此字体到网站</button> <button id="save-preset" class="button">保存为预设</button> <button id="share-preview" class="button">分享预览</button> <button id="add-to-favorites" class="button">添加到收藏夹</button> </div> <div class="css-code"> <h4>CSS代码:</h4> <pre id="css-code-output">font-family: Arial, sans-serif; font-size: 48px; font-weight: 400; color: #333333;</pre> <button id="copy-css" class="button button-small">复制CSS</button> </div> </div> </div> </div> <div class="font-presets"> <h3>字体预设</h3> <div class="presets-grid" id="presets-grid"> <!-- 预设将通过AJAX加载 --> </div> <button id="create-preset" class="button">创建新预设</button> </div> </div> <?php return ob_get_clean(); } add_shortcode('font_previewer', 'font_previewer_shortcode');
- // 添加AJAX处理函数 function get_fonts_ajax() { $category = sanitize_text_field($_POST['category']); $search = sanitize_text_field($_POST['search']); $fonts = array(); // 获取系统字体 if ($category === 'all' || $category === 'system') { $system_fonts = array( array('name' => 'Arial', 'family' => 'Arial, sans-serif', 'category' => 'system'), array('name' => 'Georgia', 'family' => 'Georgia, serif', 'category' => 'system'), array('name' => 'Times New Roman', 'family' => 'Times New Roman, serif', 'category' => 'system'), array('name' => 'Verdana', 'family' => 'Verdana, sans-serif', 'category' => 'system'), array('name' => 'Courier New', 'family' => 'Courier New, monospace', 'category' => 'system'), ); $fonts = array_merge($fonts, $system_fonts); } // 获取Google字体 if ($category === 'all' || $category === 'google') { $google_fonts = array( array('name' => 'Roboto', 'family' => 'Roboto, sans-serif', 'category' => 'google'), array('name' => 'Open Sans', 'family' => 'Open Sans, sans-serif', 'category' => 'google'), array('name' => 'Montserrat', 'family' => 'Montserrat, sans-serif', 'category' => 'google'), array('name' => 'Lato', 'family' => 'Lato, sans-serif', 'category' => 'google'), array('name' => 'Poppins', 'family' => 'Poppins, sans-serif', 'category' => 'google'), array('name' => 'Source Sans Pro', 'family' => 'Source Sans Pro, sans-serif', 'category' => 'google'), array('name' => 'Oswald', 'family' => 'Oswald, sans-serif', 'category' => 'google'), array('name' => 'Raleway', 'family' => 'Raleway, sans-serif', 'category' => 'google'), ); $fonts = array_merge($fonts, $google_fonts); } // 获取自定义字体 if ($category === 'all' || $category === 'custom') { global $wpdb; $table_name = $wpdb->prefix . 'custom_fonts'; $custom_fonts = $wpdb->get_results("SELECT * FROM $table_name WHERE is_active = 1", ARRAY_A); foreach ($custom_fonts as $font) { $fonts[] = array( 'name' => $font['font_name'], 'family' => $font['font_family'], 'category' => 'custom', 'id' => $font['id'] ); } } // 应用搜索过滤 if (!empty($search)) { $fonts = array_filter($fonts, function($font) use ($search) { return stripos($font['name'], $search) !== false; }); } wp_send_json_success($fonts); } add_action('wp_ajax_get_fonts', 'get_fonts_ajax'); add_action('wp_ajax_nopriv_get_fonts', 'get_fonts_ajax'); // 保存字体预设 function save_font_preset_ajax() { if (!is_user_logged_in()) { wp_send_json_error('请先登录'); } $preset_name = sanitize_text_field($_POST['preset_name']); $font_family = sanitize_text_field($_POST['font_family']); $font_size = sanitize_text_field($_POST['font_size']); $font_color = sanitize_text_field($_POST['font_color']); $font_weight = sanitize_text_field($_POST['font_weight']); $user_id = get_current_user_id(); // 保存预设到用户meta $presets = get_user_meta($user_id, 'font_presets', true); if (empty($presets)) { $presets = array(); } $new_preset = array( 'id' => uniqid(), 'name' => $preset_name, 'font_family' => $font_family, 'font_size' => $font_size, 'font_color' => $font_color, 'font_weight' => $font_weight, 'created' => current_time('mysql') ); $presets[] = $new_preset; update_user_meta($user_id, 'font_presets', $presets); wp_send_json_success($new_preset); } add_action('wp_ajax_save_font_preset', 'save_font_preset_ajax'); // 获取字体预设 function get_font_presets_ajax() { if (!is_user_logged_in()) { wp_send_json_success(array()); } $user_id = get_current_user_id(); $presets = get_user_meta($user_id, 'font_presets', true); if (empty($presets)) { $presets = array(); } wp_send_json_success($presets); } add_action('wp_ajax_get_font_presets', 'get_font_presets_ajax');
- // 创建js/font-previewer.js文件 jQuery(document).ready(function($) { // 初始化变量 var currentFont = { family: 'Arial, sans-serif', name: 'Arial', size: '48px', color: '#333333', weight: '400', align: 'center', backgroundColor: '#ffffff' }; // 加载字体列表 function loadFonts(category, search) { $('#font-list').html('<div class="loading-fonts">加载字体中...</div>'); $.ajax({ url: fontPreviewer.ajax_url, type: 'POST', data: { action: 'get_fonts', category: category, search: search }, success: function(response) { if (response.success) { renderFontList(response.data); } } }); } // 渲染字体列表 function renderFontList(fonts) { var html = ''; if (fonts.length === 0) { html = '<div class="no-fonts">未找到匹配的字体</div>'; } else { fonts.forEach(function(font) { var isActive = font.family === currentFont.family ? 'active' : ''; html += '<div class="font-item ' + isActive + '" data-font-family="' + font.family + '" data-font-name="' + font.name + '" data-category="' + font.category + '">'; html += '<div class="font-item-preview" style="font-family: ' + font.family + '">' + font.name + '</div>'; html += '<div class="font-item-name">' + font.name + '</div>'; html += '<div class="font-item-category ' + font.category + '">' + getCategoryLabel(font.category) + '</div>'; html += '</div>'; }); } $('#font-list').html(html); } // 获取分类标签 function getCategoryLabel(category) { var labels = { 'system': '系统', 'google': 'Google', 'custom': '自定义' }; return labels[category] || category; } // 更新预览显示 function updatePreview() { var $preview = $('#preview-text-display'); $preview.css({ 'font-family': currentFont.family, 'font-size': currentFont.size, 'color': currentFont.color, 'font-weight': currentFont.weight, 'text-align': currentFont.align }); $('#preview-display').css('background-color', currentFont.backgroundColor); // 更新信息显示 $('#current-font-name').text(currentFont.name); $('#current-font-family').text(currentFont.family); $('#current-font-size').text(currentFont.size); $('#current-font-weight').text(currentFont.weight); // 更新CSS代码 updateCssCode(); } // 更新CSS代码 function updateCssCode() { var css = 'font-family: ' + currentFont.family + ';n'; css += 'font-size: ' + currentFont.size + ';n'; css += 'font-weight: ' + currentFont.weight + ';n'; css += 'color: ' + currentFont.color + ';'; if (currentFont.backgroundColor !== '#ffffff') { css += 'nbackground-color: ' + currentFont.backgroundColor + ';'; } if (currentFont.align !== 'left') { css += 'ntext-align: ' + currentFont.align + ';'; } $('#css-code-output').text(css); } // 初始化事件监听 function initEventListeners() { // 字体选择 $(document).on('click', '.font-item', function() { $('.font-item').removeClass('active'); $(this).addClass('active'); currentFont.family = $(this).data('font-family'); currentFont.name = $(this).data('font-name'); updatePreview(); }); // 分类过滤 $('.category-btn').click(function() { $('.category-btn').removeClass('active'); $(this).addClass('active'); var category = $(this).data('category'); var search = $('#font-search').val(); loadFonts(category, search); }); // 字体搜索 $('#font-search').on('input', function() { var search = $(this).val(); var category = $('.category-btn.active').data('category'); loadFonts(category, search); }); // 预览文本更改 $('#preview-text').on('input', function() { $('#preview-text-display').text($(this).val()); }); // 字体大小更改 $('#font-size').on('input', function() { var size = $(this).val() + 'px'; $('#font-size-value').text(size); currentFont.size = size; updatePreview(); }); // 字体颜色更改 $('#font-color').on('input', function() { currentFont.color = $(this).val(); updatePreview(); }); // 背景颜色更改 $('#background-color').on('input', function() { currentFont.backgroundColor = $(this).val(); updatePreview(); }); // 字重更改 $('#font-weight').change(function() { currentFont.weight = $(this).val(); updatePreview(); }); // 对齐方式更改
在当今数字化时代,网站设计已成为品牌形象和用户体验的重要组成部分。字体作为视觉传达的核心元素之一,直接影响着网站的可读性、美观性和品牌识别度。然而,对于许多网站管理员和设计师来说,字体管理一直是一个挑战——如何在保持网站性能的同时,提供丰富的字体选择?如何让用户能够实时预览字体效果?如何高效管理自定义字库?
本文将详细介绍如何通过WordPress代码二次开发,集成在线字体预览与个性化字库管理工具到您的网站中。我们将从基础概念讲起,逐步深入到具体实现步骤,帮助您打造一个功能完善、用户友好的字体管理系统。
WordPress默认提供有限的字体选择,通常依赖于主题预设或Google Fonts等外部服务。虽然这些方案简单易用,但存在以下局限性:
- 字体选择受限,难以满足个性化需求
- 缺乏实时预览功能,用户无法直观感受字体效果
- 外部字体服务可能影响页面加载速度
- 难以管理自定义品牌字体
在开始开发之前,请确保您已准备好以下环境:
- 本地开发环境:推荐使用XAMPP、MAMP或Local by Flywheel
- WordPress安装:建议使用最新版本的WordPress
- 代码编辑器:如VS Code、Sublime Text或PHPStorm
- 浏览器开发者工具:用于调试和测试
- FTP客户端:用于将文件上传到生产环境
为了避免直接修改主题文件导致更新时丢失更改,我们首先创建一个子主题:
- 在WordPress的
wp-content/themes/目录下创建新文件夹,命名为my-font-manager-theme - 在该文件夹中创建
style.css文件,添加以下内容:
/*
Theme Name: My Font Manager Theme
Template: twentytwentythree // 根据您使用的父主题修改
Version: 1.0.0
Description: 子主题用于集成字体管理功能
*/
- 创建
functions.php文件,用于添加自定义功能
字体预览功能需要直观展示不同字体的效果。我们将创建一个简单的预览界面:
// 在functions.php中添加字体预览短代码
function font_preview_shortcode($atts) {
$atts = shortcode_atts(array(
'text' => '预览文本',
'size' => '24px',
'color' => '#333333',
'font' => 'Arial, sans-serif'
), $atts);
$output = '<div class="font-preview-container">';
$output .= '<div class="font-preview-controls">';
$output .= '<input type="text" class="font-preview-text" value="' . esc_attr($atts['text']) . '" placeholder="输入预览文本">';
$output .= '<input type="range" class="font-preview-size" min="12" max="72" value="' . str_replace('px', '', $atts['size']) . '">';
$output .= '<input type="color" class="font-preview-color" value="' . esc_attr($atts['color']) . '">';
$output .= '<select class="font-preview-select">';
$output .= '<option value="Arial, sans-serif"' . selected($atts['font'], 'Arial, sans-serif', false) . '>Arial</option>';
$output .= '<option value="Georgia, serif"' . selected($atts['font'], 'Georgia, serif', false) . '>Georgia</option>';
// 更多字体选项将在后续添加
$output .= '</select>';
$output .= '</div>';
$output .= '<div class="font-preview-display" style="font-family: ' . esc_attr($atts['font']) . '; font-size: ' . esc_attr($atts['size']) . '; color: ' . esc_attr($atts['color']) . ';">';
$output .= esc_html($atts['text']);
$output .= '</div>';
$output .= '</div>';
return $output;
}
add_shortcode('font_preview', 'font_preview_shortcode');
通过JavaScript实现实时预览效果:
// 创建js/font-preview.js文件
jQuery(document).ready(function($) {
$('.font-preview-container').each(function() {
var $container = $(this);
var $display = $container.find('.font-preview-display');
var $textInput = $container.find('.font-preview-text');
var $sizeInput = $container.find('.font-preview-size');
var $colorInput = $container.find('.font-preview-color');
var $fontSelect = $container.find('.font-preview-select');
// 更新预览文本
$textInput.on('input', function() {
$display.text($(this).val());
});
// 更新字体大小
$sizeInput.on('input', function() {
$display.css('font-size', $(this).val() + 'px');
});
// 更新字体颜色
$colorInput.on('input', function() {
$display.css('color', $(this).val());
});
// 更新字体族
$fontSelect.on('change', function() {
$display.css('font-family', $(this).val());
});
});
});
为了提供更多字体选择,我们可以集成Google Fonts API:
// 在functions.php中添加Google Fonts集成
function enqueue_google_fonts() {
wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&family=Open+Sans:wght@300;400;600&family=Montserrat:wght@400;700&display=swap');
}
add_action('wp_enqueue_scripts', 'enqueue_google_fonts');
// 扩展字体选择选项
function get_available_fonts() {
$fonts = array(
'系统字体' => array(
'Arial, sans-serif' => 'Arial',
'Georgia, serif' => 'Georgia',
'Times New Roman, serif' => 'Times New Roman',
'Verdana, sans-serif' => 'Verdana'
),
'Google字体' => array(
'Roboto, sans-serif' => 'Roboto',
'Open Sans, sans-serif' => 'Open Sans',
'Montserrat, sans-serif' => 'Montserrat',
'Lato, sans-serif' => 'Lato',
'Poppins, sans-serif' => 'Poppins'
)
);
return $fonts;
}
// 更新短代码以包含更多字体选项
function font_preview_shortcode_enhanced($atts) {
$atts = shortcode_atts(array(
'text' => '预览文本',
'size' => '24px',
'color' => '#333333',
'font' => 'Arial, sans-serif'
), $atts);
$fonts = get_available_fonts();
$output = '<div class="font-preview-container">';
$output .= '<div class="font-preview-controls">';
$output .= '<input type="text" class="font-preview-text" value="' . esc_attr($atts['text']) . '" placeholder="输入预览文本">';
$output .= '<input type="range" class="font-preview-size" min="12" max="72" value="' . str_replace('px', '', $atts['size']) . '">';
$output .= '<input type="color" class="font-preview-color" value="' . esc_attr($atts['color']) . '">';
$output .= '<select class="font-preview-select">';
foreach ($fonts as $category => $font_list) {
$output .= '<optgroup label="' . esc_attr($category) . '">';
foreach ($font_list as $font_value => $font_name) {
$selected = $font_value === $atts['font'] ? 'selected' : '';
$output .= '<option value="' . esc_attr($font_value) . '" ' . $selected . '>' . esc_html($font_name) . '</option>';
}
$output .= '</optgroup>';
}
$output .= '</select>';
$output .= '</div>';
$output .= '<div class="font-preview-display" style="font-family: ' . esc_attr($atts['font']) . '; font-size: ' . esc_attr($atts['size']) . '; color: ' . esc_attr($atts['color']) . ';">';
$output .= esc_html($atts['text']);
$output .= '</div>';
$output .= '</div>';
return $output;
}
add_shortcode('font_preview_enhanced', 'font_preview_shortcode_enhanced');
为了管理自定义字体,我们需要创建数据库表来存储字体信息:
// 创建字体数据库表
function create_fonts_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
font_name varchar(100) NOT NULL,
font_family varchar(100) NOT NULL,
font_file_woff2 varchar(255),
font_file_woff varchar(255),
font_file_ttf varchar(255),
font_license text,
upload_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_active tinyint(1) DEFAULT 1 NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'create_fonts_table');
我们将创建一个WordPress管理页面来管理自定义字体:
// 添加字体管理菜单
function add_font_management_menu() {
add_menu_page(
'字体管理',
'字体管理',
'manage_options',
'font-management',
'font_management_page',
'dashicons-editor-textcolor',
30
);
add_submenu_page(
'font-management',
'添加新字体',
'添加新字体',
'manage_options',
'add-new-font',
'add_new_font_page'
);
}
add_action('admin_menu', 'add_font_management_menu');
// 字体管理主页面
function font_management_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$fonts = $wpdb->get_results("SELECT * FROM $table_name ORDER BY upload_date DESC");
echo '<div class="wrap">';
echo '<h1>自定义字体管理</h1>';
echo '<a href="' . admin_url('admin.php?page=add-new-font') . '" class="button button-primary">添加新字体</a>';
echo '<hr>';
if (empty($fonts)) {
echo '<p>暂无自定义字体。请点击上方按钮添加字体。</p>';
} else {
echo '<table class="wp-list-table widefat fixed striped">';
echo '<thead><tr>';
echo '<th>ID</th><th>字体名称</th><th>字体族</th><th>文件格式</th><th>上传日期</th><th>状态</th><th>操作</th>';
echo '</tr></thead>';
echo '<tbody>';
foreach ($fonts as $font) {
$formats = array();
if ($font->font_file_woff2) $formats[] = 'WOFF2';
if ($font->font_file_woff) $formats[] = 'WOFF';
if ($font->font_file_ttf) $formats[] = 'TTF';
echo '<tr>';
echo '<td>' . $font->id . '</td>';
echo '<td>' . esc_html($font->font_name) . '</td>';
echo '<td>' . esc_html($font->font_family) . '</td>';
echo '<td>' . implode(', ', $formats) . '</td>';
echo '<td>' . $font->upload_date . '</td>';
echo '<td>' . ($font->is_active ? '启用' : '禁用') . '</td>';
echo '<td>';
echo '<a href="#" class="button button-small preview-font" data-font-id="' . $font->id . '">预览</a> ';
echo '<a href="#" class="button button-small toggle-font" data-font-id="' . $font->id . '" data-status="' . $font->is_active . '">' . ($font->is_active ? '禁用' : '启用') . '</a> ';
echo '<a href="#" class="button button-small delete-font" data-font-id="' . $font->id . '">删除</a>';
echo '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
}
echo '</div>';
}
// 添加新字体页面
function add_new_font_page() {
echo '<div class="wrap">';
echo '<h1>添加新字体</h1>';
echo '<form method="post" enctype="multipart/form-data" id="font-upload-form">';
echo '<table class="form-table">';
echo '<tr>';
echo '<th><label for="font_name">字体名称</label></th>';
echo '<td><input type="text" id="font_name" name="font_name" class="regular-text" required></td>';
echo '</tr>';
echo '<tr>';
echo '<th><label for="font_family">字体族名称</label></th>';
echo '<td><input type="text" id="font_family" name="font_family" class="regular-text" required>';
echo '<p class="description">用于CSS font-family属性的名称,如 "MyCustomFont"</p></td>';
echo '</tr>';
echo '<tr>';
echo '<th><label for="font_license">字体许可证</label></th>';
echo '<td><textarea id="font_license" name="font_license" rows="4" class="large-text"></textarea>';
echo '<p class="description">请确保您有权使用和分发此字体</p></td>';
echo '</tr>';
echo '<tr>';
echo '<th><label>字体文件</label></th>';
echo '<td>';
echo '<p><label><input type="checkbox" name="font_formats[]" value="woff2"> WOFF2格式</label>';
echo '<input type="file" name="font_file_woff2" accept=".woff2"></p>';
echo '<p><label><input type="checkbox" name="font_formats[]" value="woff"> WOFF格式</label>';
echo '<input type="file" name="font_file_woff" accept=".woff"></p>';
echo '<p><label><input type="checkbox" name="font_formats[]" value="ttf"> TTF格式</label>';
echo '<input type="file" name="font_file_ttf" accept=".ttf"></p>';
echo '</td>';
echo '</tr>';
echo '</table>';
echo '<p class="submit">';
echo '<input type="submit" name="submit_font" class="button button-primary" value="上传字体">';
echo '</p>';
echo '</form>';
echo '</div>';
// 处理字体上传
if (isset($_POST['submit_font'])) {
handle_font_upload();
}
}
// 处理字体上传
function handle_font_upload() {
if (!current_user_can('manage_options')) {
wp_die('权限不足');
}
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$font_name = sanitize_text_field($_POST['font_name']);
$font_family = sanitize_text_field($_POST['font_family']);
$font_license = sanitize_textarea_field($_POST['font_license']);
// 创建字体目录
$upload_dir = wp_upload_dir();
$font_dir = $upload_dir['basedir'] . '/custom-fonts/' . sanitize_title($font_family);
if (!file_exists($font_dir)) {
wp_mkdir_p($font_dir);
}
$font_data = array(
'font_name' => $font_name,
'font_family' => $font_family,
'font_license' => $font_license
);
// 处理上传的文件
$formats = array('woff2', 'woff', 'ttf');
foreach ($formats as $format) {
$file_key = 'font_file_' . $format;
if (isset($_FILES[$file_key]) && $_FILES[$file_key]['error'] === 0) {
$file = $_FILES[$file_key];
$filename = sanitize_file_name($font_family . '.' . $format);
$filepath = $font_dir . '/' . $filename;
if (move_uploaded_file($file['tmp_name'], $filepath)) {
$font_data['font_file_' . $format] = $upload_dir['baseurl'] . '/custom-fonts/' . sanitize_title($font_family) . '/' . $filename;
}
}
}
// 保存到数据库
$wpdb->insert($table_name, $font_data);
为了让用户能够在前端预览和管理字体,我们需要创建一个用户友好的界面:
// 创建字体预览器页面模板
function font_previewer_page_template($template) {
if (is_page('font-previewer')) {
$new_template = locate_template(array('page-font-previewer.php'));
if (!empty($new_template)) {
return $new_template;
}
}
return $template;
}
add_filter('template_include', 'font_previewer_page_template');
// 创建字体预览器页面内容
function create_font_previewer_page() {
$page_title = '字体预览器';
$page_content = '[font_previewer]';
$page_check = get_page_by_title($page_title);
if (!$page_check) {
$page_data = array(
'post_title' => $page_title,
'post_content' => $page_content,
'post_status' => 'publish',
'post_type' => 'page',
'post_name' => 'font-previewer'
);
wp_insert_post($page_data);
}
}
register_activation_hook(__FILE__, 'create_font_previewer_page');
// 字体预览器短代码
function font_previewer_shortcode() {
ob_start();
?>
<div class="font-previewer-container">
<div class="font-previewer-header">
<h1>在线字体预览器</h1>
<p>预览和管理您的字体库,实时查看字体效果</p>
</div>
<div class="font-previewer-controls">
<div class="control-group">
<label for="preview-text">预览文本:</label>
<input type="text" id="preview-text" value="字体的艺术在于表达" class="preview-control">
</div>
<div class="control-group">
<label for="font-size">字体大小:</label>
<input type="range" id="font-size" min="12" max="120" value="48" class="preview-control">
<span id="font-size-value">48px</span>
</div>
<div class="control-group">
<label for="font-color">字体颜色:</label>
<input type="color" id="font-color" value="#333333" class="preview-control">
</div>
<div class="control-group">
<label for="background-color">背景颜色:</label>
<input type="color" id="background-color" value="#ffffff" class="preview-control">
</div>
<div class="control-group">
<label for="font-weight">字重:</label>
<select id="font-weight" class="preview-control">
<option value="300">细体 (300)</option>
<option value="400" selected>常规 (400)</option>
<option value="600">中等 (600)</option>
<option value="700">粗体 (700)</option>
<option value="900">特粗 (900)</option>
</select>
</div>
<div class="control-group">
<label for="text-align">对齐方式:</label>
<select id="text-align" class="preview-control">
<option value="left">左对齐</option>
<option value="center" selected>居中</option>
<option value="right">右对齐</option>
<option value="justify">两端对齐</option>
</select>
</div>
</div>
<div class="font-previewer-main">
<div class="font-selector-sidebar">
<div class="font-categories">
<button class="category-btn active" data-category="all">全部字体</button>
<button class="category-btn" data-category="system">系统字体</button>
<button class="category-btn" data-category="google">Google字体</button>
<button class="category-btn" data-category="custom">自定义字体</button>
<button class="category-btn" data-category="favorites">收藏夹</button>
</div>
<div class="font-search">
<input type="text" id="font-search" placeholder="搜索字体...">
</div>
<div class="font-list" id="font-list">
<!-- 字体列表将通过AJAX加载 -->
<div class="loading-fonts">加载字体中...</div>
</div>
</div>
<div class="font-preview-area">
<div class="preview-display" id="preview-display">
<div class="preview-text" id="preview-text-display">
字体的艺术在于表达
</div>
</div>
<div class="preview-info">
<h3>字体信息</h3>
<div class="info-grid">
<div class="info-item">
<span class="info-label">字体名称:</span>
<span id="current-font-name">Arial</span>
</div>
<div class="info-item">
<span class="info-label">字体族:</span>
<span id="current-font-family">Arial, sans-serif</span>
</div>
<div class="info-item">
<span class="info-label">字体大小:</span>
<span id="current-font-size">48px</span>
</div>
<div class="info-item">
<span class="info-label">字重:</span>
<span id="current-font-weight">400</span>
</div>
</div>
<div class="preview-actions">
<button id="apply-font" class="button button-primary">应用此字体到网站</button>
<button id="save-preset" class="button">保存为预设</button>
<button id="share-preview" class="button">分享预览</button>
<button id="add-to-favorites" class="button">添加到收藏夹</button>
</div>
<div class="css-code">
<h4>CSS代码:</h4>
<pre id="css-code-output">font-family: Arial, sans-serif;
font-size: 48px;
font-weight: 400;
color: #333333;</pre>
<button id="copy-css" class="button button-small">复制CSS</button>
</div>
</div>
</div>
</div>
<div class="font-presets">
<h3>字体预设</h3>
<div class="presets-grid" id="presets-grid">
<!-- 预设将通过AJAX加载 -->
</div>
<button id="create-preset" class="button">创建新预设</button>
</div>
</div>
<?php
return ob_get_clean();
}
add_shortcode('font_previewer', 'font_previewer_shortcode');
// 添加AJAX处理函数
function get_fonts_ajax() {
$category = sanitize_text_field($_POST['category']);
$search = sanitize_text_field($_POST['search']);
$fonts = array();
// 获取系统字体
if ($category === 'all' || $category === 'system') {
$system_fonts = array(
array('name' => 'Arial', 'family' => 'Arial, sans-serif', 'category' => 'system'),
array('name' => 'Georgia', 'family' => 'Georgia, serif', 'category' => 'system'),
array('name' => 'Times New Roman', 'family' => 'Times New Roman, serif', 'category' => 'system'),
array('name' => 'Verdana', 'family' => 'Verdana, sans-serif', 'category' => 'system'),
array('name' => 'Courier New', 'family' => 'Courier New, monospace', 'category' => 'system'),
);
$fonts = array_merge($fonts, $system_fonts);
}
// 获取Google字体
if ($category === 'all' || $category === 'google') {
$google_fonts = array(
array('name' => 'Roboto', 'family' => 'Roboto, sans-serif', 'category' => 'google'),
array('name' => 'Open Sans', 'family' => 'Open Sans, sans-serif', 'category' => 'google'),
array('name' => 'Montserrat', 'family' => 'Montserrat, sans-serif', 'category' => 'google'),
array('name' => 'Lato', 'family' => 'Lato, sans-serif', 'category' => 'google'),
array('name' => 'Poppins', 'family' => 'Poppins, sans-serif', 'category' => 'google'),
array('name' => 'Source Sans Pro', 'family' => 'Source Sans Pro, sans-serif', 'category' => 'google'),
array('name' => 'Oswald', 'family' => 'Oswald, sans-serif', 'category' => 'google'),
array('name' => 'Raleway', 'family' => 'Raleway, sans-serif', 'category' => 'google'),
);
$fonts = array_merge($fonts, $google_fonts);
}
// 获取自定义字体
if ($category === 'all' || $category === 'custom') {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$custom_fonts = $wpdb->get_results("SELECT * FROM $table_name WHERE is_active = 1", ARRAY_A);
foreach ($custom_fonts as $font) {
$fonts[] = array(
'name' => $font['font_name'],
'family' => $font['font_family'],
'category' => 'custom',
'id' => $font['id']
);
}
}
// 应用搜索过滤
if (!empty($search)) {
$fonts = array_filter($fonts, function($font) use ($search) {
return stripos($font['name'], $search) !== false;
});
}
wp_send_json_success($fonts);
}
add_action('wp_ajax_get_fonts', 'get_fonts_ajax');
add_action('wp_ajax_nopriv_get_fonts', 'get_fonts_ajax');
// 保存字体预设
function save_font_preset_ajax() {
if (!is_user_logged_in()) {
wp_send_json_error('请先登录');
}
$preset_name = sanitize_text_field($_POST['preset_name']);
$font_family = sanitize_text_field($_POST['font_family']);
$font_size = sanitize_text_field($_POST['font_size']);
$font_color = sanitize_text_field($_POST['font_color']);
$font_weight = sanitize_text_field($_POST['font_weight']);
$user_id = get_current_user_id();
// 保存预设到用户meta
$presets = get_user_meta($user_id, 'font_presets', true);
if (empty($presets)) {
$presets = array();
}
$new_preset = array(
'id' => uniqid(),
'name' => $preset_name,
'font_family' => $font_family,
'font_size' => $font_size,
'font_color' => $font_color,
'font_weight' => $font_weight,
'created' => current_time('mysql')
);
$presets[] = $new_preset;
update_user_meta($user_id, 'font_presets', $presets);
wp_send_json_success($new_preset);
}
add_action('wp_ajax_save_font_preset', 'save_font_preset_ajax');
// 获取字体预设
function get_font_presets_ajax() {
if (!is_user_logged_in()) {
wp_send_json_success(array());
}
$user_id = get_current_user_id();
$presets = get_user_meta($user_id, 'font_presets', true);
if (empty($presets)) {
$presets = array();
}
wp_send_json_success($presets);
}
add_action('wp_ajax_get_font_presets', 'get_font_presets_ajax');
// 添加AJAX处理函数
function get_fonts_ajax() {
$category = sanitize_text_field($_POST['category']);
$search = sanitize_text_field($_POST['search']);
$fonts = array();
// 获取系统字体
if ($category === 'all' || $category === 'system') {
$system_fonts = array(
array('name' => 'Arial', 'family' => 'Arial, sans-serif', 'category' => 'system'),
array('name' => 'Georgia', 'family' => 'Georgia, serif', 'category' => 'system'),
array('name' => 'Times New Roman', 'family' => 'Times New Roman, serif', 'category' => 'system'),
array('name' => 'Verdana', 'family' => 'Verdana, sans-serif', 'category' => 'system'),
array('name' => 'Courier New', 'family' => 'Courier New, monospace', 'category' => 'system'),
);
$fonts = array_merge($fonts, $system_fonts);
}
// 获取Google字体
if ($category === 'all' || $category === 'google') {
$google_fonts = array(
array('name' => 'Roboto', 'family' => 'Roboto, sans-serif', 'category' => 'google'),
array('name' => 'Open Sans', 'family' => 'Open Sans, sans-serif', 'category' => 'google'),
array('name' => 'Montserrat', 'family' => 'Montserrat, sans-serif', 'category' => 'google'),
array('name' => 'Lato', 'family' => 'Lato, sans-serif', 'category' => 'google'),
array('name' => 'Poppins', 'family' => 'Poppins, sans-serif', 'category' => 'google'),
array('name' => 'Source Sans Pro', 'family' => 'Source Sans Pro, sans-serif', 'category' => 'google'),
array('name' => 'Oswald', 'family' => 'Oswald, sans-serif', 'category' => 'google'),
array('name' => 'Raleway', 'family' => 'Raleway, sans-serif', 'category' => 'google'),
);
$fonts = array_merge($fonts, $google_fonts);
}
// 获取自定义字体
if ($category === 'all' || $category === 'custom') {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$custom_fonts = $wpdb->get_results("SELECT * FROM $table_name WHERE is_active = 1", ARRAY_A);
foreach ($custom_fonts as $font) {
$fonts[] = array(
'name' => $font['font_name'],
'family' => $font['font_family'],
'category' => 'custom',
'id' => $font['id']
);
}
}
// 应用搜索过滤
if (!empty($search)) {
$fonts = array_filter($fonts, function($font) use ($search) {
return stripos($font['name'], $search) !== false;
});
}
wp_send_json_success($fonts);
}
add_action('wp_ajax_get_fonts', 'get_fonts_ajax');
add_action('wp_ajax_nopriv_get_fonts', 'get_fonts_ajax');
// 保存字体预设
function save_font_preset_ajax() {
if (!is_user_logged_in()) {
wp_send_json_error('请先登录');
}
$preset_name = sanitize_text_field($_POST['preset_name']);
$font_family = sanitize_text_field($_POST['font_family']);
$font_size = sanitize_text_field($_POST['font_size']);
$font_color = sanitize_text_field($_POST['font_color']);
$font_weight = sanitize_text_field($_POST['font_weight']);
$user_id = get_current_user_id();
// 保存预设到用户meta
$presets = get_user_meta($user_id, 'font_presets', true);
if (empty($presets)) {
$presets = array();
}
$new_preset = array(
'id' => uniqid(),
'name' => $preset_name,
'font_family' => $font_family,
'font_size' => $font_size,
'font_color' => $font_color,
'font_weight' => $font_weight,
'created' => current_time('mysql')
);
$presets[] = $new_preset;
update_user_meta($user_id, 'font_presets', $presets);
wp_send_json_success($new_preset);
}
add_action('wp_ajax_save_font_preset', 'save_font_preset_ajax');
// 获取字体预设
function get_font_presets_ajax() {
if (!is_user_logged_in()) {
wp_send_json_success(array());
}
$user_id = get_current_user_id();
$presets = get_user_meta($user_id, 'font_presets', true);
if (empty($presets)) {
$presets = array();
}
wp_send_json_success($presets);
}
add_action('wp_ajax_get_font_presets', 'get_font_presets_ajax');
// 创建js/font-previewer.js文件
jQuery(document).ready(function($) {
// 初始化变量
var currentFont = {
family: 'Arial, sans-serif',
name: 'Arial',
size: '48px',
color: '#333333',
weight: '400',
align: 'center',
backgroundColor: '#ffffff'
};
// 加载字体列表
function loadFonts(category, search) {
$('#font-list').html('<div class="loading-fonts">加载字体中...</div>');
$.ajax({
url: fontPreviewer.ajax_url,
type: 'POST',
data: {
action: 'get_fonts',
category: category,
search: search
},
success: function(response) {
if (response.success) {
renderFontList(response.data);
}
}
});
}
// 渲染字体列表
function renderFontList(fonts) {
var html = '';
if (fonts.length === 0) {
html = '<div class="no-fonts">未找到匹配的字体</div>';
} else {
fonts.forEach(function(font) {
var isActive = font.family === currentFont.family ? 'active' : '';
html += '<div class="font-item ' + isActive + '" data-font-family="' + font.family + '" data-font-name="' + font.name + '" data-category="' + font.category + '">';
html += '<div class="font-item-preview" style="font-family: ' + font.family + '">' + font.name + '</div>';
html += '<div class="font-item-name">' + font.name + '</div>';
html += '<div class="font-item-category ' + font.category + '">' + getCategoryLabel(font.category) + '</div>';
html += '</div>';
});
}
$('#font-list').html(html);
}
// 获取分类标签
function getCategoryLabel(category) {
var labels = {
'system': '系统',
'google': 'Google',
'custom': '自定义'
};
return labels[category] || category;
}
// 更新预览显示
function updatePreview() {
var $preview = $('#preview-text-display');
$preview.css({
'font-family': currentFont.family,
'font-size': currentFont.size,
'color': currentFont.color,
'font-weight': currentFont.weight,
'text-align': currentFont.align
});
$('#preview-display').css('background-color', currentFont.backgroundColor);
// 更新信息显示
$('#current-font-name').text(currentFont.name);
$('#current-font-family').text(currentFont.family);
$('#current-font-size').text(currentFont.size);
$('#current-font-weight').text(currentFont.weight);
// 更新CSS代码
updateCssCode();
}
// 更新CSS代码
function updateCssCode() {
var css = 'font-family: ' + currentFont.family + ';n';
css += 'font-size: ' + currentFont.size + ';n';
css += 'font-weight: ' + currentFont.weight + ';n';
css += 'color: ' + currentFont.color + ';';
if (currentFont.backgroundColor !== '#ffffff') {
css += 'nbackground-color: ' + currentFont.backgroundColor + ';';
}
if (currentFont.align !== 'left') {
css += 'ntext-align: ' + currentFont.align + ';';
}
$('#css-code-output').text(css);
}
// 初始化事件监听
function initEventListeners() {
// 字体选择
$(document).on('click', '.font-item', function() {
$('.font-item').removeClass('active');
$(this).addClass('active');
currentFont.family = $(this).data('font-family');
currentFont.name = $(this).data('font-name');
updatePreview();
});
// 分类过滤
$('.category-btn').click(function() {
$('.category-btn').removeClass('active');
$(this).addClass('active');
var category = $(this).data('category');
var search = $('#font-search').val();
loadFonts(category, search);
});
// 字体搜索
$('#font-search').on('input', function() {
var search = $(this).val();
var category = $('.category-btn.active').data('category');
loadFonts(category, search);
});
// 预览文本更改
$('#preview-text').on('input', function() {
$('#preview-text-display').text($(this).val());
});
// 字体大小更改
$('#font-size').on('input', function() {
var size = $(this).val() + 'px';
$('#font-size-value').text(size);
currentFont.size = size;
updatePreview();
});
// 字体颜色更改
$('#font-color').on('input', function() {
currentFont.color = $(this).val();
updatePreview();
});
// 背景颜色更改
$('#background-color').on('input', function() {
currentFont.backgroundColor = $(this).val();
updatePreview();
});
// 字重更改
$('#font-weight').change(function() {
currentFont.weight = $(this).val();
updatePreview();
});
// 对齐方式更改
// 创建js/font-previewer.js文件
jQuery(document).ready(function($) {
// 初始化变量
var currentFont = {
family: 'Arial, sans-serif',
name: 'Arial',
size: '48px',
color: '#333333',
weight: '400',
align: 'center',
backgroundColor: '#ffffff'
};
// 加载字体列表
function loadFonts(category, search) {
$('#font-list').html('<div class="loading-fonts">加载字体中...</div>');
$.ajax({
url: fontPreviewer.ajax_url,
type: 'POST',
data: {
action: 'get_fonts',
category: category,
search: search
},
success: function(response) {
if (response.success) {
renderFontList(response.data);
}
}
});
}
// 渲染字体列表
function renderFontList(fonts) {
var html = '';
if (fonts.length === 0) {
html = '<div class="no-fonts">未找到匹配的字体</div>';
} else {
fonts.forEach(function(font) {
var isActive = font.family === currentFont.family ? 'active' : '';
html += '<div class="font-item ' + isActive + '" data-font-family="' + font.family + '" data-font-name="' + font.name + '" data-category="' + font.category + '">';
html += '<div class="font-item-preview" style="font-family: ' + font.family + '">' + font.name + '</div>';
html += '<div class="font-item-name">' + font.name + '</div>';
html += '<div class="font-item-category ' + font.category + '">' + getCategoryLabel(font.category) + '</div>';
html += '</div>';
});
}
$('#font-list').html(html);
}
// 获取分类标签
function getCategoryLabel(category) {
var labels = {
'system': '系统',
'google': 'Google',
'custom': '自定义'
};
return labels[category] || category;
}
// 更新预览显示
function updatePreview() {
var $preview = $('#preview-text-display');
$preview.css({
'font-family': currentFont.family,
'font-size': currentFont.size,
'color': currentFont.color,
'font-weight': currentFont.weight,
'text-align': currentFont.align
});
$('#preview-display').css('background-color', currentFont.backgroundColor);
// 更新信息显示
$('#current-font-name').text(currentFont.name);
$('#current-font-family').text(currentFont.family);
$('#current-font-size').text(currentFont.size);
$('#current-font-weight').text(currentFont.weight);
// 更新CSS代码
updateCssCode();
}
// 更新CSS代码
function updateCssCode() {
var css = 'font-family: ' + currentFont.family + ';n';
css += 'font-size: ' + currentFont.size + ';n';
css += 'font-weight: ' + currentFont.weight + ';n';
css += 'color: ' + currentFont.color + ';';
if (currentFont.backgroundColor !== '#ffffff') {
css += 'nbackground-color: ' + currentFont.backgroundColor + ';';
}
if (currentFont.align !== 'left') {
css += 'ntext-align: ' + currentFont.align + ';';
}
$('#css-code-output').text(css);
}
// 初始化事件监听
function initEventListeners() {
// 字体选择
$(document).on('click', '.font-item', function() {
$('.font-item').removeClass('active');
$(this).addClass('active');
currentFont.family = $(this).data('font-family');
currentFont.name = $(this).data('font-name');
updatePreview();
});
// 分类过滤
$('.category-btn').click(function() {
$('.category-btn').removeClass('active');
$(this).addClass('active');
var category = $(this).data('category');
var search = $('#font-search').val();
loadFonts(category, search);
});
// 字体搜索
$('#font-search').on('input', function() {
var search = $(this).val();
var category = $('.category-btn.active').data('category');
loadFonts(category, search);
});
// 预览文本更改
$('#preview-text').on('input', function() {
$('#preview-text-display').text($(this).val());
});
// 字体大小更改
$('#font-size').on('input', function() {
var size = $(this).val() + 'px';
$('#font-size-value').text(size);
currentFont.size = size;
updatePreview();
});
// 字体颜色更改
$('#font-color').on('input', function() {
currentFont.color = $(this).val();
updatePreview();
});
// 背景颜色更改
$('#background-color').on('input', function() {
currentFont.backgroundColor = $(this).val();
updatePreview();
});
// 字重更改
$('#font-weight').change(function() {
currentFont.weight = $(this).val();
updatePreview();
});
// 对齐方式更改


