Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/vendor/
/node_modules/
/build/

# Composer
composer.lock
2 changes: 1 addition & 1 deletion .plugin-data
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "1.1.2",
"version": "1.1.3",
"slug": "beapi-acf-palette"
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

Nothing yet.

## [1.1.3] - 2026-07-08

- Add support for v3 theme json schema

## [1.1.2] - 2026-07-07

- Add support for PHP 8.4
Expand Down
4 changes: 2 additions & 2 deletions beapi-acf-palette.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/*
Plugin Name: Be API - ACF Color Palette
Version: 1.1.2
Version: 1.1.3
Version Boilerplate: 3.5.0
Plugin URI: https://beapi.fr
Description: Add a new theme color palette selector field for Advanced Custom Fields.
Expand Down Expand Up @@ -35,7 +35,7 @@
}

// Plugin constants
define( 'BEAPI_ACF_PALETTE_VERSION', '1.1.2' );
define( 'BEAPI_ACF_PALETTE_VERSION', '1.1.3' );
define( 'BEAPI_ACF_PALETTE_VIEWS_FOLDER_NAME', 'beapi-acf-palette' );

// Plugin URL and PATH
Expand Down
175 changes: 135 additions & 40 deletions classes/Theme_Color_Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,33 +103,12 @@ public function enqueue_admin_styles(): void {
* @return array Array of color options
*/
public static function get_theme_colors( string $source = 'settings' ): array {
// Try multiple possible paths for theme.json
$possible_paths = [
get_template_directory() . '/src/theme-json/settings-color.json',
get_theme_file_path( 'theme.json' ),
get_stylesheet_directory() . '/src/theme-json/settings-color.json',
];

$theme_json_path = null;
foreach ( $possible_paths as $path ) {
if ( is_readable( $path ) ) {
$theme_json_path = $path;
break;
}
}

if ( ! $theme_json_path ) {
return [];
}

$theme_json_content = file_get_contents( $theme_json_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$theme_json = json_decode( $theme_json_content, true );
$theme_json = self::load_theme_json_file();

if ( ! $theme_json ) {
return [];
}

// Get colors based on source
if ( 'custom' === $source ) {
return self::get_custom_colors( $theme_json );
}
Expand All @@ -142,18 +121,120 @@ public static function get_theme_colors( string $source = 'settings' ): array {
}

/**
* Get colors from settings.color.palette
* Load the active theme theme.json file.
*
* @param array $theme_json Decoded theme.json content
* @return array Array of color options
* @return array|null Decoded theme.json content
*/
private static function get_settings_colors( array $theme_json ): array {
if ( ! isset( $theme_json['settings']['color']['palette'] ) ) {
return [];
private static function load_theme_json_file(): ?array {
$theme_json_path = get_theme_file_path( 'theme.json' );

if ( ! is_readable( $theme_json_path ) ) {
return null;
}

$theme_json_content = file_get_contents( $theme_json_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$theme_json = json_decode( $theme_json_content, true );

return is_array( $theme_json ) ? $theme_json : null;
Comment thread
firestar300 marked this conversation as resolved.
}

/**
* Extract palette colors from theme.json across supported versions.
*
* @param array $theme_json Decoded theme.json content.
* @return array Palette definition from theme.json.
*/
private static function extract_palette_from_theme_json( array $theme_json ): array {
$palette = $theme_json['settings']['color']['palette']
?? $theme_json['settings']['palette']
?? $theme_json['color']['palette']
?? [];

return is_array( $palette ) ? $palette : [];
}

/**
* Extract custom color map from theme.json across supported versions.
*
* @param array $theme_json Decoded theme.json content.
* @return array Custom color map from theme.json.
*/
private static function extract_custom_color_map_from_theme_json( array $theme_json ): array {
$custom_color_sources = [
$theme_json['settings']['custom']['color'] ?? null,
$theme_json['custom']['color'] ?? null,
$theme_json['settings']['color']['custom'] ?? null,
];

foreach ( $custom_color_sources as $custom_colors ) {
if ( ! is_array( $custom_colors ) || [] === $custom_colors ) {
continue;
}

$normalized_colors = self::normalize_custom_color_map( $custom_colors );

if ( [] !== $normalized_colors ) {
return $normalized_colors;
}
}
Comment thread
firestar300 marked this conversation as resolved.

return [];
}

/**
* Normalize custom color values from theme.json.
*
* Supports string values and palette-like objects.
*
* @param array $custom_colors Custom color map from theme.json.
* @return array<string, string> Normalized slug => color map.
*/
private static function normalize_custom_color_map( array $custom_colors ): array {
$normalized = [];

foreach ( $custom_colors as $slug => $value ) {
if ( ! is_string( $slug ) ) {
continue;
}

$color = self::extract_color_value( $value );

if ( null !== $color ) {
$normalized[ $slug ] = $color;
}
}

return $normalized;
}

/**
* Extract a color value from theme.json custom color definitions.
*
* @param mixed $value Color value from theme.json.
* @return string|null
*/
private static function extract_color_value( mixed $value ): ?string {
if ( is_string( $value ) && '' !== $value ) {
return $value;
}

if ( is_array( $value ) && isset( $value['color'] ) && is_string( $value['color'] ) && '' !== $value['color'] ) {
return $value['color'];
}

return null;
}

/**
* Format palette colors from theme.json settings.color.palette.
*
* @param array $palette Palette definition from theme.json.
* @return array Array of color options
*/
private static function format_palette_colors( array $palette ): array {
$colors = [];
foreach ( $theme_json['settings']['color']['palette'] as $color ) {

foreach ( $palette as $color ) {
if ( isset( $color['name'], $color['slug'], $color['color'] ) ) {
$colors[ $color['slug'] ] = [
'name' => $color['name'],
Expand All @@ -167,23 +248,17 @@ private static function get_settings_colors( array $theme_json ): array {
}

/**
* Get colors from custom.color
* Format custom colors from theme.json settings.custom.color.
*
* @param array $theme_json Decoded theme.json content
* @param array $custom_colors Custom color map from theme.json.
* @return array Array of color options
*/
private static function get_custom_colors( array $theme_json ): array {
if ( ! isset( $theme_json['custom']['color'] ) || ! is_array( $theme_json['custom']['color'] ) ) {
return [];
}

private static function format_custom_color_map( array $custom_colors ): array {
$colors = [];
foreach ( $theme_json['custom']['color'] as $slug => $hex_color ) {
// Generate a readable name from the slug
$name = self::format_slug_to_name( $slug );

foreach ( self::normalize_custom_color_map( $custom_colors ) as $slug => $hex_color ) {
$colors[ $slug ] = [
'name' => $name,
'name' => self::format_slug_to_name( $slug ),
'slug' => $slug,
'color' => $hex_color,
];
Expand All @@ -192,6 +267,26 @@ private static function get_custom_colors( array $theme_json ): array {
return $colors;
}

/**
* Get colors from settings.color.palette
*
* @param array $theme_json Decoded theme.json content
* @return array Array of color options
*/
private static function get_settings_colors( array $theme_json ): array {
return self::format_palette_colors( self::extract_palette_from_theme_json( $theme_json ) );
}

/**
* Get colors from settings.custom.color
*
* @param array $theme_json Decoded theme.json content
* @return array Array of color options
*/
private static function get_custom_colors( array $theme_json ): array {
return self::format_custom_color_map( self::extract_custom_color_map_from_theme_json( $theme_json ) );
}

/**
* Get colors from both settings.color.palette and custom.color
*
Expand Down
26 changes: 15 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
"name": "beapi/acf-palette",
"description": "Add a new theme color palette selector field for Advanced Custom Fields.",
"type": "wordpress-plugin",
"keywords": ["wordpress", "plugin", "acf", "fse", "theme.json", "color", "palette", "gutenberg", "editor"],
"keywords": [
"wordpress",
"plugin",
"acf",
"fse",
"theme.json",
"color",
"palette",
"gutenberg",
"editor"
],
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "BeAPI",
"email": "technical@beapi.fr",
"homepage":"https://beapi.fr",
"role":"Company"
"homepage": "https://beapi.fr",
"role": "Company"
}
],
"config": {
Expand All @@ -32,39 +42,33 @@
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"humanmade/psalm-plugin-wordpress": "3.1.1",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpcompatibility/php-compatibility": "^9.3",
"phpro/grumphp-shim": "^2.22",
"roave/security-advisories": "dev-latest",
"roots/wordpress-no-content": "^6.0",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "^6.16",
"wp-cli/wp-cli": "^2.6",
"wp-coding-standards/wpcs": "^3.0"
"wp-coding-standards/wpcs": "^3.3.0"
},
"autoload": {
"psr-4": {
"BEAPI\\Acf_Palette\\": "classes/"
}
},
"autoload-dev": {
},
"autoload-dev": {},
"scripts": {
"cs": "./vendor/bin/phpcs",
"cb": "./vendor/bin/phpcbf",
"psalm": "./vendor/bin/psalm",
"phpunit": "phpunit",
"lint": [
"bin/php-lint",
"@psalm",
"@cs"
]
},
"scripts-descriptions": {
"cs": "Run PHP CodeSniffer on plugin codebase using our ruleset.",
"cbf": "Run PHP Code Beautifier and Fixer on plugin codebase using our ruleset.",
"psalm": "Run psalm on plugin codebase using our ruleset.",
"lint": "Run all lint tasks."
}
}
Loading
Loading