Skip to content

Commit

Permalink
Try: Alternative approach to rendering common layout styles from presets
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewserong committed Mar 11, 2022
1 parent 499d5a8 commit 3285d88
Show file tree
Hide file tree
Showing 6 changed files with 420 additions and 0 deletions.
102 changes: 102 additions & 0 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,108 @@ function gutenberg_register_layout_support( $block_type ) {
}
}

function gutenberg_generate_common_flow_layout_styles() {
$style_engine = WP_Style_Engine_Gutenberg::get_instance();

$style_engine->add_style(
'wp-layout-flow',
array(
'selector' => '.alignleft',
'rules' => array(
'float' => 'left',
'margin-right' => '2em',
'margin-left' => '0',
),
)
);

$style_engine->add_style(
'wp-layout-flow',
array(
'selector' => '.alignright',
'rules' => array(
'float' => 'right',
'margin-left' => '2em',
'margin-right' => '0',
),
)
);

$style_engine->add_style(
'wp-layout-flow',
array(
'selector' => '> .alignfull',
'rules' => array(
'max-width' => 'none',
),
)
);

$style_engine->add_style(
'wp-layout-flow--global-gap',
array(
'selector' => '> *',
'rules' => array(
'margin-top' => '0',
'margin-bottom' => '0',
),
)
);

$style_engine->add_style(
'wp-layout-flow--global-gap',
array(
'selector' => '> * + *',
'rules' => array(
'margin-top' => 'var( --wp--style--block-gap )',
'margin-bottom' => '0',
),
)
);
}

function gutenberg_generate_common_flex_layout_styles() {
$style_engine = WP_Style_Engine_Gutenberg::get_instance();

$style_engine->add_style(
'wp-layout-flex',
array(
'rules' => array(
'display' => 'flex',
'gap' => '0.5em',
),
)
);

$style_engine->add_style(
'wp-layout-flex',
array(
'selector' => '> *',
'rules' => array(
'margin' => '0',
),
)
);
}

function gutenberg_get_layout_preset_styles( $preset_metadata, $presets_by_origin ) {
WP_Style_Engine_Gutenberg::get_instance()->reset();

$presets = end( $presets_by_origin );

foreach ( $presets as $preset ) {
if ( isset( $preset['type'] ) ) {
if ( 'flow' === $preset['type'] ) {
$output_styles = gutenberg_generate_common_flow_layout_styles();
} else if ( 'flex' === $preset['type'] ) {
$output_styles = gutenberg_generate_common_flex_layout_styles();
}
}
}

return WP_Style_Engine_Gutenberg::get_instance()->get_generated_styles();
}

/**
* Generates the CSS corresponding to the provided layout.
*
Expand Down
115 changes: 115 additions & 0 deletions lib/class-wp-style-engine-gutenberg.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php
/**
* WP_Style_Engine class
*
* @package Gutenberg
*/

/**
* Singleton class representing the style engine.
*
* Consolidates rendering block styles to reduce duplication and streamline
* CSS styles generation.
*
* @since 6.0.0
*/
class WP_Style_Engine_Gutenberg {
/**
* Registered CSS styles.
*
* @since 5.5.0
* @var array
*/
private $registered_styles = array();

/**
* Container for the main instance of the class.
*
* @since 5.5.0
* @var WP_Style_Engine_Gutenberg|null
*/
private static $instance = null;

/**
* Register action for outputting styles when the class is constructed.
*/
public function __construct() {
// Borrows the logic from `gutenberg_enqueue_block_support_styles`.
// $action_hook_name = 'wp_footer';
// if ( wp_is_block_theme() ) {
// $action_hook_name = 'wp_enqueue_scripts';
// }
// add_action(
// $action_hook_name,
// array( $this, 'output_styles' )
// );
}

/**
* Utility method to retrieve the main instance of the class.
*
* The instance will be created if it does not exist yet.
*
* @return WP_Style_Engine_Gutenberg The main instance.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}

return self::$instance;
}

public function reset() {
$this->registered_styles = array();
}

public function get_generated_styles() {
$output = '';
foreach ( $this->registered_styles as $selector => $rules ) {
$output .= "{$selector} {\n";

if ( is_string( $rules ) ) {
$output .= ' ';
$output .= $rules;
} else {
foreach ( $rules as $rule => $value ) {
$output .= " {$rule}: {$value};\n";
}
}
$output .= "}\n";
}
return $output;
}

/**
* Stores style rules for a given CSS selector (the key) and returns an associated classname.
*
* @param string $key A class name used to construct a key.
* @param array $options An array of options, rules, and selector for constructing the rules.
*
* @return string The class name for the added style.
*/
public function add_style( $key, $options ) {
$class = ! empty( $options['suffix'] ) ? $key . '-' . sanitize_title( $options['suffix'] ) : $key;
$selector = ! empty( $options['selector'] ) ? ' ' . trim( $options['selector'] ) : '';
$rules = ! empty( $options['rules'] ) ? $options['rules'] : array();
$prefix = ! empty( $options['prefix'] ) ? $options['prefix'] : '.';

if ( ! $class ) {
return;
}

$this->registered_styles[ $prefix . $class . $selector ] = $rules;

return $class;
}

/**
* Render registered styles as key { ...rules } for final output.
*/
public function output_styles() {
$output = $this->get_generated_styles();
echo "<style>\n$output</style>\n";
}
}
17 changes: 17 additions & 0 deletions lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,20 @@ protected static function compute_preset_classes( $settings, $selector, $origins

$stylesheet = '';
foreach ( static::PRESETS_METADATA as $preset_metadata ) {
if ( isset( $preset_metadata['type'] ) && 'layout' === $preset_metadata['type'] ) {

$preset_per_origin = _wp_array_get( $settings, $preset_metadata['path'], array() );

if ( ! empty( $preset_per_origin ) ) {
if ( isset( $preset_metadata['value_func'] ) &&
is_callable( $preset_metadata['value_func'] )
) {
$value_func = $preset_metadata['value_func'];
$stylesheet .= call_user_func( $value_func, $preset_metadata, $preset_per_origin );
continue;
}
}
}
$slugs = static::get_settings_slugs( $settings, $preset_metadata, $origins );
foreach ( $preset_metadata['classes'] as $class => $property ) {
foreach ( $slugs as $slug ) {
Expand Down Expand Up @@ -1135,6 +1149,9 @@ protected static function replace_slug_in_string( $input, $slug ) {
protected static function compute_preset_vars( $settings, $origins ) {
$declarations = array();
foreach ( static::PRESETS_METADATA as $preset_metadata ) {
if ( isset( $preset_metadata['type'] ) && 'layout' === $preset_metadata['type'] ) {
continue;
}
$values_by_slug = static::get_settings_values_by_slug( $settings, $preset_metadata, $origins );
foreach ( $values_by_slug as $slug => $value ) {
$declarations[] = array(
Expand Down
12 changes: 12 additions & 0 deletions lib/compat/wordpress-5.9/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@
],
"text": true
},
"layout": {
"types": [
{
"slug": "flow",
"type": "flow"
},
{
"slug": "flex",
"type": "flex"
}
]
},
"spacing": {
"blockGap": null,
"margin": false,
Expand Down
Loading

0 comments on commit 3285d88

Please sign in to comment.