Skip to content
Open
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ package-lock.json

### conf-img
assets/conf-img/*.json

### theme.json
src/scss/01-abstract/_theme-json.scss
theme.json
4 changes: 4 additions & 0 deletions config/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extract
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

const WebpackImageSizesPlugin = require('./webpack-image-sizes-plugin')
const WebpackThemeJsonPlugin = require('./webpack-theme-json-plugin')

module.exports = {
get: function (mode) {
const plugins = [
new WebpackThemeJsonPlugin({
watch: mode !== 'production',
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*', '!images', '!images/**'],
}),
Expand Down
191 changes: 191 additions & 0 deletions config/webpack-theme-json-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
const chalk = require('chalk')
const path = require('path')
const fs = require('fs')

const logId = '[' + chalk.blue('WebpackThemeJsonPlugin') + ']'

class WebpackThemeJsonPlugin {
/**
* constructor
* @param {Object} options = {
* context: string - default: '../src/theme-json'
* output: string - default: '../theme.json'
* scssOutput: string - default: '../src/scss/00-variables/_theme-json.scss'
* watch: boolean - default: false
* }
*/
constructor(options) {
// folders
this._context = options.context || path.resolve(__dirname, '../src/theme-json') + '/'
this._output = options.output || path.resolve(__dirname, '../theme.json')
this._scssOutput = options.scssOutput || path.resolve(__dirname, '../src/scss/01-abstract/_theme-json.scss')

if (options.watch) {
fs.watch(this._context, () => {
this.refresh()
})
}

this.refresh()
}

/**
* apply
*/
apply() {}

/**
* Generate theme json file
*/
generateThemeJson() {
const jsonFiles = fs.readdirSync(this._context, {
withFileTypes: true,
})
const themeJson = {}

jsonFiles.forEach((file) => {
if (file.isFile() && file.name.endsWith('.json')) {
let json = fs.readFileSync(this._context + file.name, 'utf8')

try {
json = JSON.parse(json)
} catch (e) {
// eslint-disable-next-line no-console
console.error(logId, 'Error parsing JSON file:', file.name)
}

if (isPlainObject(json)) {
extend(true, themeJson, json)
} else {
// eslint-disable-next-line no-console
console.error(logId, 'JSON file is not a plain object:', file.name)
}
}
})

fs.writeFileSync(this._output, JSON.stringify(themeJson, null, 2))
// eslint-disable-next-line no-console
console.log(logId, 'JSON files successfully generated !')

return this
}

/**
* Generate scss variables file
*/
generateScssVariables() {
const comment = [
'/**',
' * Theme JSON',
' * scss variables are extracted from theme.json',
' *',
" * !!! DON'T EDIT THIS FILE !!!",
' *',
' */',
]
const tasks = {
'settings-color-palette'(key, value) {
let result = ''
const palette = []

for (const color of value) {
const colorVar = getVariableName('settings-color-' + color.slug)
result += `${colorVar}: ${color.color};\n`
palette.push(`${color.slug}: ${colorVar}`)
}

return result + `$settings-palette: (\n\t${palette.join(',\n\t')}\n);\n`
},
'settings-custom': 'default',
'settings-spacing-spacingSizes'(key, value) {
let result = ''

for (const spacing of value) {
result += `${getVariableName('settings-spacing-' + spacing.slug)}: ${spacing.size};\n`
}

return result
},
}
// eslint-disable-next-line @wordpress/no-unused-vars-before-return
const taskNames = Object.keys(tasks)
let jsonFile = fs.readFileSync(this._output, 'utf8')

// check if the theme.json file is valid
try {
jsonFile = JSON.parse(jsonFile)
} catch (e) {
// eslint-disable-next-line no-console
console.error(logId, 'Error parsing JSON file:', this._output)
return this
}

// format the scss variable name
function getVariableName(id) {
return `$${id.replace(/([A-Z])/g, '-$1').toLowerCase()}`
}

// traverse the theme.json file and generate the scss variables
function traverse(obj, parents = [], result = '') {
for (const key in obj) {
const id = (parents.length > 0 ? parents.join('-') + '-' : '') + key
const taskName = taskNames.filter((t) => (id.startsWith(t) ? t : null))[0]
const task = taskName ? tasks[taskName] : null

if (isPlainObject(obj[key])) {
result += traverse(obj[key], [...parents, key])
} else if (task) {
if (task === 'default' && typeof obj[key] === 'string') {
result += `${getVariableName(id)}: ${obj[key]};\n`
} else if (typeof task === 'function') {
result += task(key, obj[key])
}
}
}

return result
}

fs.writeFileSync(this._scssOutput, comment.join('\n') + '\n' + traverse(jsonFile))

return this
}

/**
* Refresh the theme json and scss variables files
*/
refresh() {
this.generateThemeJson()
this.generateScssVariables()
return this
}
}

// ----
// utils
// ----
function isPlainObject(o) {
return o?.constructor === Object || Object.getPrototypeOf(o ?? 0) === null
}

