Skip to content

Commit

Permalink
Adds an endpoints that returns a list of font families used by a theme (
Browse files Browse the repository at this point in the history
#648)

* adds an endpoints that returns a list of font families used by a theme, including their style variants

* remove unwanted line

* move some logic into get_all_fonts

* Added get_fonts unit test

---------

Co-authored-by: Jason Crist <jcrist@pbking.com>
  • Loading branch information
matiasbenedetto and pbking authored May 30, 2024
1 parent 4b1181d commit 5470e48
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 4 deletions.
29 changes: 29 additions & 0 deletions includes/class-create-block-theme-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ public function register_rest_routes() {
},
),
);
register_rest_route(
'create-block-theme/v1',
'/font-families',
array(
'methods' => 'GET',
'callback' => array( $this, 'rest_get_font_families' ),
'permission_callback' => function () {
return current_user_can( 'edit_theme_options' );
},
),
);
}

function rest_get_theme_data( $request ) {
Expand Down Expand Up @@ -516,6 +527,24 @@ function rest_save_theme( $request ) {
);
}

/**
* Get a list of all the font families used in the theme.
*
* It includes the font families from the theme.json data (theme.json file + global styles) and the theme style variations.
* The font families with font faces containing src urls relative to the theme folder are converted to absolute urls.
*/
function rest_get_font_families( $request ) {
$font_families = CBT_Theme_Fonts::get_all_fonts();

return new WP_REST_Response(
array(
'status' => 'SUCCESS',
'message' => __( 'Font Families retrieved.', 'create-block-theme' ),
'data' => $font_families,
)
);
}

