Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ff9c17b
Ipsum: Draw the Button block's focus outline inside the button.
MaggieCabrera Nov 9, 2026
e1fad58
Ipsum: Respect reduced motion in view transitions.
MaggieCabrera Nov 9, 2026
7acbe8d
Ipsum: Register the pattern utility classes as block styles.
MaggieCabrera Nov 9, 2026
15e09a7
Ipsum: Fix the PHPStan level 10 errors that core reports.
MaggieCabrera Nov 9, 2026
e38bced
Ipsum: Provide a minified stylesheet for production.
MaggieCabrera Nov 9, 2026
5efbb1c
Ipsum: Use the border radius shorthand in the patterns.
MaggieCabrera Nov 9, 2026
26ad1fa
Bundled Themes: Build a minified stylesheet for Ipsum.
MaggieCabrera Nov 9, 2026
a864c7c
Bundled Themes: Add Ipsum's stylesheet build process.
MaggieCabrera Nov 9, 2026
a69cdab
Ipsum: Describe every pattern and offer the format patterns as starte…
MaggieCabrera Nov 9, 2026
04dfdd8
Ipsum: Move what theme.json can express out of the block css strings.
MaggieCabrera Nov 9, 2026
b075c95
Ipsum: Clean up editor-only attributes and serialization in the patte…
MaggieCabrera Nov 9, 2026
ba34612
Ipsum: Add DESIGN.md with the theme's design model.
MaggieCabrera Nov 9, 2026
3091026
Ipsum: Inline the theme stylesheet.
MaggieCabrera Nov 9, 2026
b2da500
Ipsum: Return all theme patterns in the design guide after the regist…
MaggieCabrera Nov 9, 2026
09c9672
Merge branch 'trunk' into sync/ipsum
MaggieCabrera Nov 9, 2026
bacb9d2
Add message parameter.
peterwilsoncc Nov 9, 2026
fe4ed4f
Merge branch 'trunk' into sync/ipsum
peterwilsoncc Nov 9, 2026
5c267de
Bad one Wilson, at least you spotted in the PR....
peterwilsoncc Nov 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/workflows/test-and-zip-default-themes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
- 'src/wp-content/themes/twentytwentyone/**'
- 'src/wp-content/themes/twentytwentytwo/**'
- 'src/wp-content/themes/twentytwentyfive/**'
- 'src/wp-content/themes/ipsum/**'
# Changes to this workflow file should always verify success.
- '.github/workflows/test-and-zip-default-themes.yml'
pull_request:
Expand All @@ -35,6 +36,7 @@ on:
- 'src/wp-content/themes/twentytwentyone/**'
- 'src/wp-content/themes/twentytwentytwo/**'
- 'src/wp-content/themes/twentytwentyfive/**'
- 'src/wp-content/themes/ipsum/**'
# Changes to this workflow file should always verify success.
- '.github/workflows/test-and-zip-default-themes.yml'
workflow_dispatch:
Expand Down Expand Up @@ -123,6 +125,7 @@ jobs:
'twentyten',
];
const buildThemes = [
'ipsum',
'twentytwentyfive',
'twentytwentytwo',
'twentytwentyone',
Expand Down Expand Up @@ -339,26 +342,26 @@ jobs:
SELECTED_THEME: ${{ github.event_name == 'workflow_dispatch' && inputs.theme || 'all' }}

- name: Set up Node.js for themes needing minification
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' ) }}
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' || matrix.theme == 'ipsum' ) }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: 'src/wp-content/themes/${{ matrix.theme }}/.nvmrc'
package-manager-cache: false

- name: Set up npm
# A workflow_dispatch run can check out a release branch, which lacks the action.
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' ) && hashFiles('.github/actions/setup-npm/action.yml') != '' }}
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' || matrix.theme == 'ipsum' ) && hashFiles('.github/actions/setup-npm/action.yml') != '' }}
uses: ./.github/actions/setup-npm
with:
working-directory: src/wp-content/themes/${{ matrix.theme }}

- name: Install npm dependencies
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' ) }}
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' || matrix.theme == 'ipsum' ) }}
run: npm ci
working-directory: src/wp-content/themes/${{ matrix.theme }}

- name: Build theme assets
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' ) }}
if: ${{ steps.theme-exists.outputs.exists == 'true' && ( matrix.theme == 'twentytwentytwo' || matrix.theme == 'twentytwentyfive' || matrix.theme == 'ipsum' ) }}
run: npm run build
working-directory: src/wp-content/themes/${{ matrix.theme }}

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ wp-tests-config.php
/src/wp-content/themes/twentytwenty/node_modules
/src/wp-content/themes/twentytwentytwo/node_modules
/src/wp-content/themes/twentytwentyfive/node_modules
/src/wp-content/themes/ipsum/node_modules

# Minified files in bundled themes
/src/wp-content/themes/twentytwentytwo/*.min.css
/src/wp-content/themes/twentytwentyfive/*.min.css
/src/wp-content/themes/ipsum/*.min.css

# Operating system specific files
.DS_Store
Expand Down
2 changes: 2 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module.exports = function(grunt) {
'wp-content/plugins/hello.php',
'wp-content/plugins/akismet/**',
'!wp-content/themes/twenty*/node_modules/**',
'!wp-content/themes/ipsum/node_modules/**',
],

// All built CSS files, in /src or /build.
Expand Down Expand Up @@ -902,6 +903,7 @@ module.exports = function(grunt) {
src: [
'wp-content/themes/twentytwentytwo/style.css',
'wp-content/themes/twentytwentyfive/style.css',
'wp-content/themes/ipsum/style.css',
]
}
},
Expand Down
1 change: 1 addition & 0 deletions src/wp-content/themes/ipsum/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.18
253 changes: 253 additions & 0 deletions src/wp-content/themes/ipsum/DESIGN.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/wp-content/themes/ipsum/assets/css/editor-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* Editor-only overrides. The editors load style.css first, so this file holds
* only what the editors need on top of it.
*
* Sticky header part and pinned search bar: !important because the editor
* forces position:relative on block wrappers.
* Sticky header part and Pinned to Bottom template parts: !important because
* the editor forces position:relative on block wrappers.
*/
header.wp-block-template-part:has(> .is-position-sticky),
.sticky-bottom {
.wp-block-template-part.is-style-sticky-bottom {
position: sticky !important;
}
21 changes: 21 additions & 0 deletions src/wp-content/themes/ipsum/contributing.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
=== Contributing to Ipsum ===

Ipsum is developed at https://github.com/WordPress/ipsum. Changes made there are synced to WordPress core, so please open issues and pull requests in that repository.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little unclear which of the two repos "that repository" refers too. I think everything changes post release (unless there are plans otherwise for this theme) so not a big deal.


= Minifying CSS =

Ipsum has a single stylesheet `style.css` which is enqueued in addition to the global styles coming from core. On a normal production site, when `SCRIPT_DEBUG` is disabled, then the minified version `style.min.css` will be enqueued instead, unless `style.css` has changed since `style.min.css` was built. If you make a change to `style.css`, you'll need to re-minify the `style.min.css` using the built-in npm build tool. As always, it is preferable to use the Site Editor to supply Additional CSS instead of directly editing the theme stylesheet.

Installation instructions

1. Using a command line interface, go to the “ipsum” directory `cd /my-computer/local-wordpress-install/src/wp-content/themes/ipsum`.

2. Type `npm install` into the command line, and press the [return] key, to install all Node.js dependencies.

3. The dependencies may take a few minutes to download but once it completes, you’re done.

Usage instructions

1. After making a change to the `style.css` file, run `npm run build` from within the theme directory to regenerate `style.min.css` with your new changes.

2. You can also “watch” the theme directory for CSS changes and re-minify the CSS anytime a change occurs by running: `npm run watch`.
154 changes: 139 additions & 15 deletions src/wp-content/themes/ipsum/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,35 @@ function ipsum_add_theme_support() {
* @return void
*/
function ipsum_enqueue_styles() {
$style_path = get_parent_theme_file_path( 'style.css' );
$style_min_path = get_parent_theme_file_path( 'style.min.css' );

/*
* Use the minified stylesheet, unless script debugging is on or style.css
* has changed since style.min.css was built. That keeps edits made in the
* Theme File Editor working: saving style.css makes it the newer file.
*/
if (
SCRIPT_DEBUG
|| ! file_exists( $style_min_path )
|| ( filemtime( $style_path ) > filemtime( $style_min_path ) )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is in the build step for WP-Dev, I think we can replace this with a simple SCRIPT_DEBUG.

The process for uploading themes to the theme repo is to use the zips generated by the build steps in wp-dev so it shouldn't be a problem as it too contains the compressed file, see this action run.

) {
$src = 'style.css';
} else {
$src = 'style.min.css';
}

// Register theme stylesheet.
wp_register_style(
'ipsum-style',
get_parent_theme_file_uri( 'style.css' ),
get_parent_theme_file_uri( $src ),
array(),
wp_get_theme()->get( 'Version' )
wp_get_theme( get_template() )->get( 'Version' )
);

// Let WordPress inline the stylesheet, so it is not a render-blocking request.
wp_style_add_data( 'ipsum-style', 'path', get_parent_theme_file_path( $src ) );

// Enqueue theme stylesheet.
wp_enqueue_style( 'ipsum-style' );
}
Expand All @@ -69,21 +90,29 @@ function ipsum_enqueue_styles() {
*
* @since Ipsum 1.0
*
* @param array $source_args Block binding source arguments.
* @param WP_Block $block_instance The block instance.
* @return string The call to action text.
* @param array<string, mixed> $source_args Block binding source arguments. Unused.
* @param WP_Block $block_instance The block instance.
* @return string|null The call to action text, an empty string when comments
* are closed, or null to keep the block's original content
* when there is no post.
*/
function ipsum_comments_cta_binding( $source_args, $block_instance ) {
$post_id = $block_instance->context['postId'] ?? get_the_ID();
unset( $source_args ); // Unused, but must be accepted to get the block instance.

$post_id = $block_instance->context['postId'] ?? null;
$post = get_post( is_numeric( $post_id ) ? (int) $post_id : null );
if ( ! $post ) {
return null;
}

if ( ! comments_open( $post_id ) ) {
if ( ! comments_open( $post ) ) {
return '';
}

$post_title = wp_strip_all_tags( get_the_title( $post_id ) );
$post_title = wp_strip_all_tags( get_the_title( $post ) );
$has_title = ! empty( $post_title );

if ( get_comments_number( $post_id ) > 0 ) {
if ( get_comments_number( $post ) > 0 ) {
$text = $has_title
? sprintf(
/* translators: %s: Post title. */
Expand All @@ -101,7 +130,7 @@ function ipsum_comments_cta_binding( $source_args, $block_instance ) {
: __( 'Be the first to comment', 'ipsum' );
}

return '<a href="' . esc_url( get_comments_link( $post_id ) ) . '">' . wp_kses_post( $text ) . '</a>';
return '<a href="' . esc_url( get_comments_link( $post ) ) . '">' . wp_kses_post( $text ) . '</a>';
}
endif;

Expand Down Expand Up @@ -133,8 +162,9 @@ function ipsum_register_block_bindings() {
*
* @since Ipsum 1.0
*
* @param array $default_template_types The default template types.
* @return array The template types, with the sidebar variants added.
* @param array<string, array<string, string>> $default_template_types The default template types, keyed by
* slug, each with a title and description.
* @return array<string, array<string, string>> The template types, with the sidebar variants added.
*/
function ipsum_sidebar_template_types( $default_template_types ) {
$default_template_types['index-sidebar'] = array(
Expand Down Expand Up @@ -166,6 +196,14 @@ function ipsum_register_pattern_categories() {
'description' => __( 'Full page layouts, ready to be applied to a page.', 'ipsum' ),
)
);

register_block_pattern_category(
'ipsum_post-format',
array(
'label' => _x( 'Post formats', 'Block pattern category', 'ipsum' ),
'description' => __( 'Layouts for post formats, like audio and link posts.', 'ipsum' ),
)
);
}
endif;
add_action( 'init', 'ipsum_register_pattern_categories' );
Expand All @@ -182,12 +220,14 @@ function ipsum_register_pattern_categories() {
*
* @since Ipsum 1.0
*
* @param array $metadata Metadata for the block type being registered.
* @return array The block metadata, with ARIA label support on the Search block.
* @param array<string, mixed> $metadata Metadata for the block type being registered.
* @return array<string, mixed> The block metadata, with ARIA label support on the Search block.
*/
function ipsum_search_aria_label_support( $metadata ) {
if ( isset( $metadata['name'] ) && 'core/search' === $metadata['name'] ) {
$metadata['supports']['ariaLabel'] = true;
$supports = isset( $metadata['supports'] ) && is_array( $metadata['supports'] ) ? $metadata['supports'] : array();
$supports['ariaLabel'] = true;
$metadata['supports'] = $supports;
}
return $metadata;
}
Expand All @@ -201,6 +241,10 @@ function ipsum_search_aria_label_support( $metadata ) {
* The Evening code style keeps the Evening palette's literals on purpose,
* so the block reads as a dark slab under every style variation.
*
* Each style's CSS is an inline style, as in the default themes. Row Hover
* can't move to styles/blocks/, because a theme.json css string cannot hold
* its at-rules and selector lists.
*
* @since Ipsum 1.0
*
* @return void
Expand All @@ -223,6 +267,86 @@ function ipsum_register_block_styles() {
'inline_style' => '.wp-block-site-logo.is-style-sharp{border-radius:0;}',
)
);

/*
* Pins the part to the bottom of the viewport, so it belongs at the root
* of the template. It keeps to its content's width at the inline end, so
* the rest of the band doesn't block clicks on the page. The editors also
* need the override in editor-style.css.
*/
register_block_style(
'core/template-part',
array(
'name' => 'sticky-bottom',
'label' => _x( 'Pinned to Bottom', 'Block style label', 'ipsum' ),
'inline_style' => '
.wp-block-template-part.is-style-sticky-bottom {
position: sticky;
inset-block-end: 0;
z-index: 10;
width: fit-content;
margin-inline-start: auto;
}',
)
);

/*
* Outlines the Search button until it is hovered, focused or pressed, when
* the global button states take back over. A theme.json css string would
* wrap this in :where() and only tie with the global button styles.
*/
register_block_style(
'core/search',
array(
'name' => 'outline',
'label' => _x( 'Outline', 'Block style label', 'ipsum' ),
'inline_style' => '
.wp-block-search.is-style-outline .wp-block-search__button.wp-element-button:not(:hover):not(:focus):not(:active) {
background-color: var(--wp--preset--color--base);
border: 1px dotted var(--wp--preset--color--contrast);
color: var(--wp--preset--color--contrast);
}',
)
);

/*
* Hovering any part of a post row colors the whole row and tilts its
* featured image. Targets the row's child blocks, since the Group spans
* the full band. Needs each post's blocks wrapped in one Group.
*/
register_block_style(
'core/post-template',
array(
'name' => 'hover-together',
'label' => _x( 'Row Hover', 'Block style label', 'ipsum' ),
'inline_style' => '
.wp-block-post-template.is-style-hover-together .wp-block-post > .wp-block-group,
.wp-block-post-template.is-style-hover-together .wp-block-post > .wp-block-group a {
transition: color 0.15s ease-out;
}

.wp-block-post-template.is-style-hover-together .wp-block-post > .wp-block-group:has(> :hover),
.wp-block-post-template.is-style-hover-together .wp-block-post > .wp-block-group:has(> :hover) a {
color: var(--wp--preset--color--accent-3);
}

@media (prefers-reduced-motion: no-preference) {
@keyframes tilt-settle {
35% {
transform: rotate(-1deg);
}

100% {
transform: rotate(0deg);
}
}

.wp-block-post-template.is-style-hover-together .wp-block-post > .wp-block-group:has(> :hover) .wp-block-post-featured-image img {
animation: tilt-settle 0.5s ease-out;
}
}',
)
);
}
endif;
add_action( 'init', 'ipsum_register_block_styles' );
Expand Down
Loading
Loading