Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support WordPress 5.8 theme.json #20

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ module.exports = {
plugins: [
new PalettePlugin({
output: 'palette.json',
wp_theme_json: false,
output_prepend: '',
blacklist: ['transparent', 'inherit'],
priority: 'tailwind',
pretty: false,
Expand Down Expand Up @@ -133,12 +135,14 @@ mix.palette(options);
| Name | Type | Default | Description |
| :---------------: | :------------------------: | :--------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `output` | `{String}` | `'palette.json'` | The filename and path relative to the public path. |
| `wp_theme_json` | `{Boolean}` | `false` | Output the palette to WordPress 5.8's theme.json format. If enabled, the palette will replace the "settings.color.palette" property of the output file (which you should usually set output to `theme.json`). If the output file does not exist, it will be created with a skeleton theme.json format. If you're the plugin with mix and a `setPublicPath`, you probably want to set `output_prepend` to `../` so the file gets written to the theme root. |
| `output_prepend` | `{String}` | `''` | The value of this option is prepended to output. This is required when using `wp_theme_json` to make the output leave the public path when using mix. Set it to `../` to write the output to the top level of the theme. |
| `blacklist` | `{Array}` | `['transparent, 'inherit']` | Globs to ignore colors. |
| `priority` | `{String}` | `'tailwind'` | Priority when merging non-unique colors while using both Tailwind and Sass. |
| `pretty` | `{Boolean}` | `false` | Use pretty formatting when writing the JSON file. |
| `tailwind` | `{Object}` | `{ ... }` | Set Tailwind options. (See below) |
| `tailwind.config` | `{String}` | `'./tailwind.config.js'` | Path to the Tailwind configuration file relative to the project root path. |
| `tailwind.shades` | `{Object\|Array\|Boolean}` | `false` | While set to `true`, every color shade (`100-900`) will be generated. When set to `false`, only `500` will be used. Optionally, you may define either an array of shades as strings `['50', '100', '500']` or an object containing shade labels `{50: 'Lightest', 100: 'Lighter', 500: ''}`. |
| `tailwind.shades` | `{Object\|Array\|Boolean}` | `false` | While set to `true`, every color shade (`100-900`) will be generated. When set to `false`, only `500` will be used. Optionally, you may define either an array of shades as strings `['50', '100', '500']` or an object containing shade labels `{50: 'Lightest', 100: 'Lighter', 500: ''}`. Enabling this option will also enable support for custom palettes. |
| `tailwind.path` | `{String}` | `'colors'` | Path to Tailwind config values for palette colors in dot notation. Uses Tailwind's color palette `theme('colors')` per default. |
| `sass` | `{Object}` | `{ ... }` | Set Sass options. (See below) |
| `sass.path` | `{String}` | `'resources/assets/styles/config'` | Path to Sass variable files relative to the project root path. |
Expand All @@ -147,6 +151,11 @@ mix.palette(options);

### WordPress

#### WordPress 5.8+
WordPress 5.8 supports a [new theme.json configuration file](https://make.wordpress.org/core/2021/06/25/introducing-theme-json-in-wordpress-5-8/) which can automatically load the palette for you from a json file.

If you enable the `wp_theme_json` option, and set `output` to `theme.json`, this plugin will automatically build your palette and write it to that file, no `add_theme_support` required, and you get the added benefit of the right classes for block editor support built for you by WordPress.

#### Vanilla WordPress

The general idea is to [`file_get_contents()`](https://www.php.net/manual/en/function.file-get-contents.php) and [`json_decode()`](https://www.php.net/manual/en/function.json-decode.php) the palette and pass it to `add_theme_support('editor-color-palette', $palette)`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"d3-color": "^2.0.0",
"d3-hsv": "^0.1.0",
"lodash": "^4.17.20",
"sass-export": "^1.0.6"
"sass-export": "^2.1.0"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
Expand Down
67 changes: 59 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const _ = require('lodash');

const { color: d3Color } = require('d3-color');
const { hsv: d3Hsv } = require('d3-hsv');
const { exit } = require('process');

class PaletteWebpackPlugin {
/**
Expand All @@ -15,6 +16,8 @@ class PaletteWebpackPlugin {
this.options = _.merge(
{
output: 'palette.json',
output_prepend: '',
wp_theme_json: false,
blacklist: ['transparent', 'inherit'],
priority: 'tailwind',
pretty: false,
Expand All @@ -37,24 +40,58 @@ class PaletteWebpackPlugin {
: this.build(this.sass(), this.tailwind());
}

process_wp_theme_json(palette, theme_json_file) {

if (fs.existsSync(theme_json_file)) {
let rawdata = fs.readFileSync(theme_json_file)
var theme_json = JSON.parse(rawdata)
} else {
var theme_json = {
'version': 1,
'settings': {
'color': {
}
}
}
}

if ("undefined" == typeof theme_json.settings) theme_json.settings = {}
if ("undefined" == typeof theme_json.settings.color) theme_json.settings.color = {}

theme_json.settings.color.palette = palette
return theme_json
}

/**
* Add Palette to the webpack build process.
*
* @param {Object} compiler
*/
apply(compiler) {
const palette = JSON.stringify(
this.palette,
null,
this.options.pretty ? 2 : null
);
if (this.options.wp_theme_json) {
const theme_json_file = this.options.output == 'theme.json' ? './theme.json' : this.options.output
// Build the theme.json format. Force pretty printing if we're using wp_theme_json.
var palette = JSON.stringify(
this.process_wp_theme_json(this.palette, theme_json_file),
null,
2
);
} else {
var palette = JSON.stringify(
this.palette,
null,
this.options.pretty ? 2 : null
);
}

let output_path = this.options.output_prepend + this.options.output

if (compiler.hooks) {
compiler.hooks.emit.tapAsync(
this.constructor.name,
(compilation, callback) => {
Object.assign(compilation.assets, {
[this.options.output]: {
[output_path]: {
source() {
return palette;
},
Expand Down Expand Up @@ -227,11 +264,25 @@ class PaletteWebpackPlugin {
};
}

if (this.options.tailwind.shades) {
if ('default' == value.toLowerCase()) {
return {
name: this.title(key),
slug: key,
color: this.tailwind[key][value],
};
}

return {
name: this.title(key, value),
slug: `${key}-${value}`,
color: this.tailwind[key][value],
};
}

return {
name: isNaN(value)
? this.title(value)
: this.options.tailwind.shades
? this.title(key, value)
: this.title(key),
slug: `${key}-${value}`,
color: this.tailwind[key][value],
Expand Down
Loading