bootscore
bootscore copied to clipboard
Bootstrap color palette to Gutenberg block editor
I propose we add custom Bootstrap palette to be added to the block editor. Ref If you are using the block editor this is a feature that would help A LOT to keep consistency across your site.
Since we have pre-processing I'm guessing it could be done as in the reference, but since I'm not familiar with the process in here I'd like to hear your opnions before diving in. What are your opinions on this? How should I go about implementing it? Feel free to join in
I think it's a good idea to add some basic support for the block editor. We're happy if you want to contribute. The process here is simple. Just fork the theme repo, do your changes and create a Pull request.
I think that it wouldn't be that hard, plus it would do ground work for more theme customization. Since theme.json
is available it would make it a lot easier to implement and not depend on the PHP add_theme_support
way of doing it.
The only thing we would need to make is the for scss-compiler.php
file to generate the theme.json
in the root dir with all the colors as specified in here.
I'm not sure SCSS Compiler CAN compile to .json buit looking at the SCSS code and generated CSS file I'd say the first part of the _root.scss
has everything we need to do this, list all the colors:
@each $color, $value in $colors {
--#{$variable-prefix}#{$color}: #{$value};
}
Any idea how I would about doing this? I'm not familiar with SCSS compiler and I'm having a hard time figuring it out how to add just the colors to the .json
Building support in the scss is quite easy, using the example you posted. Unfortunately, the json/PHP is a bit harder. The compiler can't just read the variables and write json for it. This would basically require all the scss variables to be declared in PHP in some way, so both the compiler and a file writer for json can both use them.
In understrap they use gulp to generate the code, unfortunately in the current system of bootScore this won't fit, as we mainly focus on not needing additional tools. I'll take a closer look at the code on understrap soon, to see if I can get some inspiration.
The only way I can imagine this working the best if we give people instructions on how to edit the theme.json.
I've did a bit of research and got a working prototype:
- It uses an external tool https://github.com/sabberworm/PHP-CSS-Parser
composer require sabberworm/php-css-parser
to add the library - After the SCSS Compiler does all the work, it will load the bootstrap.min.css and parse the variables.
You need to add the
bootscore_compile_json()
function after this line infunctions.php
for it to work - It will get all the whitelisted variables and structure the data in a array
- Convert it to JSON and update theme.json
The function:
function bootscore_compile_json()
{
require __DIR__ . '/../vendor/autoload.php';
$parser = new \Sabberworm\CSS\Parser(file_get_contents(get_stylesheet_directory() . '/css/lib/bootstrap.min.css'));
$cssDocument = $parser->parse();
$vars_whitelist = array("--bs-primary","--bs-secondary","--bs-blue", "--bs-indigo", "--bs-purple", "--bs-pink", "--bs-red", "--bs-orange", "--bs-yellow", "--bs-green", "--bs-teal", "--bs-cyan", "--bs-white", "--bs-gray", "--bs-gray-dark");
$rulesets = $cssDocument->getAllRuleSets();
$custom_palette = array();
foreach ($rulesets as $val)
{
$tmp = $val->getRules();
foreach ($tmp as $rule)
{
$ruleV = (string) $rule->getValue();
$ruleR = $rule->getRule();
if (in_array($ruleR, $vars_whitelist))
{
$_name = str_replace("--bs-", "", $ruleR);
$_color = array(
"name" => ucfirst($_name),
"slug" => $_name,
"color" => $ruleV
);
$custom_palette[] = $_color;
}
}
}
$json_stru = array(
"version" => 1,
"settings" => array(
"color" => array(
"palette" => $custom_palette
)
)
);
$fp = fopen(get_stylesheet_directory() . '/theme.json', 'w');
fwrite($fp, json_encode($json_stru));
fclose($fp);
}
What do you think? Is the external lib a no-go? Maybe we could we make this optional?
Loading in another external library will make the theme more heavy, and recompiling slower, which is a thing to consider. Although I must say, I totally didn't consider that there would even be a library that can read css like that. Testing would be required how hard this can hit performance.
Also, I played around with the theme.json, and even though it's nice, I personally wouldn't use it. It also overrides things like font families in Gutenberg, and if you don't set them they will also be empty in Gutenberg. I would go for the approach of the editor-color-palette
and loading a colors.json in there.
Now that theme.json
evolved a bit I think it's a good time to revive this.
After refactoring, instead of just the palette, it now also loads font families and set body text and bg colors, plus opens up for any exposed BS variable to be included in theme.json
I also tested the performance and it takes around 0.7 seconds to execute the function on my end. With a check for last modified like the bootscore_compile_scss()
has it shouldn't be a problem, right?
Here's the new function:
function bootscore_compile_json()
{
require __DIR__ . '/../vendor/autoload.php';
$parser = new \Sabberworm\CSS\Parser(file_get_contents(get_stylesheet_directory() . '/css/lib/bootstrap.min.css'));
$cssDocument = $parser->parse();
$vars_fetch = array("--bs-primary", "--bs-secondary", "--bs-blue", "--bs-indigo", "--bs-purple", "--bs-pink", "--bs-red", "--bs-orange", "--bs-yellow", "--bs-green", "--bs-teal", "--bs-cyan", "--bs-white", "--bs-gray", "--bs-gray-dark", "--bs-body-font-family", "--bs-font-sans-serif", "--bs-font-monospace", "--bs-body-color", "--bs-body-bg");
$rulesets = $cssDocument->getAllRuleSets();
$custom_palette = array();
foreach ($rulesets as $val)
{
$tmp = $val->getRules();
foreach ($tmp as $rule)
{
$ruleV = (string) $rule->getValue();
$ruleR = $rule->getRule();
if (in_array($ruleR, $vars_fetch))
{
$custom_palette[$ruleR] = $ruleV;
}
}
}
$json_stru = array(
"version" => 2,
"styles" => array(
"color" => array(
"text" => $custom_palette["--bs-body-color"],
"background" => $custom_palette["--bs-body-bg"]
),
"typography" => array(
"fontFamily" => "var(--wp--preset--font-family--default-font-family)",
)
),
"settings" => array(
"typography" => array(
"fontFamilies" => array(
array(
"fontFamily" => $custom_palette["--bs-body-font-family"],
"slug" => "default-font-family",
"name" => "Default Bootstrap Font"
),
array(
"fontFamily" => $custom_palette["--bs-font-sans-serif"],
"slug" => "font-sans-serif",
"name" => "Sans Serif"
),
array(
"fontFamily" => $custom_palette["--bs-font-monospace"],
"slug" => "font-monospace",
"name" => "Monospace"
)
)
),
"color" => array(
"palette" => array(
array(
"name" => "Primary",
"slug" => "primary",
"color" => $custom_palette["--bs-primary"]
),
array(
"name" => "Secondary",
"slug" => "secondary",
"color" => $custom_palette["--bs-secondary"]
),
array(
"name" => "Blue",
"slug" => "blue",
"color" => $custom_palette["--bs-blue"]
),
array(
"name" => "Indigo",
"slug" => "indigo",
"color" => $custom_palette["--bs-indigo"]
),
array(
"name" => "Purple",
"slug" => "purple",
"color" => $custom_palette["--bs-purple"]
),
array(
"name" => "Pink",
"slug" => "pink",
"color" => $custom_palette["--bs-pink"]
),
array(
"name" => "Red",
"slug" => "red",
"color" => $custom_palette["--bs-red"]
),
array(
"name" => "Orange",
"slug" => "orange",
"color" => $custom_palette["--bs-orange"]
),
array(
"name" => "Yellow",
"slug" => "yellow",
"color" => $custom_palette["--bs-yellow"]
),
array(
"name" => "Green",
"slug" => "green",
"color" => $custom_palette["--bs-green"]
),
array(
"name" => "Teal",
"slug" => "teal",
"color" => $custom_palette["--bs-teal"]
),
array(
"name" => "Cyan",
"slug" => "cyan",
"color" => $custom_palette["--bs-cyan"]
),
array(
"name" => "White",
"slug" => "white",
"color" => $custom_palette["--bs-white"]
),
array(
"name" => "Gray",
"slug" => "gray",
"color" => $custom_palette["--bs-gray"]
),
array(
"name" => "Gray Dark",
"slug" => "gray-dark",
"color" => $custom_palette["--bs-gray-dark"]
)
)
)
)
);
$fp = fopen(get_stylesheet_directory() . '/theme.json', 'w');
fwrite($fp, json_encode($json_stru));
fclose($fp);
}
Can you fork the theme and create a working example to test?
Path to css has changed from /css/lib/bootstrap.min.css
to /css/main.css
.
Can you fork the theme and create a working example to test?
I forked it here and in this branch is the working prototype. I tested it with child theme and it seems to be working also.
(Sorry, I accidentally messed up the formatting from inc/scss-compiler.php
)
Tested and works flawlessly. Think that's pretty smart and would love to add this feature to the theme.
- @iwasthesword are you able to maintain this part in the long-therm?
- @justinkruit what do you think?
If so, I'm in.
- @iwasthesword are you able to maintain this part in the long-therm?
Yes, I can maintain this in the long term.
I'm in 👍.
If it's ok for you, I'd like to address this to v5.2.1.0 because v5.2.0.0 is closed to ship, has already many changes and I'm still struggling with some things.
I think it's best too. I will soon start working on adding the 'last modified' check so it doesn't fire every load and polish the code bit and prepare for the next release.
I've been testing with the theme.json today, but for some reason it still feels buggy. Spacing on blocks go missing, font families missing when you don't add them, etc. Next to that, adding this library will also render the theme.json on each page load when developing.
It's a nice system, but I honestly think it's for the best if users add the colors themselves, either with theme.json or via add_theme_support('editor-color-palette', array())
.
I've used the understrap build system (basically the package.json npm build script) and personally prefer it to bootscores SCSSphp compilation, but come back to bootscore as its woocommerce support and out-of-the-box menu system and other things are stronger.
The understrap system basically copies all the required SCSS files from the parent theme and compiles with NPM scripts. Understrap also has a browser watch compilation if you like that kind of thing, all are pretty straightforward.
What I like about it is you have more control over the SCSS, I comment some of Bootstrap SCSS imports that I don't use and comment out lots of fontawesome SCSS. Also dependencies like:
- fontawesome
- bootstrap5
are simply pulled down via NPM, at the moment the bootscores main theme is having to package these dependencies.
The NPM build command is straightforward and ubiquitous and wouldn't think it would scare people away from using the theme, themes like this are developer-centric. NPM build makes life easier and is powerful and configurable.
I disabled bootscores SCSSphp compilation and moved over to NPM script in the work I'm currently undertaking and run a NPM scripts that compiles the SCSS and copies it to the CSS directory. Like this
"scripts": {
"css": "npm-run-all css-compile css-postcss css-minify",
"css-compile": "sass --style expanded --source-map --embed-sources --no-error-css --quiet scss/main.scss:css/main.css",
"css-minify": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output css/ --batch --batch-suffix \".min\" \"css/*.css\" \"!css/*.min.css\" \"!css/*rtl*.css\"",
"css-postcss": "postcss --config src/build/postcss.config.js --replace \"css/*.css\" \"!css/*.rtl*.css\" \"!css/*.min.css\"",
"copy-assets": "node src/build/copy-assets.js"
},
I initially ran the copy-assets
NPM script which just runs a piece of JS to copy the required asset files from the parent theme.
Understrap has scripts to compile and minify JS
"js": "npm-run-all js-compile js-minify",
"js-compile": "rollup --config src/build/rollup.config.js --sourcemap",
"js-minify": "terser js/child-theme.min.js --config-file src/build/terser.config.json --source-map \"content=js/child-theme.js.map,url=child-theme.min.js.map,filename=child-theme.min.js\" --output js/child-theme.min.js",
And browser-sync scripts to compile when SCSS is updated etc
"watch": "npm-run-all --parallel watch-run-*",
"watch-bs": "npm-run-all --parallel bs watch-run-*",
"watch-run-css": "nodemon --watch src/sass/ --ext scss --exec \"npm-run-all css\"",
"watch-run-js": "nodemon --watch src/js/ --ext js --exec \"npm-run-all js\"",
Not sure there is much appetite to explore this after your work last year to integrate a PHP SCSS compiler. But I'd be interested in using NPM with bootscore and could chip in.
Thanks to https://github.com/bootscore/bootscore/pull/375 you can now disable scssphp with a single line in wp-config.php
or functions.php
and use a compiler of your choice instead. Release is this week after WooCommerce 7.4 update, but you can simply download main
branch as well.
@crftwrk sweet, thanks I'll use that when available.