Skip to content

Modularise theme.json into preset files#4

Merged
krugazul merged 3 commits intodevelopfrom
setup-themejson-to-presets
Apr 8, 2026
Merged

Modularise theme.json into preset files#4
krugazul merged 3 commits intodevelopfrom
setup-themejson-to-presets

Conversation

@krugazul
Copy link
Copy Markdown
Contributor

@krugazul krugazul commented Apr 8, 2026

Summary

  • add modular preset loading via inc/presets.php using wp_theme_json_data_theme
  • recursively discover and merge all preset JSON files in styles/presets/**
  • split theme.json nodes into modular preset files (layout, spacing, typography, shadows, radii, buttons, links, and block-specific button variation)
  • keep theme.json focused on core theme metadata and colour definitions for WordPress recognition

Files Added

  • inc/presets.php
  • styles/presets/layout.json
  • styles/presets/spacing.json
  • styles/presets/typography.json
  • styles/presets/shadows.json
  • styles/presets/radii.json
  • styles/presets/buttons.json
  • styles/presets/links.json
  • styles/presets/blocks/core-button.json

Files Updated

  • theme.json

Notes

  • No image files are included in this PR.
  • Preset naming and structure align with the modular pattern used in die-papier-tema (styles/presets + styles/presets/blocks).

Validation

  • validated JSON syntax for all files under styles/presets/**/*.json
  • validated JSON syntax for theme.json

Command run:

find styles/presets -name '*.json' -print | sort | while read -r f; do
  php -r '$s=file_get_contents($argv[1]); json_decode($s,true); if (json_last_error()) { fwrite(STDERR,$argv[1].": ".json_last_error_msg().PHP_EOL); exit(1);} ' "$f" || exit 1
done
php -r '$s=file_get_contents("theme.json"); json_decode($s,true); if (json_last_error()) { fwrite(STDERR,"theme.json: ".json_last_error_msg().PHP_EOL); exit(1);} echo "JSON OK".PHP_EOL;'

Summary by CodeRabbit

  • New Features

    • Modular theme presets added: typography (new fonts & fluid sizes), spacing scale, shadows, border radii, layout sizes, link styles, and button variations (including an “outline” variation).
    • Presets now load from dedicated preset files, enabling isolated theme style updates.
  • Refactor

    • Consolidated and removed large inline theme settings in favor of separate preset files for easier maintenance.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

Caution

Review failed

The pull request is closed.

Note

.coderabbit.yml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'version'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: fb9c7bfc-74e1-45d2-b670-255a5a86d65d

📥 Commits

Reviewing files that changed from the base of the PR and between 80a7c85 and d554963.

📒 Files selected for processing (1)
  • functions.php

📝 Walkthrough

Walkthrough

Added a PHP loader that discovers and merges JSON preset files from styles/presets/ into the active theme’s WP_Theme_JSON_Data, and moved many theme settings/styles out of theme.json into modular preset files under styles/presets/.

Changes

Cohort / File(s) Summary
PHP Preset Loader
inc/presets.php
New loader registering wp_theme_json_data_theme filter with merge_preset_files(), plus get_preset_files_recursive() to discover, sort, and load *.json files; decodes JSON and merges arrays into WP_Theme_JSON_Data via update_with(); handles missing/empty directories and invalid JSON gracefully.
Theme include
functions.php
Added require get_template_directory() . '/inc/presets.php' to load the preset loader during theme initialization.
Modularized Presets — Layout / Radii / Shadows / Links
styles/presets/layout.json, styles/presets/radii.json, styles/presets/shadows.json, styles/presets/links.json
Added layout settings (content/wide sizes, appearanceTools), radius presets (6 sizes), custom shadow presets (Tiny→X-Large), and link element styling with hover color.
Modularized Presets — Spacing / Typography / Buttons / Block Variation
styles/presets/spacing.json, styles/presets/typography.json, styles/presets/buttons.json, styles/presets/blocks/core-button.json
Added spacing preset sizes & units and styles spacing defaults; comprehensive typography system (font-face entries, fluid sizes, custom line-heights, heading styles); button element styles and CSS variable mappings; core/button block variation (outline).
Theme Configuration Refactor
theme.json
Removed extensive preset definitions from settings and styles (spacing, typography, custom tokens, shadow, border, layout, element overrides, and block variations) leaving core palette and basic color styles; content moved into modular preset files.

Sequence Diagram

