fix: ensure buttons pick up all colours, fonts sizes, font class styles#2337
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the server-side rendering for the Checkout Button block so front-end output better matches editor-applied typography and color styles (notably for WP 7.0 font options and custom colors), and tidies class-string output by filtering empty class tokens.
Changes:
- Add missing typography-related classes (
has-*-font-size,has-*-font-family) to the rendered checkout button element. - Ensure
has-background/has-text-colorclasses are applied when colors come from custom values instyle, not only from theme palette slugs. - Filter out empty class entries when building class strings to avoid extra spacing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/blocks/checkout-button/view.php |
Adjusts how button classes/styles are generated so preset/custom colors and typography are reflected on the front-end. |
includes/class-newspack-blocks.php |
Filters empty class tokens in block_classes() to reduce stray whitespace in class attributes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
chickenn00dle
left a comment
There was a problem hiding this comment.
Tested locally and the changes look good — approving. A few non-blocking suggestions inline, plus two out-of-diff observations below.
src/blocks/checkout-button/view.php:171 — pre-existing leading space in ' has-custom-width …' produces double-spaces in the imploded class list (array_filter drops empties but doesn't trim). Since this PR cleans up extra spacing between CSS classes, it'd be worth fixing here too.
src/blocks/checkout-button/view.php:99-104 — $button_classes / $button_styles are interpolated via %1$s / %2$s without an outer esc_attr(). Individual segments are escaped before imploding, so values are safe today, but a defense-in-depth esc_attr() at the sprintf site (or moving escaping into block_classes() itself) would prevent future contributors from missing it.
| } | ||
|
|
||
| return implode( ' ', $classes ); | ||
| return implode( ' ', array_filter( $classes ) ); |
There was a problem hiding this comment.
Non-blocking: array_filter() here is cross-cutting — all callers of block_classes() (carousel, author-profile, homepage-articles, author-profile-card template) get this empty-string trim, not just checkout-button. Worth a one-line PR-description callout for reviewers of those other blocks.
Also: bare array_filter() strips all falsy values, so a legitimate '0' class would be dropped. None of the current callers can produce '0', but array_filter( $classes, 'strlen' ) would be more explicit about intent.
There was a problem hiding this comment.
God call, @chickenn00dle! I've added strlen in e24b44c, and updated the PR description to mention the other blocks that will be affected.
| $background_color ? 'has-' . esc_attr( $background_color ) . '-background-color' : '', | ||
| $gradient ? 'has-' . esc_attr( $gradient ) . '-gradient-background' : '', | ||
| $font_size ? 'has-' . esc_attr( $font_size ) . '-font-size' : '', | ||
| $font_family ? 'has-' . esc_attr( $font_family ) . '-font-family' : '', |
There was a problem hiding this comment.
Non-blocking: font-family / font-size slugs go directly into class names via esc_attr(). If a theme ever ships a slug with uppercase or unusual characters (e.g. Inter), the emitted has-Inter-font-family won't match what core writes (has-inter-font-family). In practice the editor lowercases slugs, but sanitize_html_class() is one extra line and would harden it.
There was a problem hiding this comment.
In practice the editor lowercases slugs...
It looks like it does in some cases, but not for dynamic blocks (like the Core search block, or this one): if you make one of the colour slugs capitalized in the theme.json, it will come out that way in the front-end and not match the CSS class.
Ditto weird characters -- like *. Core doesn't remove them from dynamic Core block classes, even if it does remove them from the classes generated for CSS (they get replaced with a -).
Based on this, this block acts like a dynamic block in Core, so I'm going to leave this as is for now. It doesn't sound like theme authors are running into this issue with wacky slug choices 🙂
Thanks for flagging this though, @chickenn00dle! It was kind of cool to see how this stuff is being handled under the hood!
| $gradient ? 'has-' . esc_attr( $gradient ) . '-gradient-background' : '', | ||
| $font_size ? 'has-' . esc_attr( $font_size ) . '-font-size' : '', | ||
| $font_family ? 'has-' . esc_attr( $font_family ) . '-font-family' : '', | ||
| $text_align ? 'has-text-align-' . esc_attr( $text_align ) : '', |
There was a problem hiding this comment.
Non-blocking: no has-custom-font-family companion. A style.typography.fontSize (custom) path gets has-custom-font-size further down (~line 170), but a style.typography.fontFamily (custom) path has no parallel hook. wp_style_engine_get_styles still injects the inline CSS, but the asymmetry means themes have nothing to target for custom font-families. Consider parity.
There was a problem hiding this comment.
Thanks @chickenn00dle! I'm going to hold off on this one as well for now:
Unlike options like colours or font size, there is no free-form font family input. Any fonts registered through Appearance > Fonts or from a block theme's theme.json generate a CSS class that will be used to assign the fonts. There isn't actually a pathway to get the font assigned via a style attribute using this dropdown, which is how custom colours & fonts are applied, and why CSS classes for them have a bit more of a utility.
If it turns out there IS a use case for this, we can absolutely add it down the road, though!
There was a problem hiding this comment.
Tested this on WP 7.0-RC3 with the block theme: added a page with checkout buttons covering theme palette colours, custom hex colours, theme font size, custom font size, the Cardo theme font family and a custom gradient. Front-end output is correct in every case now — the right has-{slug}-* classes, custom values still emitted inline by the style engine, and no more background-color: primary-style garbage or stray double-spaces in the class list. Nice fix.
One thing worth deciding on before merge (the textColor note inline). Not blocking.
One more out-of-diff observation: no render test for this block (cf. tests/test-donate-block.php for the donate block), and this is exactly the class/style serialization that's regressed a couple of times on this branch. A focused test — assert preset attrs produce the has-{slug}-* classes with no slug-as-value inline CSS, style.color.background/gradient trigger has-background, and Newspack_Blocks::block_classes() emits no leading/trailing/double spaces — would be cheap insurance.
| $text_align ? 'has-text-align-' . esc_attr( $text_align ) : '', | ||
| isset( $style['border']['radius'] ) && $style['border']['radius'] === 0 ? 'no-border-radius' : '', | ||
| $button_color ? 'has-text-color has-' . esc_attr( $button_color ) . '-color' : '', | ||
| ( $button_color || isset( $style['color']['text'] ) ) ? 'has-text-color' : '', |
There was a problem hiding this comment.
Suggestion: The render callback reads $attributes['backgroundColor'] (line 88) but never $attributes['textColor']. So a named preset text colour picked via the block's Text control lands in textColor (the slug) and is silently dropped on the front end — no has-text-color, no has-{slug}-color. The new ( $button_color || isset( $style['color']['text'] ) ) guard covers the custom-hex text colour, and $button_color covers a preset link colour stored under style.elements.link.color.text — but not the plain textColor attribute, which is what the block's own colour UI actually writes for a preset.
Confirmed at runtime: a button with textColor: "accent" on a light (base-2) background renders with the default white text — effectively invisible — while the editor renders it correctly (has-base-color/has-accent-color). So there's an editor↔front-end mismatch for the most common text-colour case.
This is pre-existing (trunk's view.php also doesn't read textColor), so the PR doesn't regress anything — but the PR title is "pick up all colours" and it's reworking exactly these lines, so it'd be the natural place to add $text_color = $attributes['textColor'] ?? '';, fold it into the has-text-color guard, and emit has-{slug}-color. Worth also reconsidering the style.elements.link.color.text branch: it only fires for the var:preset|color|{slug} form (a custom hex there is dropped), and elements.link is the core/button storage path — for this <button> block the colour UI writes to textColor / style.color.text, so that branch may be dead code.
There was a problem hiding this comment.
Thanks @adekbadek!
I couldn't quite reproduce this problem on in RC 4 with the block theme, but the change makes sense from a code perspective (the attribute that's written is actually getting used) -- updated in a3cbd87.
With this fix, I got a little paranoid and kept style.elements.link.color.text as a fallback - I'm not sure if it was ever used and is dead, or is some old remnant of something that could show up in published blocks. After duking it out with Claude, we're both vaguely paranoid about it being used 😅 In my testing right now with the code as is, it gets populated with the same value as $attributes['textColor'] somehow -- when the code outputs CSS classes for both, you get two identical text colour classes, both with the classic and block theme.
Hope this is an okay compromise but we can revisit in a future PR if it seems safe to cut entirely!
|
Thank you both for your reviews, @chickenn00dle and @adekbadek! I ended up adding both out-of-diff requests, since I think they're solid additions to this PR:
I'm going to go ahead and merge this but it'll go to alpha before getting released -- so if any of this sounds wrong or should be revisited, please let me know! |
|
Hey @laurelfulford, good job getting this PR merged! 🎉 Now, the Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label. If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label. Thank you! ❤️ |
|
🎉 This PR is included in version 4.26.4-alpha.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## [4.26.4-alpha.1](Automattic/newspack-blocks@v4.26.3...v4.26.4-alpha.1) (2026-05-21) ### Bug Fixes * ensure buttons pick up all colours, fonts sizes, font class styles ([#2337](Automattic/newspack-blocks#2337)) ([c13fc94](Automattic/newspack-blocks@c13fc94)) * force alpha ([ab52b60](Automattic/newspack-blocks@ab52b60)) (cherry picked from commit 845e98a4eec11c58f0502a8adc6794b889a0c965)
All Submissions:
Changes proposed in this Pull Request:
This PR originated as a way to fix an issue with the new font options coming in WP 7.0, but it also fixes a couple minor issues with button styles:
has-backgroundCSS class when custom background colours are applied, not just colours from the default palette; dittohas-text-color.Edited to add:
This PR updates
block_classes()inincludes/class-newspack-blocks.php, which is shared by all server-rendered blocks. The newarray_filter()on the return value also affects:homepage-articles(Content Loop)carousel(Content Carousel)author-profile(and theauthor-profile-cardtemplate)Closes NEWS-1754
How to test the changes in this Pull Request:
...menu and select 'Font', then use it to change the font-family on one of the buttons.background-color: primary)has-backgroundandhas-text-colorclasses, respectively.Other information: