Skip to content

Commit 611d953

Browse files
committed
Block Editor: Add the Site Logo block's server implementation.
Props aristath, timothyblynjacobs, ocean90. Fixes #53247. git-svn-id: https://develop.svn.wordpress.org/trunk@51091 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 900367b commit 611d953

File tree

15 files changed

+648
-1
lines changed

15 files changed

+648
-1
lines changed

src/wp-includes/blocks/index.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
require ABSPATH . WPINC . '/blocks/search.php';
3333
require ABSPATH . WPINC . '/blocks/shortcode.php';
3434
require ABSPATH . WPINC . '/blocks/site-tagline.php';
35+
require ABSPATH . WPINC . '/blocks/site-logo.php';
3536
require ABSPATH . WPINC . '/blocks/site-title.php';
3637
require ABSPATH . WPINC . '/blocks/social-link.php';
3738
require ABSPATH . WPINC . '/blocks/tag-cloud.php';
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
/**
3+
* Server-side rendering of the `core/site-logo` block.
4+
*
5+
* @package WordPress
6+
*/
7+
8+
/**
9+
* Renders the `core/site-logo` block on the server.
10+
*
11+
* @param array $attributes The block attributes.
12+
*
13+
* @return string The render.
14+
*/
15+
function render_block_core_site_logo( $attributes ) {
16+
$adjust_width_height_filter = function ( $image ) use ( $attributes ) {
17+
if ( empty( $attributes['width'] ) ) {
18+
return $image;
19+
}
20+
$height = (float) $attributes['width'] / ( (float) $image[1] / (float) $image[2] );
21+
return array( $image[0], (int) $attributes['width'], (int) $height );
22+
};
23+
24+
add_filter( 'wp_get_attachment_image_src', $adjust_width_height_filter );
25+
26+
$custom_logo = get_custom_logo();
27+
28+
remove_filter( 'wp_get_attachment_image_src', $adjust_width_height_filter );
29+
30+
if ( empty( $custom_logo ) ) {
31+
return ''; // Return early if no custom logo is set, avoiding extraneous wrapper div.
32+
}
33+
34+
if ( ! $attributes['isLink'] ) {
35+
// Remove the link.
36+
$custom_logo = preg_replace( '#<a.*?>(.*?)</a>#i', '\1', $custom_logo );
37+
}
38+
39+
if ( $attributes['isLink'] && '_blank' === $attributes['linkTarget'] ) {
40+
// Add the link target after the rel="home".
41+
// Add an aria-label for informing that the page opens in a new tab.
42+
$aria_label = 'aria-label="' . esc_attr__( '(Home link, opens in a new tab)' ) . '"';
43+
$custom_logo = str_replace( 'rel="home"', 'rel="home" target="' . $attributes['linkTarget'] . '"' . $aria_label, $custom_logo );
44+
}
45+
46+
$classnames = array();
47+
if ( ! empty( $attributes['className'] ) ) {
48+
$classnames[] = $attributes['className'];
49+
}
50+
51+
if ( ! empty( $attributes['align'] ) && in_array( $attributes['align'], array( 'center', 'left', 'right' ), true ) ) {
52+
$classnames[] = "align{$attributes['align']}";
53+
}
54+
55+
if ( empty( $attributes['width'] ) ) {
56+
$classnames[] = 'is-default-size';
57+
}
58+
59+
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) );
60+
$html = sprintf( '<div %s>%s</div>', $wrapper_attributes, $custom_logo );
61+
return $html;
62+
}
63+
64+
/**
65+
* Register a core site setting for a site logo
66+
*/
67+
function register_block_core_site_logo_setting() {
68+
register_setting(
69+
'general',
70+
'site_logo',
71+
array(
72+
'show_in_rest' => array(
73+
'name' => 'site_logo',
74+
),
75+
'type' => 'integer',
76+
'description' => __( 'Site logo.' ),
77+
)
78+
);
79+
}
80+
81+
add_action( 'rest_api_init', 'register_block_core_site_logo_setting', 10 );
82+
83+
/**
84+
* Registers the `core/site-logo` block on the server.
85+
*/
86+
function register_block_core_site_logo() {
87+
register_block_type_from_metadata(
88+
__DIR__ . '/site-logo',
89+
array(
90+
'render_callback' => 'render_block_core_site_logo',
91+
)
92+
);
93+
}
94+
95+
add_action( 'init', 'register_block_core_site_logo' );
96+
97+
/**
98+
* Overrides the custom logo with a site logo, if the option is set.
99+
*
100+
* @param string $custom_logo The custom logo set by a theme.
101+
*
102+
* @return string The site logo if set.
103+
*/
104+
function _override_custom_logo_theme_mod( $custom_logo ) {
105+
$site_logo = get_option( 'site_logo' );
106+
return false === $site_logo ? $custom_logo : $site_logo;
107+
}
108+
109+
add_filter( 'theme_mod_custom_logo', '_override_custom_logo_theme_mod' );
110+
111+
/**
112+
* Updates the site_logo option when the custom_logo theme-mod gets updated.
113+
*
114+
* This function is hooked on "update_option_theme_mods_$theme" and not
115+
* "pre_set_theme_mod_custom_logo" because by hooking in `update_option`
116+
* the function accounts for remove_theme_mod() as well.
117+
*
118+
* @param mixed $old_value The old option value.
119+
* @param mixed $value The new option value.
120+
*/
121+
function _sync_custom_logo_to_site_logo( $old_value, $value ) {
122+
// Delete the option when the custom logo does not exist or was removed.
123+
// This step ensures the option stays in sync.
124+
if ( empty( $value['custom_logo'] ) ) {
125+
delete_option( 'site_logo' );
126+
} else {
127+
remove_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo' );
128+
update_option( 'site_logo', $value['custom_logo'] );
129+
add_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo', 10, 2 );
130+
}
131+
}
132+
133+
/**
134+
* Hooks `_sync_custom_logo_to_site_logo` in `update_option_theme_mods_$theme`.
135+
*
136+
* Runs on `setup_theme` to account for dynamically-switched themes in the Customizer.
137+
*/
138+
function _sync_custom_logo_to_site_logo_on_setup_theme() {
139+
$theme = get_option( 'stylesheet' );
140+
add_action( "update_option_theme_mods_$theme", '_sync_custom_logo_to_site_logo', 10, 2 );
141+
}
142+
add_action( 'setup_theme', '_sync_custom_logo_to_site_logo_on_setup_theme', 11 );
143+
144+
/**
145+
* Updates the custom_logo theme-mod when the site_logo option gets updated.
146+
*
147+
* @param mixed $old_value The old option value.
148+
* @param mixed $value The new option value.
149+
*
150+
* @return void
151+
*/
152+
function _sync_site_logo_to_custom_logo( $old_value, $value ) {
153+
// Delete the option when the custom logo does not exist or was removed.
154+
// This step ensures the option stays in sync.
155+
if ( empty( $value ) ) {
156+
remove_theme_mod( 'custom_logo' );
157+
} else {
158+
remove_filter( 'pre_set_theme_mod_custom_logo', '_sync_custom_logo_to_site_logo' );
159+
set_theme_mod( 'custom_logo', $value );
160+
add_filter( 'pre_set_theme_mod_custom_logo', '_sync_custom_logo_to_site_logo' );
161+
}
162+
}
163+
164+
add_action( 'update_option_site_logo', '_sync_site_logo_to_custom_logo', 10, 2 );
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"apiVersion": 2,
3+
"name": "core/site-logo",
4+
"title": "Site Logo",
5+
"category": "layout",
6+
"description": "Useful for displaying a graphic mark, design, or symbol to represent the site. Once a site logo is set, it can be reused in different places and templates. It should not be confused with the site icon, which is the small image used in the dashboard, browser tabs, public search results, etc, to help recognize a site.",
7+
"textdomain": "default",
8+
"attributes": {
9+
"align": {
10+
"type": "string"
11+
},
12+
"width": {
13+
"type": "number"
14+
},
15+
"isLink": {
16+
"type": "boolean",
17+
"default": true
18+
},
19+
"linkTarget": {
20+
"type": "string",
21+
"default": "_self"
22+
}
23+
},
24+
"supports": {
25+
"html": false,
26+
"align": true,
27+
"alignWide": false
28+
},
29+
"styles": [
30+
{
31+
"name": "default",
32+
"label": "Default",
33+
"isDefault": true
34+
},
35+
{ "name": "rounded", "label": "Rounded" }
36+
],
37+
"editorStyle": "wp-block-site-logo-editor",
38+
"style": "wp-block-site-logo"
39+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* Colors
3+
*/
4+
/**
5+
* Breakpoints & Media Queries
6+
*/
7+
/**
8+
* SCSS Variables.
9+
*
10+
* Please use variables from this sheet to ensure consistency across the UI.
11+
* Don't add to this sheet unless you're pretty sure the value will be reused in many places.
12+
* For example, don't add rules to this sheet that affect block visuals. It's purely for UI.
13+
*/
14+
/**
15+
* Colors
16+
*/
17+
/**
18+
* Fonts & basic variables.
19+
*/
20+
/**
21+
* Grid System.
22+
* https://make.wordpress.org/design/2019/10/31/proposal-a-consistent-spacing-system-for-wordpress/
23+
*/
24+
/**
25+
* Dimensions.
26+
*/
27+
/**
28+
* Shadows.
29+
*/
30+
/**
31+
* Editor widths.
32+
*/
33+
/**
34+
* Block & Editor UI.
35+
*/
36+
/**
37+
* Block paddings.
38+
*/
39+
/**
40+
* React Native specific.
41+
* These variables do not appear to be used anywhere else.
42+
*/
43+
/**
44+
* Breakpoint mixins
45+
*/
46+
/**
47+
* Long content fade mixin
48+
*
49+
* Creates a fading overlay to signify that the content is longer
50+
* than the space allows.
51+
*/
52+
/**
53+
* Focus styles.
54+
*/
55+
/**
56+
* Applies editor left position to the selector passed as argument
57+
*/
58+
/**
59+
* Styles that are reused verbatim in a few places
60+
*/
61+
/**
62+
* Allows users to opt-out of animations via OS-level preferences.
63+
*/
64+
/**
65+
* Reset default styles for JavaScript UI based pages.
66+
* This is a WP-admin agnostic reset
67+
*/
68+
/**
69+
* Reset the WP Admin page styles for Gutenberg-like pages.
70+
*/
71+
.wp-block[data-align=center] > .wp-block-site-logo {
72+
margin-right: auto;
73+
margin-left: auto;
74+
text-align: center;
75+
}
76+
77+
.wp-block-site-logo a {
78+
pointer-events: none;
79+
}
80+
.wp-block-site-logo:not(.is-default-size) {
81+
display: table;
82+
}
83+
.wp-block-site-logo.is-default-size {
84+
width: 120px;
85+
}
86+
.wp-block-site-logo.is-default-size img {
87+
width: 100%;
88+
}
89+
.wp-block-site-logo .custom-logo-link {
90+
cursor: inherit;
91+
}
92+
.wp-block-site-logo .custom-logo-link:focus {
93+
box-shadow: none;
94+
}
95+
.wp-block-site-logo .custom-logo-link.is-transient img {
96+
opacity: 0.3;
97+
}
98+
.wp-block-site-logo img {
99+
display: block;
100+
max-width: 100%;
101+
}
102+
.wp-block-site-logo .components-placeholder {
103+
min-height: auto;
104+
height: 120px;
105+
padding: 8px;
106+
}
107+
.wp-block-site-logo .components-placeholder .components-placeholder__label {
108+
white-space: nowrap;
109+
}
110+
.wp-block-site-logo .components-placeholder .components-placeholder__label .block-editor-block-icon {
111+
margin-left: 4px;
112+
}
113+
.wp-block-site-logo .components-placeholder .components-form-file-upload {
114+
display: none;
115+
}
116+
.wp-block-site-logo .components-placeholder .components-placeholder__preview {
117+
position: absolute;
118+
top: 4px;
119+
left: 4px;
120+
bottom: 4px;
121+
right: 4px;
122+
background: rgba(255, 255, 255, 0.8);
123+
display: flex;
124+
align-items: center;
125+
justify-content: center;
126+
}
127+
.wp-block-site-logo .components-placeholder .components-drop-zone__content-text {
128+
display: none;
129+
}

src/wp-includes/blocks/site-logo/editor-rtl.min.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)