古腾堡区块增加支持自定义字体

主题字体注册实现

在主题的functions.php中建立字体管理系统:

class Theme_Font_Manager {
    private $custom_fonts = [];
    
    public function __construct() {
        add_action('init', [$this, 'register_custom_fonts']);
        add_action('enqueue_block_editor_assets', [$this, 'enqueue_font_assets']);
        add_filter('block_editor_settings_all', [$this, 'add_font_settings']);
    }
    
    public function register_custom_fonts() {
        $this->custom_fonts = apply_filters('theme_custom_fonts', [
            'custom-sans' => [
                'name' => '自定义无衬线体',
                'family' => 'Custom Sans, system-ui, sans-serif',
                'weights' => [300, 400, 600, 700],
                'styles' => ['normal', 'italic'],
                'src' => get_template_directory_uri() . '/fonts/custom-sans.woff2'
            ],
            'custom-serif' => [
                'name' => '自定义衬线体',
                'family' => 'Custom Serif, Georgia, serif',
                'weights' => [400, 600],
                'styles' => ['normal'],
                'src' => get_template_directory_uri() . '/fonts/custom-serif.woff2'
            ]
        ]);
    }
    
    public function enqueue_font_assets() {
        foreach ($this->custom_fonts as $font_slug => $font_data) {
            wp_enqueue_style(
                "font-{$font_slug}",
                $font_data['src'],
                [],
                THEME_VERSION
            );
        }
    }
    
    public function add_font_settings($settings) {
        $settings['fontFamilies'] = array_merge(
            $settings['fontFamilies'] ?? [],
            $this->prepare_font_families()
        );
        return $settings;
    }
    
    private function prepare_font_families() {
        $families = [];
        foreach ($this->custom_fonts as $font_slug => $font_data) {
            $families[] = [
                'name' => $font_data['name'],
                'slug' => $font_slug,
                'fontFamily' => $font_data['family'],
                'fontWeight' => $font_data['weights'][0] ?? 400,
                'fontStyle' => $font_data['styles'][0] ?? 'normal'
            ];
        }
        return $families;
    }
}
new Theme_Font_Manager();

字体CSS生成系统

创建动态字体样式输出:

function generate_custom_font_styles() {
    $font_manager = new Theme_Font_Manager();
    $fonts = $font_manager->get_registered_fonts();
    $css = '';
    
    foreach ($fonts as $font_slug => $font_data) {
        $css .= "@font-face {
            font-family: '{$font_data['family']}';
            src: url('{$font_data['src']}') format('woff2');
            font-weight: 100 900;
            font-style: normal;
            font-display: swap;
        }\n";
        
        // 为古腾堡编辑器生成样式
        $css .= ".has-{$font_slug}-font-family {
            font-family: {$font_data['family']};
        }\n";
    }
    
    wp_add_inline_style('theme-fonts', $css);
}
add_action('wp_enqueue_scripts', 'generate_custom_font_styles');
add_action('enqueue_block_editor_assets', 'generate_custom_font_styles');

区块编辑器集成

字体选择器增强

创建自定义字体选择器组件:

const { SelectControl } = wp.components;
const { withSelect } = wp.data;

const CustomFontSelector = withSelect((select) => {
    return {
        fontFamilies: select('core/block-editor').getSettings().fontFamilies || []
    };
})(({ fontFamilies, value, onChange, label = '选择字体' }) => {
    const options = [
        { label: '默认字体', value: '' },
        ...fontFamilies.map(font => ({
            label: font.name,
            value: font.slug
        }))
    ];
    
    return (
        <SelectControl
            label={label}
            value={value}
            options={options}
            onChange={onChange}
        />
    );
});

