WP_Theme_JSON::get_data(): array

In this article

Returns a valid theme.json as provided by a theme.

Description

Unlike get_raw_data() this returns the presets flattened, as provided by a theme.
This also uses appearanceTools instead of their opt-ins if all of them are true.

Return

array

Source

	/*
	 * The array_replace_recursive algorithm merges at the leaf level,
	 * but we don't want leaf arrays to be merged, so we overwrite it.
	 *
	 * For leaf values that are sequential arrays it will use the numeric indexes for replacement.
	 * We rather replace the existing with the incoming value, if it exists.
	 * This is the case of spacing.units.
	 *
	 * For leaf values that are associative arrays it will merge them as expected.
	 * This is also not the behavior we want for the current associative arrays (presets).
	 * We rather replace the existing with the incoming value, if it exists.
	 * This happens, for example, when we merge data from theme.json upon existing
	 * theme supports or when we merge anything coming from the same source twice.
	 * This is the case of color.palette, color.gradients, color.duotone,
	 * typography.fontSizes, or typography.fontFamilies.
	 *
	 * Additionally, for some preset types, we also want to make sure the
	 * values they introduce don't conflict with default values. We do so
	 * by checking the incoming slugs for theme presets and compare them
	 * with the equivalent default presets: if a slug is present as a default
	 * we remove it from the theme presets.
	 */
	$nodes        = static::get_setting_nodes( $incoming_data );
	$slugs_global = static::get_default_slugs( $this->theme_json, array( 'settings' ) );
	foreach ( $nodes as $node ) {
		// Replace the spacing.units.
		$path   = $node['path'];
		$path[] = 'spacing';
		$path[] = 'units';

		$content = _wp_array_get( $incoming_data, $path, null );
		if ( isset( $content ) ) {
			_wp_array_set( $this->theme_json, $path, $content );
		}

		// Replace the presets.
		foreach ( static::PRESETS_METADATA as $preset_metadata ) {
			$prevent_override = $preset_metadata['prevent_override'];
			if ( is_array( $prevent_override ) ) {
				$prevent_override = _wp_array_get( $this->theme_json['settings'], $preset_metadata['prevent_override'] );
			}

			foreach ( static::VALID_ORIGINS as $origin ) {
				$base_path = $node['path'];
				foreach ( $preset_metadata['path'] as $leaf ) {
					$base_path[] = $leaf;
				}

				$path   = $base_path;
				$path[] = $origin;

				$content = _wp_array_get( $incoming_data, $path, null );
				if ( ! isset( $content ) ) {
					continue;
				}

				// Set names for theme presets based on the slug if they are not set and can use default names.
				if ( 'theme' === $origin && $preset_metadata['use_default_names'] ) {
					foreach ( $content as $key => $item ) {
						if ( ! isset( $item['name'] ) ) {
							$name = static::get_name_from_defaults( $item['slug'], $base_path );
							if ( null !== $name ) {
								$content[ $key ]['name'] = $name;
							}
						}
					}
				}

				// Filter out default slugs from theme presets when defaults should not be overridden.
				if ( 'theme' === $origin && $prevent_override ) {
					$slugs_node    = static::get_default_slugs( $this->theme_json, $node['path'] );
					$preset_global = _wp_array_get( $slugs_global, $preset_metadata['path'], array() );
					$preset_node   = _wp_array_get( $slugs_node, $preset_metadata['path'], array() );
					$preset_slugs  = array_merge_recursive( $preset_global, $preset_node );

					$content = static::filter_slugs( $content, $preset_slugs );
				}

				_wp_array_set( $this->theme_json, $path, $content );
			}
		}
	}

	/*
	 * Style values are merged at the leaf level, however
	 * some values provide exceptions, namely style values that are
	 * objects and represent unique definitions for the style.
	 */
	$style_nodes = static::get_block_nodes(
		$this->theme_json,
		array(),
		array( 'include_node_paths_only' => true )
	);

	// Add top-level styles.
	$style_nodes[] = array( 'path' => array( 'styles' ) );

	foreach ( $style_nodes as $style_node ) {
		$path = $style_node['path'];
		/*
		 * Background image styles should be replaced, not merged,
		 * as they themselves are specific object definitions for the style.
		 */
		$background_image_path = array_merge( $path, static::PROPERTIES_METADATA['background-image'] );
		$content               = _wp_array_get( $incoming_data, $background_image_path, null );
		if ( isset( $content ) ) {
			_wp_array_set( $this->theme_json, $background_image_path, $content );
		}
	}
}

/**
 * Converts all filter (duotone) presets into SVGs.
 *
 * @since 5.9.1
 *
 * @param array $origins List of origins to process.
 * @return string SVG filters.
 */
public function get_svg_filters( $origins ) {
	$blocks_metadata = static::get_blocks_metadata();
	$setting_nodes   = static::get_setting_nodes( $this->theme_json, $blocks_metadata );

	$filters = '';
	foreach ( $setting_nodes as $metadata ) {
		$node = _wp_array_get( $this->theme_json, $metadata['path'], array() );
		if ( empty( $node['color']['duotone'] ) ) {
			continue;
		}

		$duotone_presets = $node['color']['duotone'];

		foreach ( $origins as $origin ) {
			if ( ! isset( $duotone_presets[ $origin ] ) ) {
				continue;
			}
			foreach ( $duotone_presets[ $origin ] as $duotone_preset ) {
				$filters .= WP_Duotone::get_filter_svg_from_preset( $duotone_preset );
			}
		}

Changelog

VersionDescription
6.0.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.