Search code examples
phpcsswordpresswordpress-gutenberggutenberg-blocks

Dynamically generate add_theme_support( 'editor-color-palette') colors based on CSS :root variables


Is there a way I can dynamically generate the color variables passed to the function below by reading them from the CSS :root variables?

I am currently only able to hard code them like the function below:

add_theme_support( 'editor-color-palette', array(
        array(
            'name'  => __( 'Aqua', CHILD_THEME_SLUG ),
            'slug'  => 'aqua',
            'color' => '#21a8af',
        ),
        array(
            'name'  => __( 'Purple Dark', CHILD_THEME_SLUG ),
            'slug'  => 'purple-dark',
            'color' => '#632695',
        ),
        array(
            'name'  => __( 'Purple Light', CHILD_THEME_SLUG ),
            'slug'  => 'purple-light',
            'color' => '#9e15bf',
        ),
        array(
            'name'  => __( 'Pink', CHILD_THEME_SLUG ),
            'slug'  => 'pink',
            'color' => '#b5267b',
        ),
        array(
            'name'  => __( 'Black', CHILD_THEME_SLUG ),
            'slug'  => 'black',
            'color' => '#1d1d2c',
        ),
        array(
            'name'  => __( 'Grey Light', CHILD_THEME_SLUG ),
            'slug'  => 'grey-light',
            'color' => '#f7f7f7',
        ),
        array(
            'name'  => __( 'White', CHILD_THEME_SLUG ),
            'slug'  => 'white',
            'color' => '#ffffff',
        ),
    ) );

Solution

  • Here is how I ended up doing it:

    function color_exists($name, $colors) {
        foreach ($colors as $item) {
            if($item['name'] === $name) {
                return true;
            }
        }
        return false;
    }
    function update_color($name, $color, $colors) {
        foreach ($colors as &$item) {
            if($item['name'] === $name) {
                $item['color'] = $color;
            }
        }
        return $colors;
    }
    function render_color_classes() {
        $colors = create_colors_for_palette();
        if ($colors) {
            $css = ".components-panel__body.editor-panel-color-settings.block-editor-panel-color-settings.is-opened .block-editor-color-palette-control:first-of-type {display: none !important;}";
            foreach ($colors as $item) {
                $css = $css . ".has-" . strtolower(preg_replace('/(?<=\d)(?=[A-Za-z])|(?<=[A-Za-z])(?=\d)|(?<=[a-z])(?=[A-Z])/', "-", $item['name'])) . "-color { color: " . $item['color'] . " !important; }"; 
            }
            echo "<style>" . esc_html($css) . "</style>";
        }
    }
    function add_theme_color_options($file, $colors) {
        $lines = file_get_contents($file);
        $lines = explode(":root {", $lines);
        $lines = explode("}", $lines[1]);
        $lines = explode(";", $lines[0]);
        foreach ($lines as $data) {
            if (strpos($data, '--color') !== false) {
                $temp_color = explode("#", $data);
                $name = trim(str_replace(":", "", str_replace(" ", "", str_replace('--color', '', $temp_color[0]))));
                $slug = trim(str_replace(" ", "", str_replace('--color', '', $temp_color[0])));
                $color = "#" . trim(str_replace("", "", $temp_color[1]));
    
                if(color_exists($name, $colors)) {
                    $colors = update_color($name, $color, $colors);
                } else {
                    array_push($colors, array('name' => __( $name, $slug), 'slug' => $slug, 'color' => $color));
                }
            }
        }
        return $colors;
    }
    function add_brand_color_options($colors) {
        if (isset($_GET['post'])) {
            $post_id = sanitize_text_field($_GET['post']);
            $fields = get_fields($post_id);
            if (array_key_exists('vaccines_brand_color_light', $fields) && array_key_exists('vaccines_brand_color_dark', $fields)
            && $fields['vaccines_brand_color_light'] !== "" && $fields['vaccines_brand_color_dark'] !== "") {
                $name = "LightBrandColor";
                $slug = "light-brand-color";
                $color = $fields['vaccines_brand_color_light'];
                array_push($colors, array('name' => __( $name, $slug), 'slug' => $slug, 'color' => $color));
                $name = "DarkBrandColor";
                $slug = "dark-brand-color";
                $color = $fields['vaccines_brand_color_dark'];
                array_push($colors, array('name' => __( $name, $slug), 'slug' => $slug, 'color' => $color));
            }
        }
        return $colors;
    }
    function create_colors_for_palette() {
        $theme = wp_get_theme();
        if ($theme->Name != "vaccines") {
            return false;
        } else {
            if (isset($_SERVER['DOCUMENT_ROOT'])) {
                clearstatcache();
                $root_path = sanitize_text_field($_SERVER['DOCUMENT_ROOT']);
                $theme_folder_name = explode("/", get_stylesheet_directory_uri());
                $theme_folder_name = $theme_folder_name[6];
                $variablesFileMain = $root_path.'/wp-content/themes/vivid-main/css/style.css';
                $variablesFileTheme = $root_path.'/wp-content/themes/'.$theme_folder_name.'/css/style.css';
                if (!file_exists($variablesFileMain) && !file_exists($variablesFileTheme)) {
                    return false;
                } else {
                    $colors = array();
                    if (file_exists($variablesFileMain)) {
                        $colors = add_theme_color_options($variablesFileMain, $colors);
                    }
                    if (file_exists($variablesFileTheme)) {
                        $colors = add_theme_color_options($variablesFileTheme, $colors);
                    }
                    $colors = add_brand_color_options($colors);
                    return $colors;
                }
            }
        }
    }
    function handle_color_palette () {
        $colors = create_colors_for_palette();
        if ($colors === false) {
            add_theme_support( 'editor-color-palette');
        } else {
            add_theme_support( 'editor-color-palette', $colors);
            add_action('admin_head', 'render_color_classes');
            add_action('wp_head', 'render_color_classes');
        }
    }
    handle_color_palette();
    

    NOTE: This assumes you have a parent theme and are building off that with child themes. As a result, the main theme is queried first, and then the child theme will override any colors that are also declared in the main theme.