// 注册到区块侧边栏
wp.hooks.addFilter('editor.BlockEdit', 'theme/custom-font-control', (BlockEdit) => {
    return (props) => {
        if (props.name === 'core/paragraph') {
            return (
                <>
                    <BlockEdit {...props} />
                    <InspectorControls>
                        <PanelBody title="字体设置">
                            <CustomFontSelector
                                value={props.attributes.fontFamily}
                                onChange={(value) => {
                                    props.setAttributes({ fontFamily: value });
                                }}
                            />
                        </PanelBody>
                    </InspectorControls>
                </>
            );
        }
        return <BlockEdit {...props} />;
    };
});

实时字体预览

实现编辑器内的字体预览:

const FontPreview = ({ fontFamily, fontSize, content = '预览文本' }) => {
    const style = {
        fontFamily: fontFamily || 'inherit',
        fontSize: fontSize || '16px',
        padding: '8px',
        border: '1px solid #ddd',
        borderRadius: '4px',
        marginBottom: '8px'
    };
    
    return (
        <div style={style}>
            {content}
        </div>
    );
};

// 在字体选择器中使用预览
const EnhancedFontSelector = ({ value, onChange }) => {
    const [previewFont, setPreviewFont] = useState(value);
    
    return (
        <div>
            <FontPreview fontFamily={previewFont} />
            <CustomFontSelector
                value={value}
                onChange={(newValue) => {
                    setPreviewFont(newValue);
                    onChange(newValue);
                }}
            />
        </div>
    );
};

高级字体控制

可变字体支持

集成可变字体到古腾堡编辑器:

function register_variable_fonts_support() {
    add_theme_support('variable-fonts', [
        'inter-var' => [
            'name' => 'Inter Variable',
            'family' => 'Inter Variable, sans-serif',
            'axes' => [
                'wght' => [100, 900],
                'ital' => [0, 1]
            ],
            'src' => get_template_directory_uri() . '/fonts/Inter.var.woff2'
        ]
    ]);
}
add_action('after_setup_theme', 'register_variable_fonts_support');

字体轴控制界面

创建可变字体轴控制组件:

const FontAxisControl = ({ axis, min, max, value, onChange, label }) => {
    return (
        <BaseControl label={label}>
            <RangeControl
                value={value}
                onChange={onChange}
                min={min}
                max={max}
            />
            <div style={{ fontSize: '12px', color: '#757575' }}>
                当前值: {value}
            </div>
        </BaseControl>
    );
};

const VariableFontControls = ({ attributes, setAttributes }) => {
    const { fontWeight = 400, fontWidth = 100 } = attributes;
    
    return (
        <PanelBody title="可变字体设置">
            <FontAxisControl
                label="字重"
                axis="wght"
                min={100}
                max={900}
                value={fontWeight}
                onChange={(value) => setAttributes({ fontWeight: value })}
            />
            <FontAxisControl
                label="字宽"
                axis="wdth"
                min={75}
                max={125}
                value={fontWidth}
                onChange={(value) => setAttributes({ fontWidth: value })}
            />
        </PanelBody>
    );
};

字体加载优化

性能优化策略

实现智能字体加载:

class Font_Loading_Optimizer {
    public function __construct() {
        add_action('wp_head', [$this, 'add_preload_links']);
        add_filter('wp_resource_hints', [$this, 'add_dns_prefetch'], 10, 2);
    }
    
    public function add_preload_links() {
        $fonts = apply_filters('theme_preload_fonts', []);
        foreach ($fonts as $font) {
            echo '<link rel="preload" href="' . esc_url($font['src']) . '" as="font" type="font/woff2" crossorigin>';
        }
    }
    
    public function add_dns_prefetch($hints, $relation_type) {
        if ('dns-prefetch' === $relation_type) {
            $font_domains = apply_filters('theme_font_domains', []);
            foreach ($font_domains as $domain) {
                $hints[] = $domain;
            }
        }
        return $hints;
    }
}
new Font_Loading_Optimizer();

字体加载状态检测

const useFontLoading = (fontFamily) => {
    const [isLoaded, setIsLoaded] = useState(false);
    
    useEffect(() => {
        if (!fontFamily) return;
        
        const checkFont = async () => {
            try {
                await document.fonts.load(`16px "${fontFamily}"`);
                setIsLoaded(true);
            } catch (error) {
                console.warn('字体加载失败:', error);
            }
        };
        
        checkFont();
    }, [fontFamily]);
    
    return isLoaded;
};

