261 lines
8.4 KiB
PHP
261 lines
8.4 KiB
PHP
<?php
|
|
/**
|
|
* Font Manager - Bridges the WordPress Font Library with theme settings.
|
|
*
|
|
* Uses the built-in Font Library (WP 6.5+) for registration, discovery,
|
|
* and @font-face generation. The admin settings page uses the helpers
|
|
* in this file to populate font-family dropdowns.
|
|
*
|
|
* @package OTS_Theme
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Register a curated set of Google Fonts with WordPress's Font Library
|
|
* so they appear immediately in the admin settings page dropdown.
|
|
*
|
|
* Admins can add more fonts via Appearance → Editor → Fonts at any time.
|
|
*/
|
|
add_action( 'after_setup_theme', function () {
|
|
|
|
/*
|
|
* WordPress 6.5+ ships wp_register_font_family() / wp_register_font_face()
|
|
* via the Fonts API (WP_Fonts or WP_Webfonts depending on merge iteration).
|
|
* We wrap the calls so the theme degrades gracefully on older installs.
|
|
*/
|
|
if ( ! function_exists( 'wp_register_webfont_provider' ) && ! class_exists( 'WP_Fonts' ) ) {
|
|
// Font Library is available in WP 6.5+; on older versions the
|
|
// Google Fonts CDN link in enqueue.php serves as the fallback.
|
|
return;
|
|
}
|
|
} );
|
|
|
|
/**
|
|
* Return every font family available to this WordPress installation.
|
|
*
|
|
* Sources (merged, de-duped by slug):
|
|
* 1. theme.json → settings.typography.fontFamilies
|
|
* 2. Font Library → any fonts the user installed via Site Editor
|
|
* 3. Bundled list → a small curated set of popular Google Fonts
|
|
*
|
|
* @return array<int,array{slug:string,name:string,fontFamily:string}>
|
|
*/
|
|
function oribi_get_available_fonts() {
|
|
|
|
$fonts = [];
|
|
|
|
/* ── 1. theme.json registered families ─────────────────── */
|
|
$theme_json = WP_Theme_JSON_Resolver::get_merged_data()->get_data();
|
|
if ( ! empty( $theme_json['settings']['typography']['fontFamilies']['theme'] ) ) {
|
|
foreach ( $theme_json['settings']['typography']['fontFamilies']['theme'] as $f ) {
|
|
$fonts[ $f['slug'] ] = [
|
|
'slug' => $f['slug'],
|
|
'name' => $f['name'] ?? $f['slug'],
|
|
'fontFamily' => $f['fontFamily'],
|
|
];
|
|
}
|
|
}
|
|
|
|
/* ── 2. Font Library (user-installed via Site Editor) ───── */
|
|
$font_families = oribi_query_font_library();
|
|
foreach ( $font_families as $f ) {
|
|
$slug = sanitize_title( $f['slug'] ?? $f['name'] );
|
|
if ( ! isset( $fonts[ $slug ] ) ) {
|
|
$fonts[ $slug ] = [
|
|
'slug' => $slug,
|
|
'name' => $f['name'],
|
|
'fontFamily' => $f['fontFamily'] ?? "'{$f['name']}', sans-serif",
|
|
];
|
|
}
|
|
}
|
|
|
|
/* ── 3. Bundled Google Fonts (always shown as available) ── */
|
|
$bundled = oribi_get_bundled_google_fonts();
|
|
foreach ( $bundled as $slug => $data ) {
|
|
if ( ! isset( $fonts[ $slug ] ) ) {
|
|
$fonts[ $slug ] = $data;
|
|
}
|
|
}
|
|
|
|
// Sort alphabetically by display name.
|
|
uasort( $fonts, function ( $a, $b ) {
|
|
return strcasecmp( $a['name'], $b['name'] );
|
|
} );
|
|
|
|
return array_values( $fonts );
|
|
}
|
|
|
|
/**
|
|
* Query the WP Font Library (wp_font_family post type) for installed fonts.
|
|
*
|
|
* @return array<int,array{slug:string,name:string,fontFamily:string}>
|
|
*/
|
|
function oribi_query_font_library() {
|
|
|
|
$results = [];
|
|
|
|
// Font Library stores each font family as a wp_font_family post (WP 6.5+).
|
|
$query = new WP_Query( [
|
|
'post_type' => 'wp_font_family',
|
|
'posts_per_page' => 100,
|
|
'post_status' => 'publish',
|
|
'no_found_rows' => true,
|
|
] );
|
|
|
|
if ( $query->have_posts() ) {
|
|
foreach ( $query->posts as $post ) {
|
|
$content = json_decode( $post->post_content, true );
|
|
if ( $content ) {
|
|
$results[] = [
|
|
'slug' => $content['slug'] ?? sanitize_title( $post->post_title ),
|
|
'name' => $post->post_title,
|
|
'fontFamily' => $content['fontFamily'] ?? "'{$post->post_title}', sans-serif",
|
|
];
|
|
}
|
|
}
|
|
}
|
|
wp_reset_postdata();
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Return a curated set of popular Google Fonts bundled with the theme.
|
|
*
|
|
* These are always shown in the font selector even if the user hasn't
|
|
* explicitly installed them via the Font Library. WordPress will load
|
|
* them from Google Fonts CDN when selected.
|
|
*
|
|
* @return array<string,array{slug:string,name:string,fontFamily:string,googleUrl:string}>
|
|
*/
|
|
function oribi_get_bundled_google_fonts() {
|
|
|
|
return [
|
|
'inter' => [
|
|
'slug' => 'inter',
|
|
'name' => 'Inter',
|
|
'fontFamily' => "'Inter', system-ui, -apple-system, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'roboto' => [
|
|
'slug' => 'roboto',
|
|
'name' => 'Roboto',
|
|
'fontFamily' => "'Roboto', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap',
|
|
],
|
|
'open-sans' => [
|
|
'slug' => 'open-sans',
|
|
'name' => 'Open Sans',
|
|
'fontFamily' => "'Open Sans', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap',
|
|
],
|
|
'poppins' => [
|
|
'slug' => 'poppins',
|
|
'name' => 'Poppins',
|
|
'fontFamily' => "'Poppins', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'lato' => [
|
|
'slug' => 'lato',
|
|
'name' => 'Lato',
|
|
'fontFamily' => "'Lato', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&display=swap',
|
|
],
|
|
'montserrat' => [
|
|
'slug' => 'montserrat',
|
|
'name' => 'Montserrat',
|
|
'fontFamily' => "'Montserrat', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'source-sans-3' => [
|
|
'slug' => 'source-sans-3',
|
|
'name' => 'Source Sans 3',
|
|
'fontFamily' => "'Source Sans 3', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'nunito' => [
|
|
'slug' => 'nunito',
|
|
'name' => 'Nunito',
|
|
'fontFamily' => "'Nunito', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'raleway' => [
|
|
'slug' => 'raleway',
|
|
'name' => 'Raleway',
|
|
'fontFamily' => "'Raleway', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'dm-sans' => [
|
|
'slug' => 'dm-sans',
|
|
'name' => 'DM Sans',
|
|
'fontFamily' => "'DM Sans', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap',
|
|
],
|
|
'work-sans' => [
|
|
'slug' => 'work-sans',
|
|
'name' => 'Work Sans',
|
|
'fontFamily' => "'Work Sans', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Work+Sans:wght@300;400;500;600;700;800;900&display=swap',
|
|
],
|
|
'plus-jakarta-sans' => [
|
|
'slug' => 'plus-jakarta-sans',
|
|
'name' => 'Plus Jakarta Sans',
|
|
'fontFamily' => "'Plus Jakarta Sans', system-ui, sans-serif",
|
|
'googleUrl' => 'https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap',
|
|
],
|
|
'system-ui' => [
|
|
'slug' => 'system-ui',
|
|
'name' => 'System UI (no download)',
|
|
'fontFamily' => "system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
|
|
'googleUrl' => '',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Resolve a font slug to its CSS font-family value.
|
|
*
|
|
* Checks (in order): bundled list → Font Library → theme.json.
|
|
*
|
|
* @param string $slug Font slug (e.g. 'inter', 'roboto').
|
|
* @return string CSS font-family value.
|
|
*/
|
|
function oribi_get_font_family_css( $slug ) {
|
|
|
|
if ( empty( $slug ) ) {
|
|
$slug = 'inter';
|
|
}
|
|
|
|
// Bundled fonts (includes Google Fonts URL for enqueue).
|
|
$bundled = oribi_get_bundled_google_fonts();
|
|
if ( isset( $bundled[ $slug ] ) ) {
|
|
return $bundled[ $slug ]['fontFamily'];
|
|
}
|
|
|
|
// Search all available fonts.
|
|
$fonts = oribi_get_available_fonts();
|
|
foreach ( $fonts as $f ) {
|
|
if ( $f['slug'] === $slug ) {
|
|
return $f['fontFamily'];
|
|
}
|
|
}
|
|
|
|
// Ultimate fallback.
|
|
return "'Inter', system-ui, -apple-system, sans-serif";
|
|
}
|
|
|
|
/**
|
|
* Return the Google Fonts stylesheet URL for a given font slug,
|
|
* or empty string if not a bundled Google Font.
|
|
*
|
|
* @param string $slug Font slug.
|
|
* @return string URL or ''.
|
|
*/
|
|
function oribi_get_google_font_url( $slug ) {
|
|
$bundled = oribi_get_bundled_google_fonts();
|
|
return isset( $bundled[ $slug ] ) ? $bundled[ $slug ]['googleUrl'] : '';
|
|
}
|