Title: WP_Font_Collection
Published: April 3, 2024
Last modified: February 24, 2026

---

# class WP_Font_Collection {}

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#description)
    - [See also](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#see-also)
 * [Methods](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#methods)
 * [Source](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#source)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#wp--skip-link--target)

Font Collection class.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#description)󠁿

### 󠀁[See also](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#see-also)󠁿

 * [wp_register_font_collection()](https://developer.wordpress.org/reference/functions/wp_register_font_collection/)

## 󠀁[Methods](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#methods)󠁿

| Name | Description | 
| [WP_Font_Collection::__construct](https://developer.wordpress.org/reference/classes/wp_font_collection/__construct/) | [WP_Font_Collection](https://developer.wordpress.org/reference/classes/wp_font_collection/) constructor. | 
| [WP_Font_Collection::get_data](https://developer.wordpress.org/reference/classes/wp_font_collection/get_data/) | Retrieves the font collection data. | 
| [WP_Font_Collection::get_sanitization_schema](https://developer.wordpress.org/reference/classes/wp_font_collection/get_sanitization_schema/) | Retrieves the font collection sanitization schema. | 
| [WP_Font_Collection::load_from_file](https://developer.wordpress.org/reference/classes/wp_font_collection/load_from_file/) | Loads the font collection data from a JSON file path. | 
| [WP_Font_Collection::load_from_json](https://developer.wordpress.org/reference/classes/wp_font_collection/load_from_json/) | Loads font collection data from a JSON file or URL. | 
| [WP_Font_Collection::load_from_url](https://developer.wordpress.org/reference/classes/wp_font_collection/load_from_url/) | Loads the font collection data from a JSON file URL. | 
| [WP_Font_Collection::sanitize_and_validate_data](https://developer.wordpress.org/reference/classes/wp_font_collection/sanitize_and_validate_data/) | Sanitizes and validates the font collection data. |

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#source)󠁿

    ```php
    final class WP_Font_Collection {
    	/**
    	 * The unique slug for the font collection.
    	 *
    	 * @since 6.5.0
    	 * @var string
    	 */
    	public $slug;

    	/**
    	 * Font collection data.
    	 *
    	 * @since 6.5.0
    	 * @var array|WP_Error|null
    	 */
    	private $data;

    	/**
    	 * Font collection JSON file path or URL.
    	 *
    	 * @since 6.5.0
    	 * @var string|null
    	 */
    	private $src;

    	/**
    	 * WP_Font_Collection constructor.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @param string $slug Font collection slug. May only contain alphanumeric characters, dashes,
    	 *                     and underscores. See sanitize_title().
    	 * @param array  $args Font collection data. See wp_register_font_collection() for information on accepted arguments.
    	 */
    	public function __construct( string $slug, array $args ) {
    		$this->slug = sanitize_title( $slug );
    		if ( $this->slug !== $slug ) {
    			_doing_it_wrong(
    				__METHOD__,
    				/* translators: %s: Font collection slug. */
    				sprintf( __( 'Font collection slug "%s" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores.' ), $slug ),
    				'6.5.0'
    			);
    		}

    		$required_properties = array( 'name', 'font_families' );

    		if ( isset( $args['font_families'] ) && is_string( $args['font_families'] ) ) {
    			// JSON data is lazy loaded by ::get_data().
    			$this->src = $args['font_families'];
    			unset( $args['font_families'] );

    			$required_properties = array( 'name' );
    		}

    		$this->data = $this->sanitize_and_validate_data( $args, $required_properties );
    	}

    	/**
    	 * Retrieves the font collection data.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @return array|WP_Error An array containing the font collection data, or a WP_Error on failure.
    	 */
    	public function get_data() {
    		if ( is_wp_error( $this->data ) ) {
    			return $this->data;
    		}

    		// If the collection uses JSON data, load it and cache the data/error.
    		if ( isset( $this->src ) ) {
    			$this->data = $this->load_from_json( $this->src );
    		}

    		if ( is_wp_error( $this->data ) ) {
    			return $this->data;
    		}

    		// Set defaults for optional properties.
    		$defaults = array(
    			'description' => '',
    			'categories'  => array(),
    		);

    		return wp_parse_args( $this->data, $defaults );
    	}

    	/**
    	 * Loads font collection data from a JSON file or URL.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @param string $file_or_url File path or URL to a JSON file containing the font collection data.
    	 * @return array|WP_Error An array containing the font collection data on success,
    	 *                        else an instance of WP_Error on failure.
    	 */
    	private function load_from_json( $file_or_url ) {
    		$url  = wp_http_validate_url( $file_or_url );
    		$file = file_exists( $file_or_url ) ? wp_normalize_path( realpath( $file_or_url ) ) : false;

    		if ( ! $url && ! $file ) {
    			// translators: %s: File path or URL to font collection JSON file.
    			$message = __( 'Font collection JSON file is invalid or does not exist.' );
    			_doing_it_wrong( __METHOD__, $message, '6.5.0' );
    			return new WP_Error( 'font_collection_json_missing', $message );
    		}

    		$data = $url ? $this->load_from_url( $url ) : $this->load_from_file( $file );

    		if ( is_wp_error( $data ) ) {
    			return $data;
    		}

    		$data = array(
    			'name'          => $this->data['name'],
    			'font_families' => $data['font_families'],
    		);

    		if ( isset( $this->data['description'] ) ) {
    			$data['description'] = $this->data['description'];
    		}

    		if ( isset( $this->data['categories'] ) ) {
    			$data['categories'] = $this->data['categories'];
    		}

    		return $data;
    	}

    	/**
    	 * Loads the font collection data from a JSON file path.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @param string $file File path to a JSON file containing the font collection data.
    	 * @return array|WP_Error An array containing the font collection data on success,
    	 *                        else an instance of WP_Error on failure.
    	 */
    	private function load_from_file( $file ) {
    		$data = wp_json_file_decode( $file, array( 'associative' => true ) );
    		if ( empty( $data ) ) {
    			return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection JSON file contents.' ) );
    		}

    		return $this->sanitize_and_validate_data( $data, array( 'font_families' ) );
    	}

    	/**
    	 * Loads the font collection data from a JSON file URL.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @param string $url URL to a JSON file containing the font collection data.
    	 * @return array|WP_Error An array containing the font collection data on success,
    	 *                        else an instance of WP_Error on failure.
    	 */
    	private function load_from_url( $url ) {
    		// Limit key to 167 characters to avoid failure in the case of a long URL.
    		$transient_key = substr( 'wp_font_collection_url_' . $url, 0, 167 );
    		$data          = get_site_transient( $transient_key );

    		if ( false === $data ) {
    			$response = wp_safe_remote_get( $url );
    			if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
    				return new WP_Error(
    					'font_collection_request_error',
    					sprintf(
    						// translators: %s: Font collection URL.
    						__( 'Error fetching the font collection data from "%s".' ),
    						$url
    					)
    				);
    			}

    			$data = json_decode( wp_remote_retrieve_body( $response ), true );
    			if ( empty( $data ) ) {
    				return new WP_Error( 'font_collection_decode_error', __( 'Error decoding the font collection data from the HTTP response JSON.' ) );
    			}

    			// Make sure the data is valid before storing it in a transient.
    			$data = $this->sanitize_and_validate_data( $data, array( 'font_families' ) );
    			if ( is_wp_error( $data ) ) {
    				return $data;
    			}

    			set_site_transient( $transient_key, $data, DAY_IN_SECONDS );
    		}

    		return $data;
    	}

    	/**
    	 * Sanitizes and validates the font collection data.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @param array $data                Font collection data to sanitize and validate.
    	 * @param array $required_properties Required properties that must exist in the passed data.
    	 * @return array|WP_Error Sanitized data if valid, otherwise a WP_Error instance.
    	 */
    	private function sanitize_and_validate_data( $data, $required_properties = array() ) {
    		$schema = self::get_sanitization_schema();
    		$data   = WP_Font_Utils::sanitize_from_schema( $data, $schema );

    		foreach ( $required_properties as $property ) {
    			if ( empty( $data[ $property ] ) ) {
    				$message = sprintf(
    					// translators: 1: Font collection slug, 2: Missing property name, e.g. "font_families".
    					__( 'Font collection "%1$s" has missing or empty property: "%2$s".' ),
    					$this->slug,
    					$property
    				);
    				_doing_it_wrong( __METHOD__, $message, '6.5.0' );
    				return new WP_Error( 'font_collection_missing_property', $message );
    			}
    		}

    		return $data;
    	}

    	/**
    	 * Retrieves the font collection sanitization schema.
    	 *
    	 * @since 6.5.0
    	 *
    	 * @return array Font collection sanitization schema.
    	 */
    	private static function get_sanitization_schema() {
    		return array(
    			'name'          => 'sanitize_text_field',
    			'description'   => 'sanitize_text_field',
    			'font_families' => array(
    				array(
    					'font_family_settings' => array(
    						'name'       => 'sanitize_text_field',
    						'slug'       => static function ( $value ) {
    							return _wp_to_kebab_case( sanitize_title( $value ) );
    						},
    						'fontFamily' => 'WP_Font_Utils::sanitize_font_family',
    						'preview'    => 'sanitize_url',
    						'fontFace'   => array(
    							array(
    								'fontFamily'            => 'sanitize_text_field',
    								'fontStyle'             => 'sanitize_text_field',
    								'fontWeight'            => 'sanitize_text_field',
    								'src'                   => static function ( $value ) {
    									return is_array( $value )
    										? array_map( 'sanitize_text_field', $value )
    										: sanitize_text_field( $value );
    								},
    								'preview'               => 'sanitize_url',
    								'fontDisplay'           => 'sanitize_text_field',
    								'fontStretch'           => 'sanitize_text_field',
    								'ascentOverride'        => 'sanitize_text_field',
    								'descentOverride'       => 'sanitize_text_field',
    								'fontVariant'           => 'sanitize_text_field',
    								'fontFeatureSettings'   => 'sanitize_text_field',
    								'fontVariationSettings' => 'sanitize_text_field',
    								'lineGapOverride'       => 'sanitize_text_field',
    								'sizeAdjust'            => 'sanitize_text_field',
    								'unicodeRange'          => 'sanitize_text_field',
    							),
    						),
    					),
    					'categories'           => array( 'sanitize_title' ),
    				),
    			),
    			'categories'    => array(
    				array(
    					'name' => 'sanitize_text_field',
    					'slug' => 'sanitize_title',
    				),
    			),
    		);
    	}
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/fonts/class-wp-font-collection.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/fonts/class-wp-font-collection.php#L19)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/fonts/class-wp-font-collection.php#L19-L295)

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_font_collection/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.5.0](https://developer.wordpress.org/reference/since/6.5.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_font_collection%2F)
before being able to contribute a note or feedback.