const FontLoadingIndicator = ({ fontFamily }) => {
    const isLoaded = useFontLoading(fontFamily);
    
    return (
        <div style={{
            opacity: isLoaded ? 1 : 0.5,
            transition: 'opacity 0.3s ease'
        }}>
            {isLoaded ? '✓' : '⏳'}
        </div>
    );
};

多语言字体支持

语言特定字体配置

function language_specific_fonts() {
    $language_fonts = [
        'zh-CN' => [
            'fontFamily' => 'Noto Sans SC, sans-serif',
            'src' => get_template_directory_uri() . '/fonts/noto-sans-sc.woff2'
        ],
        'ja' => [
            'fontFamily' => 'Noto Sans JP, sans-serif',
            'src' => get_template_directory_uri() . '/fonts/noto-sans-jp.woff2'
        ],
        'ko' => [
            'fontFamily' => 'Noto Sans KR, sans-serif',
            'src' => get_template_directory_uri() . '/fonts/noto-sans-kr.woff2'
        ]
    ];
    
    return $language_fonts;
}
add_filter('theme_language_fonts', 'language_specific_fonts');

自动语言检测

const LanguageAwareFontSelector = ({ value, onChange }) => {
    const [language, setLanguage] = useState('en');
    
    useEffect(() => {
        // 检测页面语言
        const detectedLanguage = document.documentElement.lang || 'en';
        setLanguage(detectedLanguage);
    }, []);
    
    const languageFonts = useSelect((select) => {
        return select('core/editor').getEditorSettings().languageFonts || {};
    });
    
    const options = useMemo(() => {
        const baseOptions = [{ label: '默认字体', value: '' }];
        const langFonts = languageFonts[language] || [];
        
        return [
            ...baseOptions,
            ...langFonts.map(font => ({
                label: font.name,
                value: font.slug
            }))
        ];
    }, [language, languageFonts]);
    
    return (
        <SelectControl
            label="语言适配字体"
            value={value}
            options={options}
            onChange={onChange}
        />
    );
};

字体回退系统

兼容性处理

function font_fallback_system() {
    $fallback_styles = '';
    $fonts = get_theme_fonts();
    
    foreach ($fonts as $font_slug => $font_data) {
        $fallback_styles .= "
            .has-{$font_slug}-font-family {
                font-family: {$font_data['family']};
            }
            
            /* 字体加载失败时的回退 */
            .has-{$font_slug}-font-family.font-loading {
                font-family: {$font_data['fallback']};
            }
        ";
    }
    
    wp_add_inline_style('theme-fonts', $fallback_styles);
}
add_action('wp_enqueue_scripts', 'font_fallback_system');

字体加载状态管理

const withFontLoadingState = (WrappedComponent) => {
    return (props) => {
        const [fontState, setFontState] = useState('loading');
        const { fontFamily } = props.attributes;
        
        useEffect(() => {
            if (!fontFamily) {
                setFontState('loaded');
                return;
            }
            
            const checkFont = async () => {
                try {
                    setFontState('loading');
                    await document.fonts.load(`16px "${fontFamily}"`);
                    setFontState('loaded');
                } catch (error) {
                    setFontState('error');
                }
            };
            
            checkFont();
        }, [fontFamily]);
        
        return (
            <WrappedComponent 
                {...props}
                fontState={fontState}
            />
        );
    };
};

通过以上系统化的实现,古腾堡编辑器可以获得完整的自定义字体支持,包括字体注册、管理、预览、优化和多语言适配等功能。这种集成不仅增强了编辑器的排版能力,还为内容创作者提供了更丰富的设计选择。

我爱主题网 自2012
主题:260+ 销售:1000+
兼容浏览器

电话咨询

7*12服务咨询电话:

1855-626-3292

微信咨询