一步步教你,集成在线字体库预览与个性化网络字库管理工具到WordPress网站
引言:为什么网站需要字体管理工具?
在当今数字化时代,网站设计已成为品牌形象和用户体验的重要组成部分。字体作为视觉传达的核心元素之一,直接影响着网站的可读性、美观性和品牌一致性。然而,大多数网站开发者面临一个共同挑战:如何在保持设计灵活性的同时,确保字体加载效率和跨平台兼容性?
传统的字体管理方法通常依赖于系统默认字体或有限的网络字体库,这限制了设计师的创意表达。随着在线字体库的蓬勃发展,如Google Fonts、Adobe Fonts等提供了数千种高质量字体,但如何高效集成和管理这些资源成为了新的技术难题。
本文将详细介绍如何通过WordPress代码二次开发,集成在线字体库预览与个性化网络字库管理工具,使您的网站拥有专业级的字体管理能力,同时提升用户体验和设计自由度。
第一部分:准备工作与环境配置
1.1 理解WordPress字体管理现状
在开始开发之前,我们需要了解WordPress默认的字体处理方式。WordPress核心本身不提供高级字体管理功能,但通过主题和插件可以实现基本的字体控制。常见的方法包括:
- 主题自定义器中的字体选择器
- 通过CSS直接引入字体文件
- 使用插件如"Easy Google Fonts"或"Use Any Font"
然而,这些方法存在局限性:缺乏实时预览、字体库有限、管理不够直观等。我们的目标是创建一个更强大、更灵活的解决方案。
1.2 开发环境搭建
为了安全地进行代码二次开发,建议按照以下步骤配置开发环境:
-
创建子主题:避免直接修改父主题,确保更新不会丢失自定义功能
/* Theme Name: My Custom Theme Template: parent-theme-folder-name */ -
启用调试模式:在wp-config.php中设置开发模式
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); - 安装必要的开发工具:代码编辑器(如VS Code)、本地服务器环境(如XAMPP或Local by Flywheel)、Git版本控制系统
- 备份现有网站:在进行任何代码修改前,完整备份网站文件和数据库
1.3 确定技术架构
我们的字体管理工具将采用以下技术架构:
- 前端:HTML5、CSS3、JavaScript(使用Vue.js或React简化交互开发)
- 后端:PHP(WordPress核心语言)
- 数据存储:WordPress自定义数据库表 + 选项API
- API集成:连接Google Fonts API和其他字体服务API
- 缓存机制:Transients API提高性能
第二部分:创建字体管理核心功能
2.1 设计数据库结构
我们需要创建自定义数据库表来存储用户字体配置和收藏。在主题的functions.php中添加以下代码:
function create_font_management_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'custom_fonts';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
font_name varchar(255) NOT NULL,
font_family varchar(255) NOT NULL,
font_source varchar(100) DEFAULT 'google',
font_variants text,
font_subsets text,
is_active tinyint(1) DEFAULT 1,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 创建字体使用记录表
$usage_table = $wpdb->prefix . 'font_usage';
$sql_usage = "CREATE TABLE IF NOT EXISTS $usage_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
font_id mediumint(9) NOT NULL,
element_type varchar(100),
element_selector varchar(255),
user_id bigint(20),
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (font_id) REFERENCES $table_name(id) ON DELETE CASCADE
) $charset_collate;";
dbDelta($sql_usage);
}
add_action('after_setup_theme', 'create_font_management_tables');
2.2 集成Google Fonts API
Google Fonts提供了丰富的免费字体库和易于使用的API。我们将创建一个类来处理与Google Fonts API的交互:
class Google_Fonts_Integration {
private $api_key = ''; // 可选,如果需要更高API限制
private $api_url = 'https://www.googleapis.com/webfonts/v1/webfonts';
public function __construct() {
// 初始化方法
}
public function get_all_fonts($sort = 'popularity') {
$transient_key = 'google_fonts_list_' . $sort;
$fonts = get_transient($transient_key);
if (false === $fonts) {
$url = $this->api_url . '?sort=' . $sort;
if (!empty($this->api_key)) {
$url .= '&key=' . $this->api_key;
}
$response = wp_remote_get($url);
if (is_wp_error($response)) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (isset($data['items'])) {
$fonts = $data['items'];
set_transient($transient_key, $fonts, WEEK_IN_SECONDS);
}
}
return $fonts;
}
public function generate_font_import_url($font_family, $variants = array(), $subsets = array()) {
$base_url = 'https://fonts.googleapis.com/css2';
$family_param = urlencode($font_family);
if (!empty($variants)) {
$variant_str = implode(',', $variants);
$family_param .= ':wght@' . $variant_str;
}
$query_args = array('family' => $family_param);
if (!empty($subsets)) {
$query_args['subset'] = implode(',', $subsets);
}
return add_query_arg($query_args, $base_url);
}
}
2.3 创建字体预览功能
实时预览是字体管理工具的核心功能。我们将创建一个交互式预览界面:
function enqueue_font_preview_assets() {
// 仅在需要字体管理的页面加载资源
if (is_admin() || current_user_can('edit_theme_options')) {
wp_enqueue_style('font-preview-admin', get_template_directory_uri() . '/css/font-preview.css');
wp_enqueue_script('vue-js', 'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js', array(), '2.6.14', true);
wp_enqueue_script('font-preview-app', get_template_directory_uri() . '/js/font-preview.js', array('vue-js', 'jquery'), '1.0.0', true);
// 传递数据到JavaScript
wp_localize_script('font-preview-app', 'fontPreviewData', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('font_preview_nonce'),
'default_text' => __('The quick brown fox jumps over the lazy dog', 'textdomain'),
'font_categories' => array('serif', 'sans-serif', 'display', 'handwriting', 'monospace')
));
}
}
add_action('admin_enqueue_scripts', 'enqueue_font_preview_assets');
创建预览界面的HTML结构:
<div id="font-preview-app" class="font-management-wrapper">
<div class="font-preview-container">
<div class="font-controls">
<div class="font-search">
<input type="text" v-model="searchQuery" placeholder="搜索字体...">
<select v-model="selectedCategory">
<option value="">所有分类</option>
<option v-for="category in categories" :value="category">{{ category }}</option>
</select>
<select v-model="selectedSort">
<option value="popularity">最受欢迎</option>
<option value="trending">趋势</option>
<option value="alpha">字母顺序</option>
</select>
</div>
<div class="preview-controls">
<div class="text-input">
<textarea v-model="previewText" placeholder="输入预览文本"></textarea>
</div>
<div class="size-control">
<label>字体大小:</label>
<input type="range" v-model="fontSize" min="12" max="72" step="1">
<span>{{ fontSize }}px</span>
</div>
</div>
</div>
<div class="font-grid">
<div v-for="font in filteredFonts" :key="font.family" class="font-card" :class="{ active: isFontActive(font.family) }">
<div class="font-preview" :style="{ fontFamily: font.family, fontSize: fontSize + 'px' }">
{{ previewText || defaultText }}
</div>
<div class="font-info">
<h3>{{ font.family }}</h3>
<div class="font-actions">
<button @click="toggleFont(font)" class="button">
{{ isFontActive(font.family) ? '已启用' : '启用' }}
</button>
<button @click="showVariants(font)" class="button button-secondary">
变体
</button>
</div>
</div>
</div>
</div>
<div class="pagination" v-if="totalPages > 1">
<button @click="prevPage" :disabled="currentPage === 1">上一页</button>
<span>第 {{ currentPage }} 页,共 {{ totalPages }} 页</span>
<button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
</div>
</div>
<!-- 字体变体选择模态框 -->
<div v-if="showVariantModal" class="modal-overlay">
<div class="modal-content">
<h2>选择字体变体: {{ selectedFont.family }}</h2>
<div class="variant-grid">
<div v-for="variant in selectedFont.variants" :key="variant" class="variant-option">
<input type="checkbox" :id="'variant-' + variant" :value="variant" v-model="selectedVariants">
<label :for="'variant-' + variant" :style="{ fontFamily: selectedFont.family, fontWeight: variant }">
{{ getVariantName(variant) }}
</label>
</div>
</div>
<div class="modal-actions">
<button @click="applyVariants" class="button button-primary">应用</button>
<button @click="closeModal" class="button">取消</button>
</div>
</div>
</div>
</div>
第三部分:实现个性化字体管理
3.1 创建字体管理界面
在WordPress后台添加自定义菜单页面,用于管理字体:
function add_font_management_page() {
add_menu_page(
'字体管理',
'字体管理',
'manage_options',
'font-management',
'render_font_management_page',
'dashicons-editor-textcolor',
30
);
add_submenu_page(
'font-management',
'我的字体库',
'我的字体库',
'manage_options',
'font-library',
'render_font_library_page'
);
add_submenu_page(
'font-management',
'字体设置',
'字体设置',
'manage_options',
'font-settings',
'render_font_settings_page'
);
}
add_action('admin_menu', 'add_font_management_page');
function render_font_management_page() {
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<div id="font-management-app">
<!-- 这里将加载Vue.js应用 -->
</div>
</div>
<?php
}
3.2 实现AJAX字体处理
处理字体启用/禁用、保存配置等操作:
// 处理字体启用/禁用
add_action('wp_ajax_toggle_font', 'handle_toggle_font');
function handle_toggle_font() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'font_preview_nonce')) {
wp_die('安全验证失败');
}
$font_family = sanitize_text_field($_POST['font_family']);
$variants = isset($_POST['variants']) ? array_map('sanitize_text_field', $_POST['variants']) : array('regular');
$action = sanitize_text_field($_POST['action_type']); // 'enable' 或 'disable'
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
if ($action === 'enable') {
// 检查是否已存在
$existing = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $table_name WHERE font_family = %s",
$font_family
));
if (!$existing) {
$wpdb->insert(
$table_name,
array(
'font_name' => $font_family,
'font_family' => $font_family,
'font_variants' => json_encode($variants),
'is_active' => 1
),
array('%s', '%s', '%s', '%d')
);
} else {
$wpdb->update(
$table_name,
array('is_active' => 1, 'font_variants' => json_encode($variants)),
array('id' => $existing),
array('%d', '%s'),
array('%d')
);
}
// 更新CSS文件
update_font_css_file();
wp_send_json_success(array('message' => '字体已启用'));
} else {
$wpdb->update(
$table_name,
array('is_active' => 0),
array('font_family' => $font_family),
array('%d'),
array('%s')
);
update_font_css_file();
wp_send_json_success(array('message' => '字体已禁用'));
}
}
// 更新字体CSS文件
function update_font_css_file() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$active_fonts = $wpdb->get_results(
"SELECT font_family, font_variants, font_source FROM $table_name WHERE is_active = 1"
);
$css_content = "/* 动态生成的字体CSS - 最后更新: " . date('Y-m-d H:i:s') . " */nn";
foreach ($active_fonts as $font) {
$variants = json_decode($font->font_variants, true);
if ($font->font_source === 'google') {
$font_integration = new Google_Fonts_Integration();
$import_url = $font_integration->generate_font_import_url($font->font_family, $variants);
$css_content .= "@import url('" . esc_url($import_url) . "');n";
}
// 为每个字体生成CSS类
$font_class = sanitize_title($font->font_family);
$css_content .= ".font-" . $font_class . " { font-family: '" . $font->font_family . "', sans-serif; }n";
}
// 保存到文件
$upload_dir = wp_upload_dir();
$font_css_path = $upload_dir['basedir'] . '/dynamic-fonts.css';
file_put_contents($font_css_path, $css_content);
// 更新选项记录文件路径
update_option('dynamic_font_css_path', $upload_dir['baseurl'] . '/dynamic-fonts.css');
}
3.3 集成自定义字体上传
除了在线字体库,用户可能希望上传自己的字体文件:
function handle_custom_font_upload() {
if (!current_user_can('upload_files')) {
wp_die('权限不足');
}
if (!wp_verify_nonce($_POST['_wpnonce'], 'custom_font_upload')) {
wp_die('安全验证失败');
}
$font_file = $_FILES['font_file'];
// 检查文件类型
$allowed_types = array('ttf', 'otf', 'woff', 'woff2', 'eot');
$file_ext = pathinfo($font_file['name'], PATHINFO_EXTENSION);
if (!in_array(strtolower($file_ext), $allowed_types)) {
wp_send_json_error(array('message' => '不支持的文件类型'));
}
// 处理上传
require_once(ABSPATH . 'wp-admin/includes/file.php');
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($font_file, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
// 保存字体信息到数据库
$font_name = sanitize_text_field($_POST['font_name']);
$font_family = !empty($_POST['font_family']) ?
sanitize_text_field($_POST['font_family']) : $font_name;
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$wpdb->insert(
$table_name,
array(
'font_name' => $font_name,
'font_family' => $font_family,
'font_source' => 'custom',
'font_variants' => json_encode(array('regular', 'bold')),
'font_file_url' => $movefile['url'],
'is_active' => 1
),
array('%s', '%s', '%s', '%s', '%s', '%d')
);
// 生成@font-face规则
generate_custom_fontface_css($font_family, $movefile['url'], $file_ext);
wp_send_json_success(array(
'message' => '字体上传成功',
'font_family' => $font_family,
'file_url' => $movefile['url']
));
} else {
wp_send_json_error(array('message' => $movefile['error']));
}
}
add_action('wp_ajax_upload_custom_font', 'handle_custom_font_upload');
function generate_custom_fontface_css($font_family, $font_url, $font_ext) {
$css_content = "n/* 自定义字体: " . $font_family . " */n";
$css_content .= "@font-face {n";
$css_content .= " font-family: '" . $font_family . "';n";
$css_content .= " src: url('" . $font_url . "') format('" . get_font_format($font_ext) . "');n";
$css_content .= " font-weight: normal;n";
$css_content .= " font-style: normal;n";
$css_content .= " font-display: swap;n";
$css_content .= "}nn";
// 追加到动态字体CSS文件
$upload_dir = wp_upload_dir();
$font_css_path = $upload_dir['basedir'] . '/dynamic-fonts.css';
if (file_exists($font_css_path)) {
file_put_contents($font_css_path, $css_content, FILE_APPEND);
}
}
function get_font_format($extension) {
$formats = array(
'ttf' => 'truetype',
'otf' => 'opentype',
'woff' => 'woff',
'woff2' => 'woff2',
'eot' => 'embedded-opentype'
);
return isset($formats[strtolower($extension)]) ?
$formats[strtolower($extension)] : 'truetype';
}
第四部分:优化字体加载与性能
4.1 实现字体加载优化策略
字体加载是影响网站性能的关键因素。我们将实施多种优化策略:
class Font_Performance_Optimizer {
public function __construct() {
add_action('wp_head', array($this, 'add_font_preload_tags'), 1);
add_action('wp_enqueue_scripts', array($this, 'optimize_font_loading'));
}
public function add_font_preload_tags() {
$active_fonts = $this->get_critical_fonts();
foreach ($active_fonts as $font) {
if ($font['source'] === 'google') {
// 预加载关键字体文件
echo '<link rel="preload" as="style" href="' .
esc_url($font['url']) . '" crossorigin>';
// 添加预连接到Google Fonts域名
echo '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>';
} elseif ($font['source'] === 'custom') {
echo '<link rel="preload" as="font" href="' .
esc_url($font['url']) . '" type="font/' .
esc_attr($font['format']) . '" crossorigin>';
}
}
}
public function optimize_font_loading() {
// 延迟加载非关键字体
$font_css_url = get_option('dynamic_font_css_path');
if ($font_css_url) {
// 使用media="print"技巧延迟加载
wp_register_style('dynamic-fonts-print', $font_css_url, array(), null, 'print');
wp_enqueue_style('dynamic-fonts-print');
// 加载后切换到all媒体类型
wp_add_inline_script('jquery', '
(function() {
var fontStylesheet = document.querySelector("link[media='print']");
if (fontStylesheet) {
fontStylesheet.media = "all";
}
})();
');
}
}
private function get_critical_fonts() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_fonts';
$fonts = $wpdb->get_results(
"SELECT font_family, font_source, font_file_url FROM $table_name
WHERE is_active = 1 AND is_critical = 1",
ARRAY_A
);
return $fonts;
}
// 实现字体缓存机制
public static function cache_font_files($font_url, $font_family) {
$upload_dir = wp_upload_dir();
$cache_dir = $upload_dir['basedir'] . '/font-cache/';
// 创建缓存目录
if (!file_exists($cache_dir)) {
wp_mkdir_p($cache_dir);
}
$cache_key = md5($font_url . $font_family);
$cache_file = $cache_dir . $cache_key . '.css';
// 检查缓存是否有效(24小时)
if (file_exists($cache_file) &&
(time() - filemtime($cache_file)) < DAY_IN_SECONDS) {
return str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $cache_file);
}
// 下载并缓存字体CSS
$response = wp_remote_get($font_url);
if (!is_wp_error($response)) {
$font_css = wp_remote_retrieve_body($response);
// 本地化字体文件URL
$font_css = self::localize_font_urls($font_css, $font_family);
file_put_contents($cache_file, $font_css);
return str_replace($upload_dir['basedir'], $upload_dir['baseurl'], $cache_file);
}
return $font_url; // 失败时返回原始URL
}
private static function localize_font_urls($css_content, $font_family) {
// 匹配字体URL并下载到本地
preg_match_all('/url((https?://[^)]+))/', $css_content, $matches);
if (!empty($matches[1])) {
$upload_dir = wp_upload_dir();
$font_dir = $upload_dir['basedir'] . '/fonts/' . sanitize_title($font_family) . '/';
if (!file_exists($font_dir)) {
wp_mkdir_p($font_dir);
}
foreach ($matches[1] as $font_url) {
$font_filename = basename(parse_url($font_url, PHP_URL_PATH));
$local_font_path = $font_dir . $font_filename;
// 下载字体文件
if (!file_exists($local_font_path)) {
$font_data = wp_remote_get($font_url);
if (!is_wp_error($font_data)) {
file_put_contents($local_font_path, wp_remote_retrieve_body($font_data));
}
}
// 替换URL为本地路径
$local_font_url = str_replace(
$upload_dir['basedir'],
$upload_dir['baseurl'],
$local_font_path
);
$css_content = str_replace($font_url, $local_font_url, $css_content);
}
}
return $css_content;
}
}
new Font_Performance_Optimizer();
4.2 实现字体使用分析
了解字体使用情况有助于优化决策:
class Font_Analytics {
public function __construct() {
add_action('wp_footer', array($this, 'track_font_usage'));
add_action('admin_menu', array($this, 'add_analytics_page'));
}
public function track_font_usage() {
if (!current_user_can('manage_options')) {
return;
}
?>
<script>
(function() {
// 检测页面中使用的字体
var usedFonts = new Set();
// 检查所有元素的计算字体
var allElements = document.querySelectorAll('*');
allElements.forEach(function(el) {
var computedStyle = window.getComputedStyle(el);
var fontFamily = computedStyle.fontFamily;
if (fontFamily && fontFamily !== 'inherit') {
// 提取字体族名称(去除引号和备用字体)
var fonts = fontFamily.split(',')[0].replace(/['"]/g, '').trim();
if (fonts) {
usedFonts.add(fonts);
}
}
});
// 发送使用数据到服务器
if (usedFonts.size > 0) {
var data = {
action: 'track_font_usage',
fonts: Array.from(usedFonts),
page_url: window.location.href,
nonce: '<?php echo wp_create_nonce("font_analytics_nonce"); ?>'
};
// 使用navigator.sendBeacon确保数据发送
if (navigator.sendBeacon) {
var formData = new FormData();
for (var key in data) {
formData.append(key, data[key]);
}
navigator.sendBeacon('<?php echo admin_url("admin-ajax.php"); ?>', formData);
}
}
})();
</script>
<?php
}
public static function handle_usage_tracking() {
if (!wp_verify_nonce($_POST['nonce'], 'font_analytics_nonce')) {
wp_die('安全验证失败');
}
$fonts = isset($_POST['fonts']) ? array_map('sanitize_text_field', $_POST['fonts']) : array();
$page_url = sanitize_url($_POST['page_url']);
$user_id = get_current_user_id();
global $wpdb;
$usage_table = $wpdb->prefix . 'font_usage';
$fonts_table = $wpdb->prefix . 'custom_fonts';
foreach ($fonts as $font_family) {
// 查找字体ID
$font_id = $wpdb->get_var($wpdb->prepare(
"SELECT id FROM $fonts_table WHERE font_family = %s",
$font_family
));
if ($font_id) {
// 记录使用情况
$wpdb->insert(
$usage_table,
array(
'font_id' => $font_id,
'page_url' => $page_url,
'user_id' => $user_id
),
array('%d', '%s', '%d')
);
}
}
wp_die();
}
public function add_analytics_page() {
add_submenu_page(
'font-management',
'字体分析',
'字体分析',
'manage_options',
'font-analytics',
array($this, 'render_analytics_page')
);
}
public function render_analytics_page() {
?>
<div class="wrap">
<h1>字体使用分析</h1>
<div class="analytics-container">
<div class="analytics-stats">
<?php $this->display_font_statistics(); ?>
</div>
<div class="analytics-charts">
<canvas id="fontUsageChart" width="400" height="200"></canvas>
</div>
<div class="analytics-table">
<?php $this->display_font_usage_table(); ?>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
jQuery(document).ready(function($) {
var ctx = document.getElementById('fontUsageChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: <?php echo json_encode($this->get_font_labels()); ?>,
datasets: [{
label: '使用次数',
data: <?php echo json_encode($this->get_font_usage_data()); ?>,
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
});
</script>
<?php
}
private function display_font_statistics() {
global $wpdb;
$fonts_table = $wpdb->prefix . 'custom_fonts';
$usage_table = $wpdb->prefix . 'font_usage';
$total_fonts = $wpdb->get_var("SELECT COUNT(*) FROM $fonts_table WHERE is_active = 1");
$total_usage = $wpdb->get_var("SELECT COUNT(*) FROM $usage_table");
$most_used = $wpdb->get_row(
"SELECT f.font_family, COUNT(u.id) as usage_count
FROM $usage_table u
JOIN $fonts_table f ON u.font_id = f.id
GROUP BY u.font_id
ORDER BY usage_count DESC
LIMIT 1"
);
echo '<div class="stat-card">';
echo '<h3>活跃字体数量</h3>';
echo '<p class="stat-number">' . $total_fonts . '</p>';
echo '</div>';
echo '<div class="stat-card">';
echo '<h3>总使用次数</h3>';
echo '<p class="stat-number">' . $total_usage . '</p>';
echo '</div>';
if ($most_used) {
echo '<div class="stat-card">';
echo '<h3>最常用字体</h3>';
echo '<p class="stat-number">' . esc_html($most_used->font_family) . '</p>';
echo '<p class="stat-desc">使用次数: ' . $most_used->usage_count . '</p>';
echo '</div>';
}
}
}
add_action('wp_ajax_track_font_usage', array('Font_Analytics', 'handle_usage_tracking'));
add_action('wp_ajax_nopriv_track_font_usage', array('Font_Analytics', 'handle_usage_tracking'));
第五部分:创建前端字体选择器组件
5.1 开发可视化字体选择器
为内容编辑器和前端用户提供字体选择功能:
class Frontend_Font_Selector {
public function __construct() {
// 为古腾堡编辑器添加字体选择控件
add_action('enqueue_block_editor_assets', array($this, 'add_block_editor_font_controls'));
// 为经典编辑器添加字体下拉菜单
add_filter('mce_buttons_2', array($this, 'add_font_select_to_tinymce'));
add_filter('tiny_mce_before_init', array($this, 'customize_tinymce_fonts'));
// 前端字体选择器短代码
add_shortcode('font_selector', array($this, 'render_font_selector_shortcode'));
}
public function add_block_editor_font_controls() {
wp_enqueue_script(
'gutenberg-font-controls',
get_template_directory_uri() . '/js/gutenberg-font-controls.js',
array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor', 'wp-data'),
'1.0.0',
true
);
// 传递可用字体列表
$active_fonts = $this->get_active_fonts();
wp_localize_script('gutenberg-font-controls', 'fontControlsData', array(
'fonts' => $active_fonts,
'defaultFont' => get_theme_mod('primary_font', 'Arial, sans-serif')
));
// 添加编辑器样式
$font_css_url = get_option('dynamic_font_css_path');
if ($font_css_url) {
wp_enqueue_style('editor-fonts', $font_css_url);
}
}
public function add_font_select_to_tinymce($buttons) {
array_unshift($buttons, 'fontselect');
return $buttons;
}
public function customize_tinymce_fonts($init) {
$active_fonts = $this->get_active_fonts();
$font_formats = '';
foreach ($active_fonts as $font) {
$font_formats .= $font['name'] . '=' . $font['family'] . ';';
}
// 添加默认字体
$font_formats .= 'Arial=arial,helvetica,sans-serif;';
$font_formats .= 'Times New Roman=times new roman,times,serif;';
$init['font_formats'] = $font_formats;
$init['fontsize_formats'] = "8px 10px 12px 14px 16px 18px 20px 24px 28px 32px 36px 48px";
return $init;
}
public function render_font_selector_shortcode($atts) {
$atts = shortcode_atts(array(
'type' => 'dropdown', // dropdown, preview, or inline
'category' => '',
