diff --git a/lib/block-supports/custom-classname.php b/lib/block-supports/custom-classname.php
new file mode 100644
index 00000000000000..c8b8b8c3bd5eed
--- /dev/null
+++ b/lib/block-supports/custom-classname.php
@@ -0,0 +1,47 @@
+supports, array( 'customClassName' ), true );
+ if ( $has_custom_classname_support ) {
+ if ( ! $block_type->attributes ) {
+ $block_type->attributes = array();
+ }
+
+ if ( ! array_key_exists( 'className', $block_type->attributes ) ) {
+ $block_type->attributes['className'] = array(
+ 'type' => 'string',
+ );
+ }
+ }
+}
+
+/**
+ * Add the custom classnames to the output.
+ *
+ * @param array $attributes comprehensive list of attributes to be applied.
+ * @param array $block_attributes block attributes.
+ * @param array $block_type Block Type.
+ * @return array Block CSS classes and inline styles.
+ */
+function gutenberg_apply_custom_classname_support( $attributes, $block_attributes, $block_type ) {
+ $has_custom_classname_support = gutenberg_experimental_get( $block_type->supports, array( 'customClassName' ), true );
+ if ( $has_custom_classname_support ) {
+ $has_custom_classnames = array_key_exists( 'className', $block_attributes );
+
+ if ( $has_custom_classnames ) {
+ $attributes['css_classes'][] = $block_attributes['className'];
+ }
+ }
+
+ return $attributes;
+}
diff --git a/lib/block-supports/index.php b/lib/block-supports/index.php
index 4fd6460234d3f6..e000c04891eec5 100644
--- a/lib/block-supports/index.php
+++ b/lib/block-supports/index.php
@@ -17,6 +17,7 @@ function gutenberg_register_block_supports() {
gutenberg_register_alignment_support( $block_type );
gutenberg_register_colors_support( $block_type );
gutenberg_register_typography_support( $block_type );
+ gutenberg_register_custom_classname_support( $block_type );
}
}
@@ -44,6 +45,7 @@ function gutenberg_apply_block_supports( $block_content, $block ) {
$attributes = gutenberg_apply_colors_support( $attributes, $block['attrs'], $block_type );
$attributes = gutenberg_apply_typography_support( $attributes, $block['attrs'], $block_type );
$attributes = gutenberg_apply_alignment_support( $attributes, $block['attrs'], $block_type );
+ $attributes = gutenberg_apply_custom_classname_support( $attributes, $block['attrs'], $block_type );
if ( ! count( $attributes ) ) {
return $block_content;
diff --git a/lib/load.php b/lib/load.php
index 9f20014bf8e0e4..026a18c9cea523 100644
--- a/lib/load.php
+++ b/lib/load.php
@@ -110,3 +110,4 @@ function gutenberg_is_experiment_enabled( $name ) {
require dirname( __FILE__ ) . '/block-supports/align.php';
require dirname( __FILE__ ) . '/block-supports/colors.php';
require dirname( __FILE__ ) . '/block-supports/typography.php';
+require dirname( __FILE__ ) . '/block-supports/custom-classname.php';
diff --git a/lib/utils.php b/lib/utils.php
index 9d38be7a762a29..b5cdef7f999a99 100644
--- a/lib/utils.php
+++ b/lib/utils.php
@@ -24,7 +24,7 @@ function gutenberg_experimental_get( $array, $path, $default = array() ) {
$path_length = count( $path );
for ( $i = 0; $i < $path_length; ++$i ) {
- if ( empty( $array[ $path[ $i ] ] ) ) {
+ if ( ! isset( $array[ $path[ $i ] ] ) ) {
return $default;
}
$array = $array[ $path[ $i ] ];
diff --git a/packages/block-library/src/archives/block.json b/packages/block-library/src/archives/block.json
index b869126a43bb93..14a9451e1b0d89 100644
--- a/packages/block-library/src/archives/block.json
+++ b/packages/block-library/src/archives/block.json
@@ -2,9 +2,6 @@
"name": "core/archives",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"displayAsDropdown": {
"type": "boolean",
"default": false
diff --git a/packages/block-library/src/archives/index.php b/packages/block-library/src/archives/index.php
index b2a8b12b61f9d4..7fb3cf8968b577 100644
--- a/packages/block-library/src/archives/index.php
+++ b/packages/block-library/src/archives/index.php
@@ -19,10 +19,6 @@ function render_block_core_archives( $attributes ) {
$class = 'wp-block-archives';
- if ( isset( $attributes['className'] ) ) {
- $class .= " {$attributes['className']}";
- }
-
if ( ! empty( $attributes['displayAsDropdown'] ) ) {
$class .= ' wp-block-archives-dropdown';
diff --git a/packages/block-library/src/calendar/block.json b/packages/block-library/src/calendar/block.json
index b74c46f49a32af..698140a33354ba 100644
--- a/packages/block-library/src/calendar/block.json
+++ b/packages/block-library/src/calendar/block.json
@@ -2,9 +2,6 @@
"name": "core/calendar",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"month": {
"type": "integer"
},
diff --git a/packages/block-library/src/calendar/index.php b/packages/block-library/src/calendar/index.php
index d45ebad36e9d64..41d18c010ab1c0 100644
--- a/packages/block-library/src/calendar/index.php
+++ b/packages/block-library/src/calendar/index.php
@@ -31,11 +31,9 @@ function render_block_core_calendar( $attributes ) {
}
}
- $custom_class_name = empty( $attributes['className'] ) ? '' : ' ' . $attributes['className'];
-
$output = sprintf(
'
%2$s
',
- esc_attr( 'wp-block-calendar' . $custom_class_name ),
+ esc_attr( 'wp-block-calendar' ),
get_calendar( true, false )
);
diff --git a/packages/block-library/src/categories/block.json b/packages/block-library/src/categories/block.json
index 0194ee9c62971c..d4fee5e0649515 100644
--- a/packages/block-library/src/categories/block.json
+++ b/packages/block-library/src/categories/block.json
@@ -2,9 +2,6 @@
"name": "core/categories",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"displayAsDropdown": {
"type": "boolean",
"default": false
diff --git a/packages/block-library/src/categories/index.php b/packages/block-library/src/categories/index.php
index 14201f495a970a..4880ff56434094 100644
--- a/packages/block-library/src/categories/index.php
+++ b/packages/block-library/src/categories/index.php
@@ -43,10 +43,6 @@ function render_block_core_categories( $attributes ) {
$class = "wp-block-categories wp-block-categories-{$type}";
- if ( isset( $attributes['className'] ) ) {
- $class .= " {$attributes['className']}";
- }
-
return sprintf(
$wrapper_markup,
esc_attr( $class ),
diff --git a/packages/block-library/src/latest-comments/block.json b/packages/block-library/src/latest-comments/block.json
index 751efa9d270625..dd208ee7266979 100644
--- a/packages/block-library/src/latest-comments/block.json
+++ b/packages/block-library/src/latest-comments/block.json
@@ -2,9 +2,6 @@
"name": "core/latest-comments",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"commentsToShow": {
"type": "number",
"default": 5,
diff --git a/packages/block-library/src/latest-comments/index.php b/packages/block-library/src/latest-comments/index.php
index 150c586cfd6b05..cf5b62aff3ff3a 100644
--- a/packages/block-library/src/latest-comments/index.php
+++ b/packages/block-library/src/latest-comments/index.php
@@ -117,9 +117,6 @@ function render_block_core_latest_comments( $attributes = array() ) {
}
$class = 'wp-block-latest-comments';
- if ( ! empty( $attributes['className'] ) ) {
- $class .= ' ' . $attributes['className'];
- }
if ( $attributes['displayAvatar'] ) {
$class .= ' has-avatars';
}
diff --git a/packages/block-library/src/latest-posts/block.json b/packages/block-library/src/latest-posts/block.json
index 8ecb71a666db46..bf363c7718f64d 100644
--- a/packages/block-library/src/latest-posts/block.json
+++ b/packages/block-library/src/latest-posts/block.json
@@ -2,9 +2,6 @@
"name": "core/latest-posts",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"categories": {
"type": "array",
"items": {
diff --git a/packages/block-library/src/latest-posts/index.php b/packages/block-library/src/latest-posts/index.php
index 4dc1efa1514815..fc900fbacf22b7 100644
--- a/packages/block-library/src/latest-posts/index.php
+++ b/packages/block-library/src/latest-posts/index.php
@@ -162,10 +162,6 @@ function render_block_core_latest_posts( $attributes ) {
$class .= ' has-author';
}
- if ( isset( $attributes['className'] ) ) {
- $class .= ' ' . $attributes['className'];
- }
-
return sprintf(
'',
esc_attr( $class ),
diff --git a/packages/block-library/src/navigation/block.json b/packages/block-library/src/navigation/block.json
index 050e31f3fffdc1..1c0abeeee1aed1 100644
--- a/packages/block-library/src/navigation/block.json
+++ b/packages/block-library/src/navigation/block.json
@@ -5,9 +5,6 @@
"orientation": {
"type": "string"
},
- "className": {
- "type": "string"
- },
"textColor": {
"type": "string"
},
diff --git a/packages/block-library/src/navigation/index.php b/packages/block-library/src/navigation/index.php
index d7babf262c30a2..4f763e70180bc9 100644
--- a/packages/block-library/src/navigation/index.php
+++ b/packages/block-library/src/navigation/index.php
@@ -131,7 +131,6 @@ function render_block_core_navigation( $attributes, $content, $block ) {
$colors['css_classes'],
$font_sizes['css_classes'],
array( 'wp-block-navigation' ),
- isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(),
( isset( $attributes['orientation'] ) && 'vertical' === $attributes['orientation'] ) ? array( 'is-vertical' ) : array(),
isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array()
);
diff --git a/packages/block-library/src/rss/block.json b/packages/block-library/src/rss/block.json
index 947ee295651b45..88ad78c5963852 100644
--- a/packages/block-library/src/rss/block.json
+++ b/packages/block-library/src/rss/block.json
@@ -2,9 +2,6 @@
"name": "core/rss",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"columns": {
"type": "number",
"default": 2
diff --git a/packages/block-library/src/rss/index.php b/packages/block-library/src/rss/index.php
index 3f1e85ae1c407d..6c8792aa448d66 100644
--- a/packages/block-library/src/rss/index.php
+++ b/packages/block-library/src/rss/index.php
@@ -88,10 +88,6 @@ function render_block_core_rss( $attributes ) {
$class .= ' columns-' . $attributes['columns'];
}
- if ( isset( $attributes['className'] ) ) {
- $class .= ' ' . $attributes['className'];
- }
-
return sprintf( '', esc_attr( $class ), $list_items );
}
diff --git a/packages/block-library/src/search/block.json b/packages/block-library/src/search/block.json
index ea0e247ae9e534..0a2f217aca34b7 100644
--- a/packages/block-library/src/search/block.json
+++ b/packages/block-library/src/search/block.json
@@ -2,9 +2,6 @@
"name": "core/search",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"label": {
"type": "string"
},
diff --git a/packages/block-library/src/search/index.php b/packages/block-library/src/search/index.php
index d7209352ba6a90..7a224fa2eed3da 100644
--- a/packages/block-library/src/search/index.php
+++ b/packages/block-library/src/search/index.php
@@ -60,9 +60,6 @@ function render_block_core_search( $attributes ) {
}
$class = 'wp-block-search';
- if ( isset( $attributes['className'] ) ) {
- $class .= ' ' . $attributes['className'];
- }
return sprintf(
'',
diff --git a/packages/block-library/src/tag-cloud/block.json b/packages/block-library/src/tag-cloud/block.json
index 6d90c6acc2057d..7116bb43ddf16a 100644
--- a/packages/block-library/src/tag-cloud/block.json
+++ b/packages/block-library/src/tag-cloud/block.json
@@ -2,9 +2,6 @@
"name": "core/tag-cloud",
"category": "widgets",
"attributes": {
- "className": {
- "type": "string"
- },
"taxonomy": {
"type": "string",
"default": "post_tag"
diff --git a/packages/block-library/src/tag-cloud/index.php b/packages/block-library/src/tag-cloud/index.php
index 12d2a288217bda..667c09a325651f 100644
--- a/packages/block-library/src/tag-cloud/index.php
+++ b/packages/block-library/src/tag-cloud/index.php
@@ -14,12 +14,7 @@
*/
function render_block_core_tag_cloud( $attributes ) {
$class = 'wp-block-tag-cloud';
-
- if ( isset( $attributes['className'] ) ) {
- $class .= ' ' . $attributes['className'];
- }
-
- $args = array(
+ $args = array(
'echo' => false,
'taxonomy' => $attributes['taxonomy'],
'show_count' => $attributes['showTagCounts'],
diff --git a/phpunit/class-block-supported-styles-test.php b/phpunit/class-block-supported-styles-test.php
index f0589e3d151001..39b7f5eece35fe 100644
--- a/phpunit/class-block-supported-styles-test.php
+++ b/phpunit/class-block-supported-styles-test.php
@@ -687,4 +687,60 @@ function test_render_callback_required() {
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
+
+ /**
+ * Tests custom classname server-side block support.
+ */
+ function test_custom_classnames_support() {
+ $block_type_settings = array(
+ 'attributes' => array(),
+ 'supports' => array(),
+ 'render_callback' => true,
+ );
+ $this->register_block_type( 'core/example', $block_type_settings );
+
+ $block = array(
+ 'blockName' => 'core/example',
+ 'attrs' => array(
+ 'className' => 'my-custom-classname',
+ ),
+ 'innerBlock' => array(),
+ 'innerContent' => array(),
+ 'innerHTML' => array(),
+ );
+
+ $expected_styles = 'test:style; ';
+ $expected_classes = 'wp-block-example foo-bar-class my-custom-classname';
+
+ $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
+ }
+
+ /**
+ * Tests custom classname server-side block support opt-out.
+ */
+ function test_custom_classnames_support_opt_out() {
+ $block_type_settings = array(
+ 'attributes' => array(),
+ 'supports' => array(
+ 'customClassName' => false,
+ ),
+ 'render_callback' => true,
+ );
+ $this->register_block_type( 'core/example', $block_type_settings );
+
+ $block = array(
+ 'blockName' => 'core/example',
+ 'attrs' => array(
+ 'className' => 'my-custom-classname',
+ ),
+ 'innerBlock' => array(),
+ 'innerContent' => array(),
+ 'innerHTML' => array(),
+ );
+
+ $expected_styles = 'test:style;';
+ $expected_classes = 'wp-block-example foo-bar-class';
+
+ $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
+ }
}