sequenceDiagram
    actor WP as WordPress
    participant Filter as wp_theme_json_data_theme (hook)
    participant Loader as merge_preset_files()
    participant FS as FileSystem
    participant Parser as json_decode
    participant ThemeData as WP_Theme_JSON_Data

    WP->>Filter: trigger filter with ThemeData
    Filter->>Loader: call merge_preset_files(ThemeData)
    Loader->>FS: stat /styles/presets/ directory
    FS-->>Loader: directory exists / not exists
    alt directory exists
        Loader->>FS: find *.json recursively
        FS-->>Loader: return sorted file list
        loop per file
            Loader->>FS: read file content
            FS-->>Loader: json string
            Loader->>Parser: json_decode(content)
            Parser-->>Loader: parsed array/object
            alt parsed is array/object
                Loader->>ThemeData: ThemeData.update_with(parsed)
                ThemeData-->>Loader: merged
            end
        end
    end
    Loader-->>Filter: return ThemeData
    Filter-->>WP: filtered ThemeData used by WP
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through folders, tiny and neat,

Found JSON treasures, each preset a treat.
I sorted and merged with careful delight,
Now theme styles dance, tidy and bright. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Modularise theme.json into preset files' clearly and accurately summarizes the main change: refactoring a monolithic theme.json into modular preset files with a loader mechanism.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch setup-themejson-to-presets

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements a modular theme configuration system by extracting settings and styles from theme.json into individual files within a new presets directory. A PHP utility was added to recursively load and merge these JSON files into the theme data. Review feedback suggests optimizing the PHP loading process with static caching and wp_json_file_decode() to reduce overhead, and standardizing the token reference syntax to use the var:preset and var:custom formats across the configuration files for better consistency and maintainability.

Comment on lines +37 to +63
$preset_dir = get_template_directory() . '/styles/presets/';

// Automatically discover all JSON files in the presets directory.
if ( ! is_dir( $preset_dir ) ) {
return $theme_json;
}

// Recursively find all JSON files in presets directory and subdirectories.
$preset_files = get_preset_files_recursive( $preset_dir );

if ( empty( $preset_files ) ) {
return $theme_json;
}

// Sort alphabetically for predictable loading order.
sort( $preset_files );

foreach ( $preset_files as $file ) {
$preset_data = json_decode( file_get_contents( $file ), true ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents

if ( ! is_array( $preset_data ) ) {
continue;
}

// Use WordPress's native merge method via update_with().
$theme_json->update_with( $preset_data );
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation performs recursive directory scanning and JSON decoding on every execution of the wp_theme_json_data_theme filter. This can lead to unnecessary disk I/O and CPU overhead, especially on sites with many preset files or without persistent object caching.

Additionally, using wp_json_file_decode() is more idiomatic in WordPress and provides better handling for JSON files compared to file_get_contents() and json_decode().

Consider caching the decoded preset data in a static variable to improve performance.

	static $cached_presets = null;

	if ( null === $cached_presets ) {
		$cached_presets = array();
		$preset_dir     = get_template_directory() . '/styles/presets/';

		if ( is_dir( $preset_dir ) ) {
			$preset_files = get_preset_files_recursive( $preset_dir );
			if ( ! empty( $preset_files ) ) {
				sort( $preset_files );
				foreach ( $preset_files as $file ) {
					$data = wp_json_file_decode( $file, array( 'associative' => true ) );
					if ( is_array( $data ) ) {
						$cached_presets[] = $data;
					}
				}
			}
		}
	}

	foreach ( $cached_presets as $preset_data ) {
		$theme_json->update_with( $preset_data );
	}

"elements": {
"link": {
"color": {
"text": "var(--wp--preset--color--accent-500)"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For better consistency with other preset files (like buttons.json) and to leverage WordPress's internal preset resolution, use the var:preset|color|accent-500 syntax instead of the full CSS variable string.

Suggested change
"text": "var(--wp--preset--color--accent-500)"
"text": "var:preset|color|accent-500"

},
":hover": {
"color": {
"text": "var(--wp--preset--color--accent-two-500)"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Use the var:preset syntax for consistency.

Suggested change
"text": "var(--wp--preset--color--accent-two-500)"
"text": "var:preset|color|accent-two-500"

Comment on lines +267 to +268
"fontSize": "var(--wp--preset--font-size--200)",
"lineHeight": "var(--wp--custom--line-height--paragraph)"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Use the var:preset and var:custom syntax for referencing design tokens. This improves maintainability and ensures the references are correctly resolved by the WordPress engine.

Suggested change
"fontSize": "var(--wp--preset--font-size--200)",
"lineHeight": "var(--wp--custom--line-height--paragraph)"
"fontSize": "var:preset|font-size|200",
"lineHeight": "var:custom|line-height|paragraph"

@krugazul krugazul self-assigned this Apr 8, 2026
@krugazul krugazul added area:theme Theme & styles (templates, template parts, FSE) comp:theme-json Tokens, presets, settings labels Apr 8, 2026
@krugazul krugazul merged commit ad0777b into develop Apr 8, 2026
2 of 3 checks passed
@krugazul krugazul deleted the setup-themejson-to-presets branch April 8, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:theme Theme & styles (templates, template parts, FSE) comp:theme-json Tokens, presets, settings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant