Add input for Google Fonts links

This commit is contained in:
Tetrakern 2024-02-08 14:40:47 +01:00
parent 2d1fbf5d65
commit 6f32c420af
5 changed files with 294 additions and 132 deletions

File diff suppressed because one or more lines are too long

View File

@ -2742,6 +2742,93 @@ function fictioneer_append_meta_fields( $post_type, $meta_key, $meta_value ) {
}
}
// =============================================================================
// EXTRACT FONT DATA FROM GOOGLE FONTS LINK
// =============================================================================
/**
* Returns fonts data from a Google Fonts link
*
* @since 5.10.0
*
* @param string $link The Google Fonts link.
*
* @return array|false|null The font data if successful, false if malformed,
* null if not a valid Google Fonts link.
*/
function fictioneer_extract_font_from_google_link( $link ) {
// Validate
if ( preg_match( '/^https:\/\/fonts\.googleapis\.com\/css2/', $link ) !== 1 ) {
// Not Google Fonts link
return null;
}
// Setup
$font = array(
'google_link' => $link,
'skip' => true,
'chapter' => true,
'version' => '',
'key' => '',
'name' => '',
'family' => '',
'type' => '',
'styles' => ['normal'],
'weights' => [],
'charsets' => [],
'formats' => [],
'about' => __( 'This font is loaded via the Google Fonts CDN, see source for additional information.', 'fictioneer' ),
'note' => '',
'sources' => array(
'googleFontsCss' => array(
'name' => 'Google Fonts CSS File',
'url' => $link
)
)
);
// Name?
preg_match( '/family=([^:]+)/', $link, $name_matches );
if ( ! empty( $name_matches ) ) {
$font['name'] = str_replace( '+', ' ', $name_matches[1] );
$font['family'] = $font['name'];
$font['key'] = sanitize_title( $font['name'] );
} else {
// Link malformed
return false;
}
// Italic? Weights?
preg_match( '/ital,wght@([0-9,;]+)/', $link, $ital_weight_matches );
if ( ! empty( $ital_weight_matches ) ) {
$specifications = explode( ';', $ital_weight_matches[1] );
$weights = [];
$is_italic = false;
foreach ( $specifications as $spec ) {
list( $ital, $weight ) = explode( ',', $spec );
if ( $ital == '1' ) {
$is_italic = true;
}
$weights[ $weight ] = true;
}
if ( $is_italic ) {
$font['styles'][] = 'italic';
}
$font['weights'] = array_keys( $weights );
}
// Done
return $font;
}
// =============================================================================
// GET FONT DATA
// =============================================================================
@ -2751,7 +2838,7 @@ function fictioneer_append_meta_fields( $post_type, $meta_key, $meta_value ) {
*
* @since 5.10.0
*
* @return array Array of font information.
* @return array Array of font data.
*/
function fictioneer_get_font_data() {
@ -2760,6 +2847,7 @@ function fictioneer_get_font_data() {
$child_font_dir = get_stylesheet_directory() . '/fonts';
$parent_fonts = [];
$child_fonts = [];
$google_fonts = [];
// Helper function
$extract_font_data = function( $font_dir, &$fonts ) {
@ -2796,8 +2884,13 @@ function fictioneer_get_font_data() {
$extract_font_data( $child_font_dir, $child_fonts );
}
// Google Fonts link
// $google_fonts = array(
// fictioneer_extract_font_from_google_link( 'https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap' )
// );
// Merge finds
$fonts = array_merge( $parent_fonts, $child_fonts );
$fonts = array_merge( $parent_fonts, $child_fonts, $google_fonts );
// Return complete font list
return $fonts;
@ -2835,7 +2928,7 @@ function fictioneer_build_bundled_fonts() {
);
}
if ( ! ( $font['skip'] ?? 0 ) ) {
if ( ! ( $font['skip'] ?? 0 ) && ! ( $font['google_link'] ?? 0 ) ) {
$combined_font_css .= file_get_contents( $font['css_file'] );
}
}

View File

@ -996,6 +996,14 @@ define( 'FICTIONEER_OPTIONS', array(
'label' => __( 'Age confirmation modal content for posts.', 'fictioneer' ),
'default' => __( 'This content is intended for an adult audience. Please confirm that you are of legal age (18+) or leave the website.', 'fictioneer' ),
'placeholder' => __( 'This content is intended for an adult audience. Please confirm that you are of legal age (18+) or leave the website.', 'fictioneer' )
),
'fictioneer_google_fonts_links' => array(
'name' => 'fictioneer_google_fonts_links',
'group' => 'fictioneer-settings-fonts-group',
'sanitize_callback' => 'fictioneer_sanitize_google_fonts_links',
'label' => __( 'List of Google Fonts links', 'fictioneer' ),
'default' => '',
'placeholder' => __( 'https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap', 'fictioneer' )
)
)
));
@ -1210,6 +1218,36 @@ function fictioneer_sanitize_disable_widget_checkbox( $value ) {
return filter_var( $value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
}
/**
* Sanitizes the textarea input for Google Fonts links
*
* @since 5.10.0
*
* @param string $value The textarea string.
*
* @return string The sanitized textarea string.
*/
function fictioneer_sanitize_google_fonts_links( $value ) {
$value = sanitize_textarea_field( $value );
$lines = explode( "\n", $value );
$valid_links = [];
foreach ( $lines as $line ) {
$line = trim( $line );
if ( preg_match( '/^https:\/\/fonts\.googleapis\.com\/css2/', $line ) === 1 ) {
$sanitized_link = filter_var( $line, FILTER_SANITIZE_URL );
if ( $sanitized_link !== false ) {
$valid_links[] = $sanitized_link;
}
}
}
return implode( "\n", $valid_links );
}
// =============================================================================
// SANITIZE OPTION FILTERS
// =============================================================================

View File

@ -23,148 +23,173 @@ $heading_font = get_theme_mod( 'heading_font_family_value', 'Open Sans' );
<?php fictioneer_settings_header( 'fonts' ); ?>
<div class="fictioneer-settings__content">
<div class="fictioneer-single-column">
<div class="fictioneer-card">
<div class="fictioneer-card__wrapper">
<div class="fictioneer-card__content">
<div class="fictioneer-card__row">
<p><?php
printf(
__( 'This is an overview of all installed fonts; see <a href="%s" target="_blank">Installation guide</a> on how to add custom fonts yourself. You can assign the primary, secondary, and heading fonts in the <a href="%s">Customizer</a>.', 'fictioneer' ),
'https://github.com/Tetrakern/fictioneer/blob/main/INSTALLATION.md#custom-fonts',
wp_customize_url()
);
?></p>
</div>
</div>
</div>
</div>
<form method="post" action="options.php" class="fictioneer-form">
<?php settings_fields( 'fictioneer-settings-fonts-group' ); ?>
<?php foreach ( $fonts as $key => $font ) : ?>
<?php
$fallback = _x( 'n/a', 'Settings font card.', 'fictioneer' );
$name = $font['name'] ?? $key;
$family = $font['family'] ?? $fallback;
$type = $font['type'] ?? '';
$skip = $font['skip'] ?? false;
$version = $font['version'] ?? '';
$charsets = $font['charsets'] ?? [ $fallback ];
$formats = $font['formats'] ?? [ $fallback ];
$about = $font['about'] ?? _x( 'No description provided', 'Settings font card.', 'fictioneer' );
$weights = $font['weights'] ?? [ $fallback ];
$styles = $font['styles'] ?? [ $fallback ];
$sources = $font['sources'] ?? [];
$note = $font['note'] ?? '';
?>
<div class="fictioneer-single-column">
<div class="fictioneer-card">
<div class="fictioneer-card__wrapper">
<h3 class="fictioneer-card__header"><?php
echo $name;
if ( ! empty( $version ) ) {
printf( _x( ' (v%s)', 'Settings font card.', 'fictioneer' ), $version );
}
if ( $primary_font === $font['family'] ) {
_ex( ' — Primary Font', 'Settings font card.', 'fictioneer' );
}
if ( $secondary_font === $font['family'] ) {
_ex( ' — Secondary Font', 'Settings font card.', 'fictioneer' );
}
if ( $heading_font === $font['family'] ) {
_ex( ' — Heading Font', 'Settings font card.', 'fictioneer' );
}
?></h3>
<h3 class="fictioneer-card__header"><?php _e( 'Google Fonts', 'fictioneer' ); ?></h3>
<div class="fictioneer-card__content">
<div class="fictioneer-card__row"><?php
echo $about;
if ( ! empty( $sources ) ) {
echo _nx(
' <strong>Source:</strong> ',
' <strong>Sources:</strong> ',
count( $sources ),
'Settings font card.',
'fictioneer'
<div class="fictioneer-card__row">
<p><?php
printf(
__( 'You can install <a href="%s" target="_blank">Google Fonts</a> by adding the embed link below, which you can find in the href attribute provided on the right after selecting the font styles. Several fonts can be combined into one link, but be aware that the more fonts you load, the slower your site will become. Also note that using Google Fonts violates the GDPR.', 'fictioneer' ),
'https://fonts.google.com/'
);
?></p>
</div>
echo implode(
', ',
array_map(
function( $item ) {
return sprintf( '<a href="%s" target="_blank">%s</a>', $item['url'], $item['name'] );
},
$sources
)
);
}
?></div>
<?php if ( ! empty( $note ) ): ?>
<div class="fictioneer-card__row"><?php
printf( _x( '<strong>Note:</strong> %s', 'Settings font card.', 'fictioneer' ), $note );
?></div>
<?php endif; ?>
<div class="fictioneer-card__row fictioneer-card__row--boxes">
<div class="fictioneer-card__box" style="flex-grow: 2;">
<div class="fictioneer-card__box-title"><?php
_ex( 'Weights', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $weights ); ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Styles', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $styles ); ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Formats', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $formats ); ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Family', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php
echo fictioneer_font_family_value( $family );
if ( ! empty( $type ) ) {
echo ", {$type}";
}
?></div>
</div>
<div class="fictioneer-card__box" style="flex-grow: 8;">
<div class="fictioneer-card__box-title"><?php
_ex( 'Charsets', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $charsets ); ?></div>
</div>
<div class="fictioneer-card__row">
<textarea name="fictioneer_google_fonts_links" id="fictioneer_google_fonts_links" rows="4" placeholder="<?php echo FICTIONEER_OPTIONS['strings']['fictioneer_google_fonts_links']['placeholder']; ?>"><?php echo get_option( 'fictioneer_google_fonts_links' ); ?></textarea>
<p class="fictioneer-sub-label"><?php _e( 'One link per line; ideally bundle fonts into a single link.', 'fictioneer' ); ?></p>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php do_action( 'fictioneer_admin_settings_fonts' ); ?>
</div>
<div class="fictioneer-actions"><?php submit_button(); ?></div>
<div>
<h1 style="margin-bottom: 12px;"><?php _e( 'Installed Fonts', 'fictioneer' ); ?></h1>
<p><?php
printf(
__( 'See <a href="%s" target="_blank">installation guide</a> on how to add custom fonts yourself. You can assign the primary, secondary, and heading fonts in the <a href="%s">Customizer > Layout</a>.', 'fictioneer' ),
'https://github.com/Tetrakern/fictioneer/blob/main/INSTALLATION.md#custom-fonts',
wp_customize_url()
);
?></p>
</div>
<?php foreach ( $fonts as $key => $font ) : ?>
<?php
$fallback = _x( 'n/a', 'Settings font card.', 'fictioneer' );
$name = $font['name'] ?? $key;
$family = $font['family'] ?? $fallback;
$type = $font['type'] ?? '';
$skip = $font['skip'] ?? false;
$version = $font['version'] ?? '';
$charsets = $font['charsets'] ?? [ $fallback ];
$formats = $font['formats'] ?? [ $fallback ];
$about = $font['about'] ?? _x( 'No description provided', 'Settings font card.', 'fictioneer' );
$weights = $font['weights'] ?? [ $fallback ];
$styles = $font['styles'] ?? [ $fallback ];
$sources = $font['sources'] ?? [];
$note = $font['note'] ?? '';
?>
<div class="fictioneer-card">
<div class="fictioneer-card__wrapper">
<h3 class="fictioneer-card__header"><?php
echo $name;
if ( ! empty( $version ) ) {
printf( _x( ' (v%s)', 'Settings font card.', 'fictioneer' ), $version );
}
if ( $primary_font === $font['family'] ) {
_ex( ' — Primary Font', 'Settings font card.', 'fictioneer' );
}
if ( $secondary_font === $font['family'] ) {
_ex( ' — Secondary Font', 'Settings font card.', 'fictioneer' );
}
if ( $heading_font === $font['family'] ) {
_ex( ' — Heading Font', 'Settings font card.', 'fictioneer' );
}
?></h3>
<div class="fictioneer-card__content">
<div class="fictioneer-card__row"><?php
echo $about;
if ( ! empty( $sources ) ) {
echo _nx(
' <strong>Source:</strong> ',
' <strong>Sources:</strong> ',
count( $sources ),
'Settings font card.',
'fictioneer'
);
echo implode(
', ',
array_map(
function( $item ) {
return sprintf( '<a href="%s" target="_blank">%s</a>', $item['url'], $item['name'] );
},
$sources
)
);
}
?></div>
<?php if ( ! empty( $note ) ): ?>
<div class="fictioneer-card__row"><?php
printf( _x( '<strong>Note:</strong> %s', 'Settings font card.', 'fictioneer' ), $note );
?></div>
<?php endif; ?>
<div class="fictioneer-card__row fictioneer-card__row--boxes">
<div class="fictioneer-card__box" style="flex-grow: 2;">
<div class="fictioneer-card__box-title"><?php
_ex( 'Weights', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $weights ) ?: $fallback; ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Styles', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $styles ) ?: $fallback; ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Formats', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $formats ) ?: $fallback; ?></div>
</div>
<div class="fictioneer-card__box">
<div class="fictioneer-card__box-title"><?php
_ex( 'Family', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php
echo fictioneer_font_family_value( $family );
if ( ! empty( $type ) ) {
echo ", {$type}";
}
?></div>
</div>
<div class="fictioneer-card__box" style="flex-grow: 8;">
<div class="fictioneer-card__box-title"><?php
_ex( 'Charsets', 'Settings font card.', 'fictioneer' );
?></div>
<div class="fictioneer-card__box-content"><?php echo implode( ', ', $charsets ) ?: $fallback; ?></div>
</div>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php do_action( 'fictioneer_admin_settings_fonts' ); ?>
</div>
</form>
</div>
</div>

View File

@ -128,6 +128,12 @@ body[class*="fictioneer_page_"] {
margin: 0;
}
h1 {
font-size: 23px;
font-weight: 400;
margin: 0;
}
img {
display: block;
border-radius: 2px;