WP_Theme_JSON::get_layout_styles()protectedWP 6.1.0

Gets the CSS layout rules for a particular block from theme.json layout definitions.

Метод класса: WP_Theme_JSON{}

Хуков нет.

Возвращает

Строку. Layout styles for the block.

Использование

// protected - в коде основоного (родительского) или дочернего класса
$result = $this->get_layout_styles( $block_metadata );
$block_metadata(массив) (обязательный)
Metadata about the block to get styles for.

Список изменений

С версии 6.1.0 Введена.
С версии 6.3.0 Reduced specificity for layout margin rules.

Код WP_Theme_JSON::get_layout_styles() WP 6.5.2

protected function get_layout_styles( $block_metadata ) {
	$block_rules = '';
	$block_type  = null;

	// Skip outputting layout styles if explicitly disabled.
	if ( current_theme_supports( 'disable-layout-styles' ) ) {
		return $block_rules;
	}

	if ( isset( $block_metadata['name'] ) ) {
		$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_metadata['name'] );
		if ( ! block_has_support( $block_type, 'layout', false ) && ! block_has_support( $block_type, '__experimentalLayout', false ) ) {
			return $block_rules;
		}
	}

	$selector                 = isset( $block_metadata['selector'] ) ? $block_metadata['selector'] : '';
	$has_block_gap_support    = isset( $this->theme_json['settings']['spacing']['blockGap'] );
	$has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support.
	$node                     = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
	$layout_definitions       = wp_get_layout_definitions();
	$layout_selector_pattern  = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.

	/*
	 * Gap styles will only be output if the theme has block gap support, or supports a fallback gap.
	 * Default layout gap styles will be skipped for themes that do not explicitly opt-in to blockGap with a `true` or `false` value.
	 */
	if ( $has_block_gap_support || $has_fallback_gap_support ) {
		$block_gap_value = null;
		// Use a fallback gap value if block gap support is not available.
		if ( ! $has_block_gap_support ) {
			$block_gap_value = static::ROOT_BLOCK_SELECTOR === $selector ? '0.5em' : null;
			if ( ! empty( $block_type ) ) {
				$block_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] )
					? $block_type->supports['spacing']['blockGap']['__experimentalDefault']
					: null;
			}
		} else {
			$block_gap_value = static::get_property_value( $node, array( 'spacing', 'blockGap' ) );
		}

		// Support split row / column values and concatenate to a shorthand value.
		if ( is_array( $block_gap_value ) ) {
			if ( isset( $block_gap_value['top'] ) && isset( $block_gap_value['left'] ) ) {
				$gap_row         = static::get_property_value( $node, array( 'spacing', 'blockGap', 'top' ) );
				$gap_column      = static::get_property_value( $node, array( 'spacing', 'blockGap', 'left' ) );
				$block_gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column;
			} else {
				// Skip outputting gap value if not all sides are provided.
				$block_gap_value = null;
			}
		}

		// If the block should have custom gap, add the gap styles.
		if ( null !== $block_gap_value && false !== $block_gap_value && '' !== $block_gap_value ) {
			foreach ( $layout_definitions as $layout_definition_key => $layout_definition ) {
				// Allow outputting fallback gap styles for flex and grid layout types when block gap support isn't available.
				if ( ! $has_block_gap_support && 'flex' !== $layout_definition_key && 'grid' !== $layout_definition_key ) {
					continue;
				}

				$class_name    = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false;
				$spacing_rules = isset( $layout_definition['spacingStyles'] ) ? $layout_definition['spacingStyles'] : array();

				if (
					! empty( $class_name ) &&
					! empty( $spacing_rules )
				) {
					foreach ( $spacing_rules as $spacing_rule ) {
						$declarations = array();
						if (
							isset( $spacing_rule['selector'] ) &&
							preg_match( $layout_selector_pattern, $spacing_rule['selector'] ) &&
							! empty( $spacing_rule['rules'] )
						) {
							// Iterate over each of the styling rules and substitute non-string values such as `null` with the real `blockGap` value.
							foreach ( $spacing_rule['rules'] as $css_property => $css_value ) {
								$current_css_value = is_string( $css_value ) ? $css_value : $block_gap_value;
								if ( static::is_safe_css_declaration( $css_property, $current_css_value ) ) {
									$declarations[] = array(
										'name'  => $css_property,
										'value' => $current_css_value,
									);
								}
							}

							if ( ! $has_block_gap_support ) {
								// For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles.
								$format          = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(.%2$s%3$s)' : ':where(%1$s.%2$s%3$s)';
								$layout_selector = sprintf(
									$format,
									$selector,
									$class_name,
									$spacing_rule['selector']
								);
							} else {
								$format          = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(%s .%s) %s' : '%s-%s%s';
								$layout_selector = sprintf(
									$format,
									$selector,
									$class_name,
									$spacing_rule['selector']
								);
							}
							$block_rules .= static::to_ruleset( $layout_selector, $declarations );
						}
					}
				}
			}
		}
	}

	// Output base styles.
	if (
		static::ROOT_BLOCK_SELECTOR === $selector
	) {
		$valid_display_modes = array( 'block', 'flex', 'grid' );
		foreach ( $layout_definitions as $layout_definition ) {
			$class_name       = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false;
			$base_style_rules = isset( $layout_definition['baseStyles'] ) ? $layout_definition['baseStyles'] : array();

			if (
				! empty( $class_name ) &&
				is_array( $base_style_rules )
			) {
				// Output display mode. This requires special handling as `display` is not exposed in `safe_style_css_filter`.
				if (
					! empty( $layout_definition['displayMode'] ) &&
					is_string( $layout_definition['displayMode'] ) &&
					in_array( $layout_definition['displayMode'], $valid_display_modes, true )
				) {
					$layout_selector = sprintf(
						'%s .%s',
						$selector,
						$class_name
					);
					$block_rules    .= static::to_ruleset(
						$layout_selector,
						array(
							array(
								'name'  => 'display',
								'value' => $layout_definition['displayMode'],
							),
						)
					);
				}

				foreach ( $base_style_rules as $base_style_rule ) {
					$declarations = array();

					if (
						isset( $base_style_rule['selector'] ) &&
						preg_match( $layout_selector_pattern, $base_style_rule['selector'] ) &&
						! empty( $base_style_rule['rules'] )
					) {
						foreach ( $base_style_rule['rules'] as $css_property => $css_value ) {
							if ( static::is_safe_css_declaration( $css_property, $css_value ) ) {
								$declarations[] = array(
									'name'  => $css_property,
									'value' => $css_value,
								);
							}
						}

						$layout_selector = sprintf(
							'%s .%s%s',
							$selector,
							$class_name,
							$base_style_rule['selector']
						);
						$block_rules    .= static::to_ruleset( $layout_selector, $declarations );
					}
				}
			}
		}
	}
	return $block_rules;
}