function extend() {
const args = arguments
const firstArgIsBool = typeof args[0] === 'boolean'
const deep = firstArgIsBool ? args[0] : false
const start = firstArgIsBool ? 1 : 0
const rt = isPlainObject(args[start]) ? args[start] : {}

for (let i = start + 1; i < args.length; i++) {
for (const prop in args[i]) {
if (deep && isPlainObject(args[i][prop])) {
rt[prop] = extend(true, {}, rt[prop], args[i][prop])
} else if (typeof args[i][prop] !== 'undefined') {
rt[prop] = args[i][prop]
}
}
}

return rt
}

module.exports = WebpackThemeJsonPlugin
126 changes: 19 additions & 107 deletions inc/Services/Editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public function get_service_name(): string {
* @param Service_Container $container
*/
public function boot( Service_Container $container ): void {
$this->after_theme_setup();
/**
* Load editor style css for admin and frontend
*/
Expand All @@ -48,11 +47,6 @@ public function boot( Service_Container $container ): void {
*/
$this->register_custom_block_styles();

/**
* Customize theme.json settings
*/
add_filter( 'wp_theme_json_data_theme', [ $this, 'filter_theme_json_theme' ], 10, 1 );

/**
* Load editor JS for ADMIN
*/
Expand All @@ -63,86 +57,6 @@ public function boot( Service_Container $container ): void {
add_filter( 'allowed_block_types_all', [ $this, 'gutenberg_blocks_allowed' ], 10, 2 );
}

/**
* Register :
* - theme_supports
* - color palettes
* - font sizes
* - etc.
*
*/
private function after_theme_setup(): void {

//color palettes
add_theme_support(
'editor-color-palette',
[
[
'name' => __( 'Dark', 'beapi-frontend-framework' ),
'slug' => 'dark',
'color' => '#000000',
],
[
'name' => __( 'Light', 'beapi-frontend-framework' ),
'slug' => 'light',
'color' => '#ffffff',
],
[
'name' => __( 'Primary', 'beapi-frontend-framework' ),
'slug' => 'primary',
'color' => '#ffff00',
],
[
'name' => __( 'Secondary', 'beapi-frontend-framework' ),
'slug' => 'secondary',
'color' => '#00ffff',
],
]
);
// font sizes
add_theme_support(
'editor-font-sizes',
[
[
'name' => __( 'Title 6', 'beapi-frontend-framework' ),
'shortName' => 'h6',
'size' => 14,
'slug' => 'h6',
],
[
'name' => __( 'Title 5', 'beapi-frontend-framework' ),
'shortName' => 'h5',
'size' => 16,
'slug' => 'h5',
],
[
'name' => __( 'Title 4', 'beapi-frontend-framework' ),
'shortName' => 'h4',
'size' => 18,
'slug' => 'h4',
],
[
'name' => __( 'Title 3', 'beapi-frontend-framework' ),
'shortName' => 'h3',
'size' => 24,
'slug' => 'h3',
],
[
'name' => __( 'Title 2', 'beapi-frontend-framework' ),
'shortName' => 'h2',
'size' => 40,
'slug' => 'h2',
],
[
'name' => __( 'Title 1', 'beapi-frontend-framework' ),
'shortName' => 'h1',
'size' => 58,
'slug' => 'h1',
],
]
);
}

/**
* editor style
*/
Expand All @@ -159,27 +73,6 @@ private function style(): void {
add_editor_style( 'dist/' . $file );
}

/**
* Theme.json settings
* See https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/
*
* @param \WP_Theme_JSON_Data $theme_json Class to access and update the underlying data.
*
* @return \WP_Theme_JSON_Data
*/
public function filter_theme_json_theme( \WP_Theme_JSON_Data $theme_json ): \WP_Theme_JSON_Data {
$custom_theme_json = [
'version' => 2,
'settings' => [
'typography' => [
'dropCap' => false,
],
],
];

return $theme_json->update_with( $custom_theme_json );
}

/**
* Editor script
*/
Expand Down Expand Up @@ -267,6 +160,25 @@ private function register_custom_block_styles() {
'label' => __( 'Huge', 'beapi-frontend-framework' ),
]
);

for ( $i = 1; $i <= 6; $i++ ) {
$style = [
'name' => 'h' . $i,
'label' => sprintf( __( 'Style H%s', 'beapi-frontend-framework' ), $i ),
];

// heading
register_block_style(
'core/heading',
$style
);

// paragraph
register_block_style(
'core/paragraph',
$style
);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion page.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<header class="container">
<h1><?php the_title(); ?></h1>
</header>
<div class="blocks-container">
<div class="blocks-container is-layout-constrained has-global-padding">
<?php the_content(); ?>
</div>
<?php
Expand Down
2 changes: 1 addition & 1 deletion single.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<header class="container">
<h1><?php the_title(); ?></h1>
</header>
<div class="blocks-container">
<div class="blocks-container is-layout-constrained has-global-padding">
<?php the_content(); ?>
</div>
<?php
Expand Down
Loading
Loading