private function sanitize_theme_data( $theme ) {
$sanitized_theme['name'] = sanitize_text_field( $theme['name'] );
$sanitized_theme['description'] = sanitize_text_field( $theme['description'] ?? '' );
Expand Down
69 changes: 69 additions & 0 deletions includes/create-theme/theme-fonts.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,75 @@

class CBT_Theme_Fonts {


/**
* Make the font face theme src urls absolute.
*
* It replaces the 'file:./' prefix with the theme directory uri.
*
* Example: 'file:./assets/fonts/my-font.ttf' -> 'http://example.com/wp-content/themes/my-theme/assets/fonts/my-font.ttf'
* Example: [ 'https://example.com/assets/fonts/my-font.ttf' ] -> [ 'https://example.com/assets/fonts/my-font.ttf' ]
*
* @param array|string $src
* @return array|string
*/
private static function make_theme_font_src_absolute( $src ) {
$make_absolute = function ( $url ) {
if ( str_starts_with( $url, 'file:./' ) ) {
return str_replace( 'file:./', get_stylesheet_directory_uri() . '/', $url );
}
return $url;
};

if ( is_array( $src ) ) {
foreach ( $src as &$url ) {
$url = $make_absolute( $url );
}
} else {
$src = $make_absolute( $src );
}

return $src;
}

/**
* Get all fonts from the theme.json data + all the style variations.
*
* @return array
*/
public static function get_all_fonts() {
$font_families = array();
$theme = CBT_Theme_JSON_Resolver::get_merged_data();
$settings = $theme->get_settings();

if ( isset( $settings['typography']['fontFamilies']['theme'] ) ) {
$font_families = array_merge( $font_families, $settings['typography']['fontFamilies']['theme'] );
}

if ( isset( $settings['typography']['fontFamilies']['custom'] ) ) {
$font_families = array_merge( $font_families, $settings['typography']['fontFamilies']['custom'] );
}

$variations = CBT_Theme_JSON_Resolver::get_style_variations();

foreach ( $variations as $variation ) {
if ( isset( $variation['settings']['typography']['fontFamilies']['theme'] ) ) {
$font_families = array_merge( $font_families, $variation['settings']['typography']['fontFamilies']['theme'] );
}
}

// Iterates through the font families and makes the urls absolute to use in the frontend code.
foreach ( $font_families as &$font_family ) {
if ( isset( $font_family['fontFace'] ) ) {
foreach ( $font_family['fontFace'] as &$font_face ) {
$font_face['src'] = CBT_Theme_Fonts::make_theme_font_src_absolute( $font_face['src'] );
}
}
}

return $font_families;
}

/**
* Copy any ACTIVATED fonts from USER configuration to THEME configuration including any font face assets.
* Remove any DEACTIVATED fronts from the THEME configuration.
Expand Down
117 changes: 113 additions & 4 deletions tests/test-theme-fonts.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,121 @@ public function test_remove_deactivated_fonts_from_theme() {
$this->uninstall_theme( $test_theme_slug );
}

public function test_get_all_fonts_just_theme() {

wp_set_current_user( self::$admin_id );

$test_theme_slug = $this->create_blank_theme();

$theme_json = CBT_Theme_JSON_Resolver::get_theme_file_contents();
$theme_json['settings']['typography']['fontFamilies'] = array(
array(
'slug' => 'open-sans',
'name' => 'Open Sans',
'fontFamily' => 'Open Sans',
'fontFace' => array(
array(
'fontFamily' => 'Open Sans',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'file:./assets/fonts/open-sans-normal-400.ttf',
),
),
),
array(
'slug' => 'closed-sans',
'name' => 'Closed Sans',
'fontFamily' => 'Closed Sans',
'fontFace' => array(
array(
'fontFamily' => 'Closed Sans',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'http://example.com/closed-sans-normal-400.ttf',
),
),
),
);
CBT_Theme_JSON_Resolver::write_theme_file_contents( $theme_json );

$fonts = CBT_Theme_Fonts::get_all_fonts();

$this->assertCount( 2, $fonts );
$this->assertEquals( 'open-sans', $fonts[0]['slug'] );
$this->assertEquals( 'closed-sans', $fonts[1]['slug'] );
$this->assertStringNotContainsString( 'file:.', $fonts[0]['fontFace'][0]['src'] );
$this->assertStringNotContainsString( 'file:.', $fonts[1]['fontFace'][0]['src'] );

$this->uninstall_theme( $test_theme_slug );
}

public function test_get_all_fonts_from_theme_and_variation() {

wp_set_current_user( self::$admin_id );

$test_theme_slug = $this->create_blank_theme();

$theme_json = CBT_Theme_JSON_Resolver::get_theme_file_contents();
$theme_json['settings']['typography']['fontFamilies'] = array(
array(
'slug' => 'open-sans',
'name' => 'Open Sans',
'fontFamily' => 'Open Sans',
'fontFace' => array(
array(
'fontFamily' => 'Open Sans',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'file:./assets/fonts/open-sans-normal-400.ttf',
),
),
),
);
CBT_Theme_JSON_Resolver::write_theme_file_contents( $theme_json );

$variation_json = array(
'version' => '2',
'title' => 'Variation',
);
$variation_json['settings']['typography']['fontFamilies'] = array(
array(
'slug' => 'closed-sans',
'name' => 'Closed Sans',
'fontFamily' => 'Closed Sans',
'fontFace' => array(
array(
'fontFamily' => 'Closed Sans',
'fontStyle' => 'normal',
'fontWeight' => '400',
'src' => 'http://example.com/closed-sans-normal-400.ttf',
),
),
),
);

// Save the variation
$variation_path = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR;
$variation_slug = 'variation';
wp_mkdir_p( $variation_path );
file_put_contents(
$variation_path . $variation_slug . '.json',
wp_json_encode( $variation_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE )
);

$fonts = CBT_Theme_Fonts::get_all_fonts();

$this->assertCount( 2, $fonts );
$this->assertEquals( 'open-sans', $fonts[0]['slug'] );
$this->assertEquals( 'closed-sans', $fonts[1]['slug'] );
$this->assertStringNotContainsString( 'file:.', $fonts[0]['fontFace'][0]['src'] );
$this->assertStringNotContainsString( 'file:.', $fonts[1]['fontFace'][0]['src'] );

$this->uninstall_theme( $test_theme_slug );

}

private function save_theme() {
CBT_Theme_Fonts::persist_font_settings();
// CBT_Theme_Templates::add_templates_to_local( 'all' );
// CBT_Theme_JSON::add_theme_json_to_local( 'all' );
// CBT_Theme_Styles::clear_user_styles_customizations();
// CBT_Theme_Templates::clear_user_templates_customizations();
}

private function create_blank_theme() {
Expand Down

0 comments on commit 5470e48

Please sign in to comment.