From be69e20245f43faee47a0b2fd28603f82848c00e Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 30 Jan 2025 15:04:50 +0000 Subject: [PATCH 01/17] Move everything into a src directory --- mu-plugins/10up-plugin/composer.json | 7 ++----- mu-plugins/10up-plugin/composer.lock | 8 ++++---- .../10up-plugin/{includes/classes => src}/Overrides.php | 0 .../{includes/classes => src}/PostTypes/Demo.php | 0 .../{includes/classes => src}/PostTypes/Page.php | 0 .../{includes/classes => src}/PostTypes/Post.php | 0 .../{includes/classes => src}/Taxonomies/Demo.php | 0 7 files changed, 6 insertions(+), 9 deletions(-) rename mu-plugins/10up-plugin/{includes/classes => src}/Overrides.php (100%) rename mu-plugins/10up-plugin/{includes/classes => src}/PostTypes/Demo.php (100%) rename mu-plugins/10up-plugin/{includes/classes => src}/PostTypes/Page.php (100%) rename mu-plugins/10up-plugin/{includes/classes => src}/PostTypes/Post.php (100%) rename mu-plugins/10up-plugin/{includes/classes => src}/Taxonomies/Demo.php (100%) diff --git a/mu-plugins/10up-plugin/composer.json b/mu-plugins/10up-plugin/composer.json index 3ee47ed..ec0d6e3 100644 --- a/mu-plugins/10up-plugin/composer.json +++ b/mu-plugins/10up-plugin/composer.json @@ -15,10 +15,7 @@ }, "autoload": { "psr-4": { - "TenUpPlugin\\": "includes/classes/" - }, - "files": [ - "includes/helpers/helpers.php" - ] + "TenUpPlugin\\": "src/" + } } } diff --git a/mu-plugins/10up-plugin/composer.lock b/mu-plugins/10up-plugin/composer.lock index 7b634c1..58ca41a 100644 --- a/mu-plugins/10up-plugin/composer.lock +++ b/mu-plugins/10up-plugin/composer.lock @@ -907,7 +907,7 @@ }, { "name": "illuminate/collections", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -963,7 +963,7 @@ }, { "name": "illuminate/conditionable", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1009,7 +1009,7 @@ }, { "name": "illuminate/contracts", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1057,7 +1057,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", diff --git a/mu-plugins/10up-plugin/includes/classes/Overrides.php b/mu-plugins/10up-plugin/src/Overrides.php similarity index 100% rename from mu-plugins/10up-plugin/includes/classes/Overrides.php rename to mu-plugins/10up-plugin/src/Overrides.php diff --git a/mu-plugins/10up-plugin/includes/classes/PostTypes/Demo.php b/mu-plugins/10up-plugin/src/PostTypes/Demo.php similarity index 100% rename from mu-plugins/10up-plugin/includes/classes/PostTypes/Demo.php rename to mu-plugins/10up-plugin/src/PostTypes/Demo.php diff --git a/mu-plugins/10up-plugin/includes/classes/PostTypes/Page.php b/mu-plugins/10up-plugin/src/PostTypes/Page.php similarity index 100% rename from mu-plugins/10up-plugin/includes/classes/PostTypes/Page.php rename to mu-plugins/10up-plugin/src/PostTypes/Page.php diff --git a/mu-plugins/10up-plugin/includes/classes/PostTypes/Post.php b/mu-plugins/10up-plugin/src/PostTypes/Post.php similarity index 100% rename from mu-plugins/10up-plugin/includes/classes/PostTypes/Post.php rename to mu-plugins/10up-plugin/src/PostTypes/Post.php diff --git a/mu-plugins/10up-plugin/includes/classes/Taxonomies/Demo.php b/mu-plugins/10up-plugin/src/Taxonomies/Demo.php similarity index 100% rename from mu-plugins/10up-plugin/includes/classes/Taxonomies/Demo.php rename to mu-plugins/10up-plugin/src/Taxonomies/Demo.php From 03bcfd84e8c02e8c14a46695f00821db36a78047 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 30 Jan 2025 15:05:44 +0000 Subject: [PATCH 02/17] Split the functional code into a couple of classes and update the init --- mu-plugins/10up-plugin/includes/core.php | 292 ------------------ .../10up-plugin/includes/helpers/helpers.php | 19 -- mu-plugins/10up-plugin/includes/utility.php | 42 --- mu-plugins/10up-plugin/plugin.php | 12 +- mu-plugins/10up-plugin/src/Assets.php | 273 ++++++++++++++++ mu-plugins/10up-plugin/src/PluginCore.php | 138 +++++++++ 6 files changed, 416 insertions(+), 360 deletions(-) delete mode 100755 mu-plugins/10up-plugin/includes/core.php delete mode 100644 mu-plugins/10up-plugin/includes/helpers/helpers.php delete mode 100755 mu-plugins/10up-plugin/includes/utility.php create mode 100644 mu-plugins/10up-plugin/src/Assets.php create mode 100644 mu-plugins/10up-plugin/src/PluginCore.php diff --git a/mu-plugins/10up-plugin/includes/core.php b/mu-plugins/10up-plugin/includes/core.php deleted file mode 100755 index 308c5c5..0000000 --- a/mu-plugins/10up-plugin/includes/core.php +++ /dev/null @@ -1,292 +0,0 @@ -

%2$s

', - esc_attr( $class ), - wp_kses_post( __( 'Please ensure the 10up/wp-framework composer package is installed.', 'tenup-plugin' ) ) - ); - } - ); - return; - } - - ModuleInitialization::instance()->init_classes( TENUP_PLUGIN_INC ); - do_action( 'tenup_plugin_init' ); -} - -/** - * Activate the plugin - * - * @return void - */ -function activate() { - // First load the init scripts in case any rewrite functionality is being loaded - init(); - flush_rewrite_rules(); -} - -/** - * Deactivate the plugin - * - * Uninstall routines should be in uninstall.php - * - * @return void - */ -function deactivate() { -} - - -/** - * The list of knows contexts for enqueuing scripts/styles. - * - * @return array - */ -function get_enqueue_contexts() { - return [ 'admin', 'frontend', 'shared' ]; -} - -/** - * Generate an URL to a script, taking into account whether SCRIPT_DEBUG is enabled. - * - * @param string $script Script file name (no .js extension) - * @param string $context Context for the script ('admin', 'frontend', or 'shared') - * - * @throws \RuntimeException If an invalid $context is specified. - * - * @return string URL - */ -function script_url( $script, $context ) { - - if ( ! in_array( $context, get_enqueue_contexts(), true ) ) { - throw new \RuntimeException( 'Invalid $context specified in TenUpPlugin script loader.' ); - } - - return TENUP_PLUGIN_URL . "dist/js/{$script}.js"; -} - -/** - * Generate an URL to a stylesheet, taking into account whether SCRIPT_DEBUG is enabled. - * - * @param string $stylesheet Stylesheet file name (no .css extension) - * @param string $context Context for the script ('admin', 'frontend', or 'shared') - * - * @throws \RuntimeException If an invalid $context is specified. - * - * @return string URL - */ -function style_url( $stylesheet, $context ) { - - if ( ! in_array( $context, get_enqueue_contexts(), true ) ) { - throw new \RuntimeException( 'Invalid $context specified in TenUpPlugin stylesheet loader.' ); - } - - return TENUP_PLUGIN_URL . "dist/css/{$stylesheet}.css"; -} - -/** - * Enqueue scripts for front-end. - * - * @return void - */ -function scripts() { - - wp_enqueue_script( - 'tenup_plugin_shared', - script_url( 'shared', 'shared' ), - Utility\get_asset_info( 'shared', 'dependencies' ), - Utility\get_asset_info( 'shared', 'version' ), - true - ); - - wp_enqueue_script( - 'tenup_plugin_frontend', - script_url( 'frontend', 'frontend' ), - Utility\get_asset_info( 'frontend', 'dependencies' ), - Utility\get_asset_info( 'frontend', 'version' ), - true - ); -} - -/** - * Enqueue scripts for admin. - * - * @return void - */ -function admin_scripts() { - - wp_enqueue_script( - 'tenup_plugin_shared', - script_url( 'shared', 'shared' ), - Utility\get_asset_info( 'shared', 'dependencies' ), - Utility\get_asset_info( 'shared', 'version' ), - true - ); - - wp_enqueue_script( - 'tenup_plugin_admin', - script_url( 'admin', 'admin' ), - Utility\get_asset_info( 'admin', 'dependencies' ), - Utility\get_asset_info( 'admin', 'version' ), - true - ); -} - -/** - * Enqueue styles for front-end. - * - * @return void - */ -function styles() { - - wp_enqueue_style( - 'tenup_plugin_shared', - style_url( 'shared', 'shared' ), - [], - Utility\get_asset_info( 'shared', 'version' ), - ); - - if ( is_admin() ) { - wp_enqueue_style( - 'tenup_plugin_admin', - style_url( 'admin', 'admin' ), - [], - Utility\get_asset_info( 'admin', 'version' ), - ); - } else { - wp_enqueue_style( - 'tenup_plugin_frontend', - style_url( 'frontend', 'frontend' ), - [], - Utility\get_asset_info( 'frontend', 'version' ), - ); - } -} - -/** - * Enqueue styles for admin. - * - * @return void - */ -function admin_styles() { - - wp_enqueue_style( - 'tenup_plugin_shared', - style_url( 'shared', 'shared' ), - [], - Utility\get_asset_info( 'shared', 'version' ), - ); - - wp_enqueue_style( - 'tenup_plugin_admin', - style_url( 'admin', 'admin' ), - [], - Utility\get_asset_info( 'admin', 'version' ), - ); -} - -/** - * Enqueue editor styles. Filters the comma-delimited list of stylesheets to load in TinyMCE. - * - * @param string $stylesheets Comma-delimited list of stylesheets. - * @return string - */ -function mce_css( $stylesheets ) { - if ( ! empty( $stylesheets ) ) { - $stylesheets .= ','; - } - - return $stylesheets . TENUP_PLUGIN_URL . ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? - 'assets/css/frontend/editor-style.css' : - 'dist/css/editor-style.min.css' ); -} - -/** - * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. - * - * @link https://core.trac.wordpress.org/ticket/12009 - * @param string $tag The script tag. - * @param string $handle The script handle. - * @return string|null - */ -function script_loader_tag( $tag, $handle ) { - $script_execution = wp_scripts()->get_data( $handle, 'script_execution' ); - - if ( ! $script_execution ) { - return $tag; - } - - if ( 'async' !== $script_execution && 'defer' !== $script_execution ) { - return $tag; - } - - // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()? - foreach ( wp_scripts()->registered as $script ) { - if ( in_array( $handle, $script->deps, true ) ) { - return $tag; - } - } - - // Add the attribute if it hasn't already been added. - if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) { - $tag = preg_replace( ':(?=>):', " $script_execution", $tag, 1 ); - } - - return $tag; -} diff --git a/mu-plugins/10up-plugin/includes/helpers/helpers.php b/mu-plugins/10up-plugin/includes/helpers/helpers.php deleted file mode 100644 index c392095..0000000 --- a/mu-plugins/10up-plugin/includes/helpers/helpers.php +++ /dev/null @@ -1,19 +0,0 @@ -} : $attribute is 'dependencies' ? array : string) - */ -function get_asset_info( $slug, $attribute = null ) { - if ( file_exists( TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php'; - } elseif ( file_exists( TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php'; - } else { - $asset = [ - 'version' => TENUP_PLUGIN_VERSION, - 'dependencies' => [], - ]; - } - - // @var }> $asset - - if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { - return $asset[ $attribute ]; - } - - return $asset; -} diff --git a/mu-plugins/10up-plugin/plugin.php b/mu-plugins/10up-plugin/plugin.php index aa53aae..395c18c 100755 --- a/mu-plugins/10up-plugin/plugin.php +++ b/mu-plugins/10up-plugin/plugin.php @@ -20,7 +20,7 @@ define( 'TENUP_PLUGIN_VERSION', '0.1.0' ); define( 'TENUP_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'TENUP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); -define( 'TENUP_PLUGIN_INC', TENUP_PLUGIN_PATH . 'includes/' ); +define( 'TENUP_PLUGIN_INC', TENUP_PLUGIN_PATH . 'src/' ); define( 'TENUP_PLUGIN_DIST_URL', TENUP_PLUGIN_URL . 'dist/' ); define( 'TENUP_PLUGIN_DIST_PATH', TENUP_PLUGIN_PATH . 'dist/' ); @@ -41,13 +41,11 @@ require_once TENUP_PLUGIN_PATH . 'vendor/autoload.php'; } -// Include files. -require_once TENUP_PLUGIN_INC . '/utility.php'; -require_once TENUP_PLUGIN_INC . '/core.php'; +$plugin_core = \TenUpPlugin\PluginCore::instance(); // Activation/Deactivation. -register_activation_hook( __FILE__, '\TenUpPlugin\Core\activate' ); -register_deactivation_hook( __FILE__, '\TenUpPlugin\Core\deactivate' ); +register_activation_hook( __FILE__, [ $plugin_core, 'activate' ] ); +register_deactivation_hook( __FILE__, [ $plugin_core, 'deactivate' ] ); // Bootstrap. -TenUpPlugin\Core\setup(); +$plugin_core->setup(); diff --git a/mu-plugins/10up-plugin/src/Assets.php b/mu-plugins/10up-plugin/src/Assets.php new file mode 100644 index 0000000..a112228 --- /dev/null +++ b/mu-plugins/10up-plugin/src/Assets.php @@ -0,0 +1,273 @@ + + */ + protected function get_enqueue_contexts() { + return [ 'admin', 'frontend', 'shared' ]; + } + + /** + * Get asset info from extracted asset files + * + * @param string $slug Asset slug as defined in build/webpack configuration + * @param string $attribute Optional attribute to get. Can be version or dependencies + * @return ($attribute is null ? array{version: string, dependencies: array} : $attribute is 'dependencies' ? array : string) + */ + public function get_asset_info( $slug, $attribute = null ) { + if ( file_exists( TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php'; + } else { + $asset = [ + 'version' => TENUP_PLUGIN_VERSION, + 'dependencies' => [], + ]; + } + + // @var }> $asset + + if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { + return $asset[ $attribute ]; + } + + return $asset; + } + + /** + * Generate an URL to a script, taking into account whether SCRIPT_DEBUG is enabled. + * + * @param string $script Script file name (no .js extension) + * @param string $context Context for the script ('admin', 'frontend', or 'shared') + * + * @throws \RuntimeException If an invalid $context is specified. + * + * @return string URL + */ + public function script_url( $script, $context ) { + + if ( ! in_array( $context, $this->get_enqueue_contexts(), true ) ) { + throw new \RuntimeException( 'Invalid $context specified in TenUpPlugin script loader.' ); + } + + return TENUP_PLUGIN_URL . "dist/js/{$script}.js"; + } + + /** + * Generate an URL to a stylesheet, taking into account whether SCRIPT_DEBUG is enabled. + * + * @param string $stylesheet Stylesheet file name (no .css extension) + * @param string $context Context for the script ('admin', 'frontend', or 'shared') + * + * @throws \RuntimeException If an invalid $context is specified. + * + * @return string URL + */ + public function style_url( $stylesheet, $context ) { + + if ( ! in_array( $context, $this->get_enqueue_contexts(), true ) ) { + throw new \RuntimeException( 'Invalid $context specified in TenUpPlugin stylesheet loader.' ); + } + + return TENUP_PLUGIN_URL . "dist/css/{$stylesheet}.css"; + } + + /** + * Enqueue scripts for front-end. + * + * @return void + */ + public function scripts() { + + wp_enqueue_script( + 'tenup_plugin_shared', + $this->script_url( 'shared', 'shared' ), + $this->get_asset_info( 'shared', 'dependencies' ), + $this->get_asset_info( 'shared', 'version' ), + true + ); + + wp_enqueue_script( + 'tenup_plugin_frontend', + $this->script_url( 'frontend', 'frontend' ), + $this->get_asset_info( 'frontend', 'dependencies' ), + $this->get_asset_info( 'frontend', 'version' ), + true + ); + } + + /** + * Enqueue scripts for admin. + * + * @return void + */ + public function admin_scripts() { + + wp_enqueue_script( + 'tenup_plugin_shared', + $this->script_url( 'shared', 'shared' ), + $this->get_asset_info( 'shared', 'dependencies' ), + $this->get_asset_info( 'shared', 'version' ), + true + ); + + wp_enqueue_script( + 'tenup_plugin_admin', + $this->script_url( 'admin', 'admin' ), + $this->get_asset_info( 'admin', 'dependencies' ), + $this->get_asset_info( 'admin', 'version' ), + true + ); + } + + /** + * Enqueue styles for front-end. + * + * @return void + */ + public function styles() { + + wp_enqueue_style( + 'tenup_plugin_shared', + $this->style_url( 'shared', 'shared' ), + [], + $this->get_asset_info( 'shared', 'version' ), + ); + + if ( is_admin() ) { + wp_enqueue_style( + 'tenup_plugin_admin', + $this->style_url( 'admin', 'admin' ), + [], + $this->get_asset_info( 'admin', 'version' ), + ); + } else { + wp_enqueue_style( + 'tenup_plugin_frontend', + $this->style_url( 'frontend', 'frontend' ), + [], + $this->get_asset_info( 'frontend', 'version' ), + ); + } + } + + /** + * Enqueue styles for admin. + * + * @return void + */ + public function admin_styles() { + + wp_enqueue_style( + 'tenup_plugin_shared', + $this->style_url( 'shared', 'shared' ), + [], + $this->get_asset_info( 'shared', 'version' ), + ); + + wp_enqueue_style( + 'tenup_plugin_admin', + $this->style_url( 'admin', 'admin' ), + [], + $this->get_asset_info( 'admin', 'version' ), + ); + } + + /** + * Enqueue editor styles. Filters the comma-delimited list of stylesheets to load in TinyMCE. + * + * @param string $stylesheets Comma-delimited list of stylesheets. + * @return string + */ + public function mce_css( $stylesheets ) { + if ( ! empty( $stylesheets ) ) { + $stylesheets .= ','; + } + + return $stylesheets . TENUP_PLUGIN_URL . ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? + 'assets/css/frontend/editor-style.css' : + 'dist/css/editor-style.min.css' ); + } + + /** + * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. + * + * @link https://core.trac.wordpress.org/ticket/12009 + * @param string $tag The script tag. + * @param string $handle The script handle. + * @return string|null + */ + public function script_loader_tag( $tag, $handle ) { + $script_execution = wp_scripts()->get_data( $handle, 'script_execution' ); + + if ( ! $script_execution ) { + return $tag; + } + + if ( 'async' !== $script_execution && 'defer' !== $script_execution ) { + return $tag; + } + + // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()? + foreach ( wp_scripts()->registered as $script ) { + if ( in_array( $handle, $script->deps, true ) ) { + return $tag; + } + } + + // Add the attribute if it hasn't already been added. + if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) { + $tag = preg_replace( ':(?=>):', " $script_execution", $tag, 1 ); + } + + return $tag; + } +} diff --git a/mu-plugins/10up-plugin/src/PluginCore.php b/mu-plugins/10up-plugin/src/PluginCore.php new file mode 100644 index 0000000..09b6fff --- /dev/null +++ b/mu-plugins/10up-plugin/src/PluginCore.php @@ -0,0 +1,138 @@ +

%2$s

', + esc_attr( $class ), + wp_kses_post( + __( + 'Please ensure the 10up/wp-framework composer package is installed.', + 'tenup-plugin' + ) + ) + ); + } + ); + + return; + } + + ModuleInitialization::instance()->init_classes( TENUP_PLUGIN_INC ); + do_action( 'tenup_plugin_init' ); + } + + /** + * Activate the plugin + * + * @return void + */ + public function activate() { + // First load the init scripts in case any rewrite functionality is being loaded + $this->init(); + flush_rewrite_rules(); + } + + /** + * Deactivate the plugin + * + * Uninstall routines should be in uninstall.php + * + * @return void + */ + public function deactivate() { + // Do nothing. + } + + /** + * Get an initialized class by its full class name, including namespace. + * + * @param string $class_name The class name including the namespace. + * + * @return false|\TenupFramework\ModuleInterface + */ + public static function get_module( $class_name ) { + return \TenupFramework\ModuleInitialization::get_module( $class_name ); + } + +} From bdef91ec42de55d56b583d98d14da38183979fc3 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 30 Jan 2025 17:30:21 +0000 Subject: [PATCH 03/17] Split overrides out into smaller classes --- .../src/{Overrides.php => Core/Emoji.php} | 19 +++---- .../10up-plugin/src/Core/HeadOverrides.php | 51 +++++++++++++++++++ 2 files changed, 58 insertions(+), 12 deletions(-) rename mu-plugins/10up-plugin/src/{Overrides.php => Core/Emoji.php} (82%) create mode 100644 mu-plugins/10up-plugin/src/Core/HeadOverrides.php diff --git a/mu-plugins/10up-plugin/src/Overrides.php b/mu-plugins/10up-plugin/src/Core/Emoji.php similarity index 82% rename from mu-plugins/10up-plugin/src/Overrides.php rename to mu-plugins/10up-plugin/src/Core/Emoji.php index 19c7b58..de49458 100644 --- a/mu-plugins/10up-plugin/src/Overrides.php +++ b/mu-plugins/10up-plugin/src/Core/Emoji.php @@ -1,19 +1,21 @@ Date: Thu, 6 Feb 2025 14:25:17 +0000 Subject: [PATCH 04/17] Remove singleton --- mu-plugins/10up-plugin/plugin.php | 12 ++++++---- mu-plugins/10up-plugin/src/PluginCore.php | 29 ----------------------- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/mu-plugins/10up-plugin/plugin.php b/mu-plugins/10up-plugin/plugin.php index 395c18c..91dd69f 100755 --- a/mu-plugins/10up-plugin/plugin.php +++ b/mu-plugins/10up-plugin/plugin.php @@ -36,12 +36,16 @@ } } -// Require Composer autoloader if it exists. -if ( file_exists( TENUP_PLUGIN_PATH . 'vendor/autoload.php' ) ) { - require_once TENUP_PLUGIN_PATH . 'vendor/autoload.php'; +// Bail if Composer autoloader is not found. +if ( ! file_exists( TENUP_PLUGIN_PATH . 'vendor/autoload.php' ) ) { + throw new \Exception( + 'Vendor autoload file not found. Please run `composer install`.' + ); } -$plugin_core = \TenUpPlugin\PluginCore::instance(); +require_once TENUP_PLUGIN_PATH . 'vendor/autoload.php'; + +$plugin_core = new \TenUpPlugin\PluginCore(); // Activation/Deactivation. register_activation_hook( __FILE__, [ $plugin_core, 'activate' ] ); diff --git a/mu-plugins/10up-plugin/src/PluginCore.php b/mu-plugins/10up-plugin/src/PluginCore.php index 09b6fff..a06b611 100644 --- a/mu-plugins/10up-plugin/src/PluginCore.php +++ b/mu-plugins/10up-plugin/src/PluginCore.php @@ -16,35 +16,6 @@ */ class PluginCore { - /** - * Instance of this class. - * - * @var PluginCore|null - */ - private static $instance = null; - - /** - * Get the instance of this class. - * - * @return PluginCore - */ - public static function instance() { - if ( null === self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } - - /** - * Constructor - * - * @return void - */ - private function __construct() { - // Do nothing. - } - /** * Default setup routine * From 757fd2b592acd156ff592ddc38183ec7a7e2148c Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 6 Feb 2025 14:26:13 +0000 Subject: [PATCH 05/17] lint fix --- mu-plugins/10up-plugin/src/PluginCore.php | 1 - 1 file changed, 1 deletion(-) diff --git a/mu-plugins/10up-plugin/src/PluginCore.php b/mu-plugins/10up-plugin/src/PluginCore.php index a06b611..f30e9f6 100644 --- a/mu-plugins/10up-plugin/src/PluginCore.php +++ b/mu-plugins/10up-plugin/src/PluginCore.php @@ -105,5 +105,4 @@ public function deactivate() { public static function get_module( $class_name ) { return \TenupFramework\ModuleInitialization::get_module( $class_name ); } - } From eceaa18178fed934b8d33fb2799cc8edc7a84428 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 6 Feb 2025 14:30:49 +0000 Subject: [PATCH 06/17] Linting --- themes/10up-block-theme/includes/blocks.php | 4 ++-- themes/10up-block-theme/includes/core.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/themes/10up-block-theme/includes/blocks.php b/themes/10up-block-theme/includes/blocks.php index 0e84507..4c3cd0c 100644 --- a/themes/10up-block-theme/includes/blocks.php +++ b/themes/10up-block-theme/includes/blocks.php @@ -35,8 +35,8 @@ function register_theme_blocks() { } foreach ( $block_json_files as $filename ) { - $block_folder = dirname( $filename ); - $block = register_block_type_from_metadata( $block_folder ); + $block_folder = dirname( $filename ); + $block = register_block_type_from_metadata( $block_folder ); if ( ! $block ) { continue; diff --git a/themes/10up-block-theme/includes/core.php b/themes/10up-block-theme/includes/core.php index a8340e8..4bc4722 100755 --- a/themes/10up-block-theme/includes/core.php +++ b/themes/10up-block-theme/includes/core.php @@ -120,7 +120,7 @@ function register_all_icons() { return; } - $icons = array_map( + $icons = array_map( function ( $icon_path ) { $icon_name = preg_replace( '#\..*$#', '', basename( $icon_path ) ); From c6edff607826d36d1a0b320250c6199f218dbe98 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 6 Feb 2025 14:30:56 +0000 Subject: [PATCH 07/17] Fix PHPCS --- composer.json | 4 ++-- phpcs.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 0b98e15..1707e76 100755 --- a/composer.json +++ b/composer.json @@ -34,8 +34,8 @@ "phpstan/phpstan-deprecation-rules": "^1.2" }, "scripts": { - "lint": "phpcs .", - "lint-fix": "phpcbf .", + "lint": "./vendor/bin/phpcs --standard=./phpcs.xml", + "lint-fix": "./vendor/bin/phpcbf --standard=./phpcs.xml", "static": [ "Composer\\Config::disableProcessTimeout", "phpstan --memory-limit=1G" diff --git a/phpcs.xml b/phpcs.xml index d0a9bac..579bba3 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -3,8 +3,8 @@ 10up PHPCS extended. - ./themes/* - ./mu-plugins/* + themes + mu-plugins node_modules/ From c0673ed9181ab01ff3a183dc94695e24a1e6851d Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 6 Feb 2025 16:18:17 +0000 Subject: [PATCH 08/17] OOP the theme --- .../js/block-editor}/block-collection.js | 0 .../js/block-editor}/block-editor-script.js | 0 .../js/block-editor}/block-filters/index.js | 0 .../js/block-editor}/block-styles/index.js | 0 .../block-editor}/block-variations/index.js | 0 .../blocks/example-block/block.json | 0 .../blocks/example-block/edit.js | 0 .../blocks/example-block/index.js | 0 .../blocks/example-block/markup.php | 0 .../blocks/example-block/save.js | 0 themes/10up-theme/composer.json | 2 +- themes/10up-theme/composer.lock | 28 +- themes/10up-theme/functions.php | 23 +- themes/10up-theme/includes/blocks.php | 160 ---------- themes/10up-theme/includes/classes/.gitkeep | 1 - themes/10up-theme/includes/core.php | 296 ------------------ themes/10up-theme/includes/helpers.php | 19 -- themes/10up-theme/includes/template-tags.php | 17 - themes/10up-theme/includes/utility.php | 40 --- themes/10up-theme/package.json | 5 +- themes/10up-theme/src/Assets.php | 238 ++++++++++++++ themes/10up-theme/src/Blocks.php | 183 +++++++++++ themes/10up-theme/src/ThemeCore.php | 121 +++++++ themes/10up-theme/src/Traits/GetAssetInfo.php | 43 +++ 24 files changed, 613 insertions(+), 563 deletions(-) rename themes/10up-theme/{includes => assets/js/block-editor}/block-collection.js (100%) rename themes/10up-theme/{includes => assets/js/block-editor}/block-editor-script.js (100%) rename themes/10up-theme/{includes => assets/js/block-editor}/block-filters/index.js (100%) rename themes/10up-theme/{includes => assets/js/block-editor}/block-styles/index.js (100%) rename themes/10up-theme/{includes => assets/js/block-editor}/block-variations/index.js (100%) rename themes/10up-theme/{includes => }/blocks/example-block/block.json (100%) rename themes/10up-theme/{includes => }/blocks/example-block/edit.js (100%) rename themes/10up-theme/{includes => }/blocks/example-block/index.js (100%) rename themes/10up-theme/{includes => }/blocks/example-block/markup.php (100%) rename themes/10up-theme/{includes => }/blocks/example-block/save.js (100%) delete mode 100644 themes/10up-theme/includes/blocks.php delete mode 100755 themes/10up-theme/includes/classes/.gitkeep delete mode 100755 themes/10up-theme/includes/core.php delete mode 100644 themes/10up-theme/includes/helpers.php delete mode 100644 themes/10up-theme/includes/template-tags.php delete mode 100755 themes/10up-theme/includes/utility.php create mode 100644 themes/10up-theme/src/Assets.php create mode 100644 themes/10up-theme/src/Blocks.php create mode 100644 themes/10up-theme/src/ThemeCore.php create mode 100644 themes/10up-theme/src/Traits/GetAssetInfo.php diff --git a/themes/10up-theme/includes/block-collection.js b/themes/10up-theme/assets/js/block-editor/block-collection.js similarity index 100% rename from themes/10up-theme/includes/block-collection.js rename to themes/10up-theme/assets/js/block-editor/block-collection.js diff --git a/themes/10up-theme/includes/block-editor-script.js b/themes/10up-theme/assets/js/block-editor/block-editor-script.js similarity index 100% rename from themes/10up-theme/includes/block-editor-script.js rename to themes/10up-theme/assets/js/block-editor/block-editor-script.js diff --git a/themes/10up-theme/includes/block-filters/index.js b/themes/10up-theme/assets/js/block-editor/block-filters/index.js similarity index 100% rename from themes/10up-theme/includes/block-filters/index.js rename to themes/10up-theme/assets/js/block-editor/block-filters/index.js diff --git a/themes/10up-theme/includes/block-styles/index.js b/themes/10up-theme/assets/js/block-editor/block-styles/index.js similarity index 100% rename from themes/10up-theme/includes/block-styles/index.js rename to themes/10up-theme/assets/js/block-editor/block-styles/index.js diff --git a/themes/10up-theme/includes/block-variations/index.js b/themes/10up-theme/assets/js/block-editor/block-variations/index.js similarity index 100% rename from themes/10up-theme/includes/block-variations/index.js rename to themes/10up-theme/assets/js/block-editor/block-variations/index.js diff --git a/themes/10up-theme/includes/blocks/example-block/block.json b/themes/10up-theme/blocks/example-block/block.json similarity index 100% rename from themes/10up-theme/includes/blocks/example-block/block.json rename to themes/10up-theme/blocks/example-block/block.json diff --git a/themes/10up-theme/includes/blocks/example-block/edit.js b/themes/10up-theme/blocks/example-block/edit.js similarity index 100% rename from themes/10up-theme/includes/blocks/example-block/edit.js rename to themes/10up-theme/blocks/example-block/edit.js diff --git a/themes/10up-theme/includes/blocks/example-block/index.js b/themes/10up-theme/blocks/example-block/index.js similarity index 100% rename from themes/10up-theme/includes/blocks/example-block/index.js rename to themes/10up-theme/blocks/example-block/index.js diff --git a/themes/10up-theme/includes/blocks/example-block/markup.php b/themes/10up-theme/blocks/example-block/markup.php similarity index 100% rename from themes/10up-theme/includes/blocks/example-block/markup.php rename to themes/10up-theme/blocks/example-block/markup.php diff --git a/themes/10up-theme/includes/blocks/example-block/save.js b/themes/10up-theme/blocks/example-block/save.js similarity index 100% rename from themes/10up-theme/includes/blocks/example-block/save.js rename to themes/10up-theme/blocks/example-block/save.js diff --git a/themes/10up-theme/composer.json b/themes/10up-theme/composer.json index dc97758..5238bf5 100644 --- a/themes/10up-theme/composer.json +++ b/themes/10up-theme/composer.json @@ -15,7 +15,7 @@ }, "autoload": { "psr-4": { - "TenUpTheme\\": "includes/classes/" + "TenUpTheme\\": "src/" } } } diff --git a/themes/10up-theme/composer.lock b/themes/10up-theme/composer.lock index d1d3c06..20ca342 100644 --- a/themes/10up-theme/composer.lock +++ b/themes/10up-theme/composer.lock @@ -907,7 +907,7 @@ }, { "name": "illuminate/collections", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", @@ -963,7 +963,7 @@ }, { "name": "illuminate/conditionable", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1009,7 +1009,7 @@ }, { "name": "illuminate/contracts", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1057,7 +1057,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.41.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1619,27 +1619,27 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.18.3", + "version": "1.19.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "ba67eee37d86ed775dab7dad58a7cbaf9a6cfe78" + "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ba67eee37d86ed775dab7dad58a7cbaf9a6cfe78", - "reference": "ba67eee37d86ed775dab7dad58a7cbaf9a6cfe78", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", + "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", "shasum": "" }, "require": { - "illuminate/contracts": "^9.28|^10.0|^11.0", + "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0", "php": "^8.0" }, "require-dev": { "mockery/mockery": "^1.5", - "orchestra/testbench": "^7.7|^8.0|^9.0", - "pestphp/pest": "^1.22|^2", - "phpunit/phpunit": "^9.5.24|^10.5", + "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.23|^2.1|^3.1", + "phpunit/phpunit": "^9.5.24|^10.5|^11.5", "spatie/pest-plugin-test-time": "^1.1|^2.2" }, "type": "library", @@ -1667,7 +1667,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.18.3" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.19.0" }, "funding": [ { @@ -1675,7 +1675,7 @@ "type": "github" } ], - "time": "2025-01-22T08:51:18+00:00" + "time": "2025-02-06T14:58:20+00:00" }, { "name": "spatie/php-structure-discoverer", diff --git a/themes/10up-theme/functions.php b/themes/10up-theme/functions.php index 09f73be..d1d99cc 100755 --- a/themes/10up-theme/functions.php +++ b/themes/10up-theme/functions.php @@ -11,8 +11,8 @@ define( 'TENUP_THEME_PATH', get_template_directory() . '/' ); define( 'TENUP_THEME_DIST_PATH', TENUP_THEME_PATH . 'dist/' ); define( 'TENUP_THEME_DIST_URL', TENUP_THEME_TEMPLATE_URL . '/dist/' ); -define( 'TENUP_THEME_INC', TENUP_THEME_PATH . 'includes/' ); -define( 'TENUP_THEME_BLOCK_DIR', TENUP_THEME_INC . 'blocks/' ); +define( 'TENUP_THEME_INC', TENUP_THEME_PATH . 'src/' ); +define( 'TENUP_THEME_BLOCK_DIR', TENUP_THEME_PATH . 'blocks/' ); define( 'TENUP_THEME_BLOCK_DIST_DIR', TENUP_THEME_PATH . 'dist/blocks/' ); $is_local_env = in_array( wp_get_environment_type(), [ 'local', 'development' ], true ); @@ -27,17 +27,12 @@ } } -require_once TENUP_THEME_INC . 'core.php'; -require_once TENUP_THEME_INC . 'template-tags.php'; -require_once TENUP_THEME_INC . 'utility.php'; -require_once TENUP_THEME_INC . 'blocks.php'; -require_once TENUP_THEME_INC . 'helpers.php'; - -// Run the setup functions. -TenUpTheme\Core\setup(); -TenUpTheme\Blocks\setup(); - // Require Composer autoloader if it exists. -if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require_once __DIR__ . '/vendor/autoload.php'; +if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + throw new Exception( 'Please run `composer install` in your theme directory.' ); } + +require_once __DIR__ . '/vendor/autoload.php'; + +$theme_core = new \TenUpTheme\ThemeCore(); +$theme_core->setup(); diff --git a/themes/10up-theme/includes/blocks.php b/themes/10up-theme/includes/blocks.php deleted file mode 100644 index a0652a0..0000000 --- a/themes/10up-theme/includes/blocks.php +++ /dev/null @@ -1,160 +0,0 @@ -context; - - // get the actual markup from the markup.php file - ob_start(); - include $block_folder . '/markup.php'; - return ob_get_clean(); - }; - } - - register_block_type_from_metadata( $block_folder, $block_options ); - } - } -} - -/** - * Enqueue editor-only JavaScript/CSS for blocks. - * - * @return void - */ -function blocks_editor_styles() { - wp_enqueue_style( - 'editor-style-overrides', - TENUP_THEME_TEMPLATE_URL . '/dist/css/editor-style-overrides.css', - [], - Utility\get_asset_info( 'editor-style-overrides', 'version' ) - ); - - if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { - wp_enqueue_script( - 'editor-style-overrides', - TENUP_THEME_TEMPLATE_URL . '/dist/js/editor-style-overrides.js', - Utility\get_asset_info( 'editor-style-overrides', 'dependencies' ), - Utility\get_asset_info( 'editor-style-overrides', 'version' ), - true - ); - } -} - - -/** - * Enqueue block specific styles. - * - * This function is used to enqueue styles that are specific to a block. It - * first gets all the CSS files in the 'blocks/autoenqueue' directory. Then - * for each stylesheet, it determines the block type by removing the directory - * path and '.css' from the stylesheet path. It then tries to get the asset - * file for the block type. If the asset file doesn't exist, it creates a new - * one with the version set to the file modification time of the stylesheet - * and no dependencies. Finally, it enqueues the block style using the block - * type, the URL to the stylesheet, the path to the stylesheet, the version - * from the asset file, and the dependencies from the asset file. - * - * @return void - */ -function enqueue_block_specific_styles() { - $stylesheets = glob( TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/**/*.css' ); - - if ( empty( $stylesheets ) ) { - return; - } - - foreach ( $stylesheets as $stylesheet_path ) { - $block_type = str_replace( TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/', '', $stylesheet_path ); - $block_type = str_replace( '.css', '', $block_type ); - $asset_file = TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/' . $block_type . '.asset.php'; - - if ( ! file_exists( $asset_file ) ) { - $asset_file = require $asset_file; - } else { - $asset_file = [ - 'version' => filemtime( $stylesheet_path ), - 'dependencies' => [], - ]; - } - - [$block_namespace, $block_name] = explode( '/', $block_type ); - - wp_register_style( - "tenup-theme-{$block_namespace}-{$block_name}", - TENUP_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.css', - $asset_file['version'], - $asset_file['dependencies'], - ); - - wp_enqueue_block_style( - $block_type, - [ - 'handle' => "tenup-theme-{$block_namespace}-{$block_name}", - 'path' => $stylesheet_path, - ] - ); - } -} - -/** - * Register block pattern categories - * - * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-patterns/ - * - * @return void - */ -function register_block_pattern_categories() { - - // Register a block pattern category - register_block_pattern_category( - '10up-theme', - [ 'label' => __( '10up Theme', 'tenup-theme' ) ] - ); -} diff --git a/themes/10up-theme/includes/classes/.gitkeep b/themes/10up-theme/includes/classes/.gitkeep deleted file mode 100755 index c1df439..0000000 --- a/themes/10up-theme/includes/classes/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# Basically just want to ignore the directory contents diff --git a/themes/10up-theme/includes/core.php b/themes/10up-theme/includes/core.php deleted file mode 100755 index 6a2fac2..0000000 --- a/themes/10up-theme/includes/core.php +++ /dev/null @@ -1,296 +0,0 @@ -

%2$s

', - esc_attr( $class ), - wp_kses_post( __( 'Please ensure the 10up/wp-framework package is installed.', 'tenup-theme' ) ) - ); - } - ); - return; - } - - ModuleInitialization::instance()->init_classes( TENUP_THEME_INC ); - do_action( 'tenup_theme_init' ); -} - -/** - * Makes Theme available for translation. - * - * Translations can be added to the /languages directory. - * If you're building a theme based on "tenup-theme", change the - * filename of '/languages/TenUpTheme.pot' to the name of your project. - * - * @return void - */ -function i18n() { - load_theme_textdomain( 'tenup-theme', TENUP_THEME_PATH . '/languages' ); -} - -/** - * Sets up theme defaults and registers support for various WordPress features. - * - * @return void - */ -function theme_setup() { - add_theme_support( 'automatic-feed-links' ); - add_theme_support( 'title-tag' ); - add_theme_support( 'post-thumbnails' ); - add_theme_support( - 'html5', - array( - 'search-form', - 'gallery', - 'navigation-widgets', - ) - ); - - add_theme_support( 'editor-styles' ); - add_editor_style( 'dist/css/frontend.css' ); - - remove_theme_support( 'core-block-patterns' ); - - // by adding the `theme.json` file block templates automatically get enabled. - // because the template editor will need additional QA and work to get right - // the default is to disable this feature. - remove_theme_support( 'block-templates' ); - - // This theme uses wp_nav_menu() in three locations. - register_nav_menus( - array( - 'primary' => esc_html__( 'Primary Menu', 'tenup-theme' ), - ) - ); -} - -/** - * Enqueue scripts for front-end. - * - * @return void - */ -function scripts() { - - /** - * Enqueuing frontend.js is required to get css hot reloading working in the frontend - * If you're not shipping any front-end js wrap this enqueue in a SCRIPT_DEBUG check. - */ - wp_enqueue_script( - 'frontend', - TENUP_THEME_TEMPLATE_URL . '/dist/js/frontend.js', - Utility\get_asset_info( 'frontend', 'dependencies' ), - Utility\get_asset_info( 'frontend', 'version' ), - true - ); - - /** - * Enqueuing shared.js is required to get css hot reloading working in the frontend - * If you're not shipping any shared js wrap this enqueue in a SCRIPT_DEBUG check. - */ - - /* - * Uncoment this to use the shared.js file. - wp_enqueue_script( - 'shared', - TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', - Utility\get_asset_info( 'shared', 'dependencies' ), - Utility\get_asset_info( 'shared', 'version' ), - true - ); - */ -} - -/** - * Enqueue scripts for admin - * - * @return void - */ -function admin_scripts() { - wp_enqueue_script( - 'admin', - TENUP_THEME_TEMPLATE_URL . '/dist/js/admin.js', - Utility\get_asset_info( 'admin', 'dependencies' ), - Utility\get_asset_info( 'admin', 'version' ), - true - ); - - /* - * Uncoment this to use the shared.js file. - wp_enqueue_script( - 'shared', - TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', - Utility\get_asset_info( 'shared', 'dependencies' ), - Utility\get_asset_info( 'shared', 'version' ), - true - ); - */ -} - -/** - * Enqueue core block filters, styles and variations. - * - * @return void - */ -function enqueue_block_editor_scripts() { - wp_enqueue_script( - 'block-editor-script', - TENUP_THEME_DIST_URL . 'js/block-editor-script.js', - Utility\get_asset_info( 'block-editor-script', 'dependencies' ), - Utility\get_asset_info( 'block-editor-script', 'version' ), - true - ); -} - -/** - * Enqueue styles for admin - * - * @return void - */ -function admin_styles() { - - wp_enqueue_style( - 'admin-style', - TENUP_THEME_TEMPLATE_URL . '/dist/css/admin.css', - [], - Utility\get_asset_info( 'admin-style', 'version' ) - ); - - /* - * Uncoment this to use the shared.css file. - wp_enqueue_style( - 'shared-style', - TENUP_THEME_TEMPLATE_URL . '/dist/css/shared.css', - [], - Utility\get_asset_info( 'shared', 'version' ) - ); - */ -} - -/** - * Enqueue styles for front-end. - * - * @return void - */ -function styles() { - wp_enqueue_style( - 'styles', - TENUP_THEME_TEMPLATE_URL . '/dist/css/frontend.css', - [], - Utility\get_asset_info( 'frontend', 'version' ) - ); -} - -/** - * Handles JavaScript detection. - * - * Adds a `js` class to the root `` element when JavaScript is detected. - * - * @return void - */ -function js_detection() { - - echo "\n"; -} - -/** - * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. - * - * @link https://core.trac.wordpress.org/ticket/12009 - * @param string $tag The script tag. - * @param string $handle The script handle. - * @return string|null - */ -function script_loader_tag( $tag, $handle ) { - $script_execution = wp_scripts()->get_data( $handle, 'script_execution' ); - - if ( ! $script_execution ) { - return $tag; - } - - if ( 'async' !== $script_execution && 'defer' !== $script_execution ) { - return $tag; - } - - // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()? - foreach ( wp_scripts()->registered as $script ) { - if ( in_array( $handle, $script->deps, true ) ) { - return $tag; - } - } - - // Add the attribute if it hasn't already been added. - if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) { - $tag = preg_replace( ':(?=>):', " $script_execution", $tag, 1 ); - } - - return $tag; -} - -/** - * Inlines ct.css in the head - * - * Embeds a diagnostic CSS file written by Harry Roberts - * that helps diagnose render blocking resources and other - * performance bottle necks. - * - * The CSS is inlined in the head of the document, only when requesting - * a page with the query param ?debug_perf=1 - * - * @link https://csswizardry.com/ct/ - * @return void - */ -function embed_ct_css() { - - $debug_performance = rest_sanitize_boolean( boolval( filter_input( INPUT_GET, 'debug_perf', FILTER_SANITIZE_NUMBER_INT ) ) ); - - if ( ! $debug_performance ) { - return; - } - - wp_register_style( 'ct', false ); // phpcs:ignore - wp_enqueue_style( 'ct' ); - wp_add_inline_style( 'ct', 'head{--ct-is-problematic:solid;--ct-is-affected:dashed;--ct-notify:#0bce6b;--ct-warn:#ffa400;--ct-error:#ff4e42}head,head [rel=stylesheet],head script,head script:not([src])[async],head script:not([src])[defer],head script~meta[http-equiv=content-security-policy],head style,head>meta[charset]:not(:nth-child(-n+5)){display:block}head [rel=stylesheet],head script,head script~meta[http-equiv=content-security-policy],head style,head title,head>meta[charset]:not(:nth-child(-n+5)){margin:5px;padding:5px;border-width:5px;background-color:#fff;color:#333}head ::before,head script,head style{font:16px/1.5 monospace,monospace;display:block}head ::before{font-weight:700}head link[rel=stylesheet],head script[src]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src]::before{content:"[Blocking Script – " attr(src) "]"}head link[rel=stylesheet]::before{content:"[Blocking Stylesheet – " attr(href) "]"}head script:not(:empty),head style:not(:empty){max-height:5em;overflow:auto;background-color:#ffd;white-space:pre;border-color:var(--ct-notify);border-style:var(--ct-is-problematic)}head script:not(:empty)::before{content:"[Inline Script] "}head style:not(:empty)::before{content:"[Inline Style] "}head script:not(:empty)~title,head script[src]:not([async]):not([defer]):not([type=module])~title{display:block;border-style:var(--ct-is-affected);border-color:var(--ct-error)}head script:not(:empty)~title::before,head script[src]:not([async]):not([defer]):not([type=module])~title::before{content:"[ blocked by JS] "}head [rel=stylesheet]:not([media=print]):not(.ct)~script,head style:not(:empty)~script{border-style:var(--ct-is-affected);border-color:var(--ct-warn)}head [rel=stylesheet]:not([media=print]):not(.ct)~script::before,head style:not(:empty)~script::before{content:"[JS blocked by CSS – " attr(src) "]"}head script[src][src][async][defer]{display:block;border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src][src][async][defer]::before{content:"[async and defer is redundant: prefer defer – " attr(src) "]"}head script:not([src])[async],head script:not([src])[defer]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script:not([src])[async]::before{content:"The async attribute is redundant on inline scripts"}head script:not([src])[defer]::before{content:"The defer attribute is redundant on inline scripts"}head [rel=stylesheet][href^="//"],head [rel=stylesheet][href^=http],head script[src][src][src^="//"],head script[src][src][src^=http]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script[src][src][src^="//"]::before,head script[src][src][src^=http]::before{content:"[Third Party Blocking Script – " attr(src) "]"}head [rel=stylesheet][href^="//"]::before,head [rel=stylesheet][href^=http]::before{content:"[Third Party Blocking Stylesheet – " attr(href) "]"}head script~meta[http-equiv=content-security-policy]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script~meta[http-equiv=content-security-policy]::before{content:"[Meta CSP defined after JS]"}head>meta[charset]:not(:nth-child(-n+5)){border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head>meta[charset]:not(:nth-child(-n+5))::before{content:"[Charset should appear as early as possible]"}link[rel=stylesheet].ct,link[rel=stylesheet][media=print],script[async],script[defer],script[type=module],style.ct{display:none}' ); -} diff --git a/themes/10up-theme/includes/helpers.php b/themes/10up-theme/includes/helpers.php deleted file mode 100644 index 3fa3f51..0000000 --- a/themes/10up-theme/includes/helpers.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Theme specific helpers. - * - * @package TenUpTheme - */ - -namespace TenUpTheme; - -/** - * Get an initialized class by its full class name, including namespace. - * - * @param string $class_name The class name including the namespace. - * - * @return false|\TenupFramework\ModuleInterface - */ -function get_module( $class_name ) { - return \TenupFramework\ModuleInitialization::get_module( $class_name ); -} diff --git a/themes/10up-theme/includes/template-tags.php b/themes/10up-theme/includes/template-tags.php deleted file mode 100644 index 034f354..0000000 --- a/themes/10up-theme/includes/template-tags.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Custom template tags for this theme. - * - * This file is for custom template tags only and it should not contain - * functions that will be used for filtering or adding an action. - * - * All functions should be prefixed with TenUpTheme in order to prevent - * pollution of the global namespace and potential conflicts with functions - * from plugins. - * Example: `tenup_theme_function()` - * - * @package TenUpTheme\Template_Tags - * - */ - -// phpcs:ignoreFile diff --git a/themes/10up-theme/includes/utility.php b/themes/10up-theme/includes/utility.php deleted file mode 100755 index e7c72fa..0000000 --- a/themes/10up-theme/includes/utility.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Utility functions for the theme. - * - * This file is for custom helper functions. - * These should not be confused with WordPress template - * tags. Template tags typically use prefixing, as opposed - * to Namespaces. - * - * @link https://developer.wordpress.org/themes/basics/template-tags/ - * @package TenUpTheme - */ - -namespace TenUpTheme\Utility; - -/** - * Get asset info from extracted asset files - * - * @param string $slug Asset slug as defined in build/webpack configuration - * @param string $attribute Optional attribute to get. Can be version or dependencies - * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) - */ -function get_asset_info( $slug, $attribute = null ) { - if ( file_exists( TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php'; - } elseif ( file_exists( TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php'; - } else { - $asset = [ - 'version' => TENUP_THEME_VERSION, - 'dependencies' => [], - ]; - } - - if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { - return $asset[ $attribute ]; - } - - return $asset; -} diff --git a/themes/10up-theme/package.json b/themes/10up-theme/package.json index 686c225..1082ee1 100644 --- a/themes/10up-theme/package.json +++ b/themes/10up-theme/package.json @@ -30,7 +30,10 @@ "editor-style-overrides": "./assets/js/admin/editor-style-overrides.js", "frontend": "./assets/js/frontend/frontend.js", "shared": "./assets/js/shared/shared.js", - "block-editor-script": "./includes/block-editor-script.js" + "block-editor-script": "./assets/js/block-editor/block-editor-script.js" + }, + "paths": { + "blocksDir": "./blocks" } } } diff --git a/themes/10up-theme/src/Assets.php b/themes/10up-theme/src/Assets.php new file mode 100644 index 0000000..46a5d6f --- /dev/null +++ b/themes/10up-theme/src/Assets.php @@ -0,0 +1,238 @@ +<?php +/** + * Assets module. + * + * @package TenUpTheme + */ + +namespace TenUpTheme; + +use TenupFramework\Module; +use TenupFramework\ModuleInterface; +use TenUpTheme\Traits\GetAssetInfo; + +/** + * Assets module. + * + * @package TenUpTheme + */ +class Assets implements ModuleInterface { + + use Module; + use GetAssetInfo; + + /** + * Can this module be registered? + * + * @return bool + */ + public function can_register() { + return true; + } + + /** + * Register any hooks and filters. + * + * @return void + */ + public function register() { + add_action( 'wp_enqueue_scripts', [ $this, 'scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'admin_styles' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts' ] ); + add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_scripts' ] ); + add_action( 'wp_enqueue_scripts', [ $this, 'styles' ] ); + add_action( 'wp_head', [ $this, 'js_detection' ], 0 ); + add_action( 'wp_head', [ $this, 'embed_ct_css' ], 0 ); + + add_filter( 'script_loader_tag', [ $this, 'script_loader_tag' ], 10, 2 ); + } + + + /** + * Enqueue scripts for front-end. + * + * @return void + */ + public function scripts() { + + /** + * Enqueuing frontend.js is required to get css hot reloading working in the frontend + * If you're not shipping any front-end js wrap this enqueue in a SCRIPT_DEBUG check. + */ + wp_enqueue_script( + 'frontend', + TENUP_THEME_TEMPLATE_URL . '/dist/js/frontend.js', + $this->get_asset_info( 'frontend', 'dependencies' ), + $this->get_asset_info( 'frontend', 'version' ), + true + ); + + /** + * Enqueuing shared.js is required to get css hot reloading working in the frontend + * If you're not shipping any shared js wrap this enqueue in a SCRIPT_DEBUG check. + */ + + /* + * Uncoment this to use the shared.js file. + wp_enqueue_script( + 'shared', + TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', + $this->get_asset_info( 'shared', 'dependencies' ), + $this->get_asset_info( 'shared', 'version' ), + true + ); + */ + } + + /** + * Enqueue scripts for admin + * + * @return void + */ + public function admin_scripts() { + wp_enqueue_script( + 'admin', + TENUP_THEME_TEMPLATE_URL . '/dist/js/admin.js', + $this->get_asset_info( 'admin', 'dependencies' ), + $this->get_asset_info( 'admin', 'version' ), + true + ); + + /* + * Uncoment this to use the shared.js file. + wp_enqueue_script( + 'shared', + TENUP_THEME_TEMPLATE_URL . '/dist/js/shared.js', + $this->get_asset_info( 'shared', 'dependencies' ), + $this->get_asset_info( 'shared', 'version' ), + true + ); + */ + } + + /** + * Enqueue core block filters, styles and variations. + * + * @return void + */ + public function enqueue_block_editor_scripts() { + wp_enqueue_script( + 'block-editor-script', + TENUP_THEME_DIST_URL . 'js/block-editor-script.js', + $this->get_asset_info( 'block-editor-script', 'dependencies' ), + $this->get_asset_info( 'block-editor-script', 'version' ), + true + ); + } + + /** + * Enqueue styles for admin + * + * @return void + */ + public function admin_styles() { + + wp_enqueue_style( + 'admin-style', + TENUP_THEME_TEMPLATE_URL . '/dist/css/admin.css', + [], + $this->get_asset_info( 'admin-style', 'version' ) + ); + + /* + * Uncoment this to use the shared.css file. + wp_enqueue_style( + 'shared-style', + TENUP_THEME_TEMPLATE_URL . '/dist/css/shared.css', + [], + $this->get_asset_info( 'shared', 'version' ) + ); + */ + } + + /** + * Enqueue styles for front-end. + * + * @return void + */ + public function styles() { + wp_enqueue_style( + 'styles', + TENUP_THEME_TEMPLATE_URL . '/dist/css/frontend.css', + [], + $this->get_asset_info( 'frontend', 'version' ) + ); + } + + /** + * Handles JavaScript detection. + * + * Adds a `js` class to the root `<html>` element when JavaScript is detected. + * + * @return void + */ + public function js_detection() { + + echo "<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>\n"; + } + + /** + * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. + * + * @link https://core.trac.wordpress.org/ticket/12009 + * @param string $tag The script tag. + * @param string $handle The script handle. + * @return string|null + */ + public function script_loader_tag( $tag, $handle ) { + $script_execution = wp_scripts()->get_data( $handle, 'script_execution' ); + + if ( ! $script_execution ) { + return $tag; + } + + if ( 'async' !== $script_execution && 'defer' !== $script_execution ) { + return $tag; + } + + // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()? + foreach ( wp_scripts()->registered as $script ) { + if ( in_array( $handle, $script->deps, true ) ) { + return $tag; + } + } + + // Add the attribute if it hasn't already been added. + if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) { + $tag = preg_replace( ':(?=></script>):', " $script_execution", $tag, 1 ); + } + + return $tag; + } + + /** + * Inlines ct.css in the head + * + * Embeds a diagnostic CSS file written by Harry Roberts + * that helps diagnose render blocking resources and other + * performance bottle necks. + * + * The CSS is inlined in the head of the document, only when requesting + * a page with the query param ?debug_perf=1 + * + * @link https://csswizardry.com/ct/ + * @return void + */ + public function embed_ct_css() { + + $debug_performance = rest_sanitize_boolean( boolval( filter_input( INPUT_GET, 'debug_perf', FILTER_SANITIZE_NUMBER_INT ) ) ); + + if ( ! $debug_performance ) { + return; + } + + wp_register_style( 'ct', false ); // phpcs:ignore + wp_enqueue_style( 'ct' ); + wp_add_inline_style( 'ct', 'head{--ct-is-problematic:solid;--ct-is-affected:dashed;--ct-notify:#0bce6b;--ct-warn:#ffa400;--ct-error:#ff4e42}head,head [rel=stylesheet],head script,head script:not([src])[async],head script:not([src])[defer],head script~meta[http-equiv=content-security-policy],head style,head>meta[charset]:not(:nth-child(-n+5)){display:block}head [rel=stylesheet],head script,head script~meta[http-equiv=content-security-policy],head style,head title,head>meta[charset]:not(:nth-child(-n+5)){margin:5px;padding:5px;border-width:5px;background-color:#fff;color:#333}head ::before,head script,head style{font:16px/1.5 monospace,monospace;display:block}head ::before{font-weight:700}head link[rel=stylesheet],head script[src]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src]::before{content:"[Blocking Script – " attr(src) "]"}head link[rel=stylesheet]::before{content:"[Blocking Stylesheet – " attr(href) "]"}head script:not(:empty),head style:not(:empty){max-height:5em;overflow:auto;background-color:#ffd;white-space:pre;border-color:var(--ct-notify);border-style:var(--ct-is-problematic)}head script:not(:empty)::before{content:"[Inline Script] "}head style:not(:empty)::before{content:"[Inline Style] "}head script:not(:empty)~title,head script[src]:not([async]):not([defer]):not([type=module])~title{display:block;border-style:var(--ct-is-affected);border-color:var(--ct-error)}head script:not(:empty)~title::before,head script[src]:not([async]):not([defer]):not([type=module])~title::before{content:"[<title> blocked by JS] "}head [rel=stylesheet]:not([media=print]):not(.ct)~script,head style:not(:empty)~script{border-style:var(--ct-is-affected);border-color:var(--ct-warn)}head [rel=stylesheet]:not([media=print]):not(.ct)~script::before,head style:not(:empty)~script::before{content:"[JS blocked by CSS – " attr(src) "]"}head script[src][src][async][defer]{display:block;border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script[src][src][async][defer]::before{content:"[async and defer is redundant: prefer defer – " attr(src) "]"}head script:not([src])[async],head script:not([src])[defer]{border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head script:not([src])[async]::before{content:"The async attribute is redundant on inline scripts"}head script:not([src])[defer]::before{content:"The defer attribute is redundant on inline scripts"}head [rel=stylesheet][href^="//"],head [rel=stylesheet][href^=http],head script[src][src][src^="//"],head script[src][src][src^=http]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script[src][src][src^="//"]::before,head script[src][src][src^=http]::before{content:"[Third Party Blocking Script – " attr(src) "]"}head [rel=stylesheet][href^="//"]::before,head [rel=stylesheet][href^=http]::before{content:"[Third Party Blocking Stylesheet – " attr(href) "]"}head script~meta[http-equiv=content-security-policy]{border-style:var(--ct-is-problematic);border-color:var(--ct-error)}head script~meta[http-equiv=content-security-policy]::before{content:"[Meta CSP defined after JS]"}head>meta[charset]:not(:nth-child(-n+5)){border-style:var(--ct-is-problematic);border-color:var(--ct-warn)}head>meta[charset]:not(:nth-child(-n+5))::before{content:"[Charset should appear as early as possible]"}link[rel=stylesheet].ct,link[rel=stylesheet][media=print],script[async],script[defer],script[type=module],style.ct{display:none}' ); + } +} diff --git a/themes/10up-theme/src/Blocks.php b/themes/10up-theme/src/Blocks.php new file mode 100644 index 0000000..94b6909 --- /dev/null +++ b/themes/10up-theme/src/Blocks.php @@ -0,0 +1,183 @@ +<?php +/** + * Gutenberg Blocks setup + * + * @package TenUpTheme + */ + +namespace TenUpTheme; + +use TenupFramework\Module; +use TenupFramework\ModuleInterface; +use TenUpTheme\Traits\GetAssetInfo; + +/** + * Blocks module. + * + * @package TenUpTheme + */ +class Blocks implements ModuleInterface { + + use Module; + use GetAssetInfo; + + /** + * Can this module be registered? + * + * @return bool + */ + public function can_register() { + return true; + } + + /** + * Register any hooks and filters. + * + * @return void + */ + public function register() { + add_action( 'enqueue_block_editor_assets', [ $this, 'blocks_editor_styles' ] ); + add_action( 'init', [ $this, 'enqueue_block_specific_styles' ] ); + add_action( 'init', [ $this, 'register_theme_blocks' ] ); + add_action( 'init', [ $this, 'register_block_pattern_categories' ] ); + } + + + /** + * Automatically registers all blocks that are located within the includes/blocks directory + * + * @return void + */ + public function register_theme_blocks() { + // Register all the blocks in the theme + if ( file_exists( TENUP_THEME_BLOCK_DIST_DIR ) ) { + $block_json_files = glob( TENUP_THEME_BLOCK_DIST_DIR . '*/block.json' ); + + if ( empty( $block_json_files ) ) { + return; + } + + // auto register all blocks that were found. + foreach ( $block_json_files as $filename ) { + + $block_folder = dirname( $filename ); + + $block_options = []; + + $markup_file_path = $block_folder . '/markup.php'; + if ( file_exists( $markup_file_path ) ) { + + // only add the render callback if the block has a file called markup.php in it's directory + $block_options['render_callback'] = function ( $attributes, $content, $block ) use ( $block_folder ) { + + // create helpful variables that will be accessible in markup.php file + $context = $block->context; + + // get the actual markup from the markup.php file + ob_start(); + include $block_folder . '/markup.php'; + return ob_get_clean(); + }; + } + + register_block_type_from_metadata( $block_folder, $block_options ); + } + } + } + + /** + * Enqueue editor-only JavaScript/CSS for blocks. + * + * @return void + */ + public function blocks_editor_styles() { + wp_enqueue_style( + 'editor-style-overrides', + TENUP_THEME_TEMPLATE_URL . '/dist/css/editor-style-overrides.css', + [], + $this->get_asset_info( 'editor-style-overrides', 'version' ) + ); + + if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { + wp_enqueue_script( + 'editor-style-overrides', + TENUP_THEME_TEMPLATE_URL . '/dist/js/editor-style-overrides.js', + $this->get_asset_info( 'editor-style-overrides', 'dependencies' ), + $this->get_asset_info( 'editor-style-overrides', 'version' ), + true + ); + } + } + + + /** + * Enqueue block specific styles. + * + * This function is used to enqueue styles that are specific to a block. It + * first gets all the CSS files in the 'blocks/autoenqueue' directory. Then + * for each stylesheet, it determines the block type by removing the directory + * path and '.css' from the stylesheet path. It then tries to get the asset + * file for the block type. If the asset file doesn't exist, it creates a new + * one with the version set to the file modification time of the stylesheet + * and no dependencies. Finally, it enqueues the block style using the block + * type, the URL to the stylesheet, the path to the stylesheet, the version + * from the asset file, and the dependencies from the asset file. + * + * @return void + */ + public function enqueue_block_specific_styles() { + $stylesheets = glob( TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/**/*.css' ); + + if ( empty( $stylesheets ) ) { + return; + } + + foreach ( $stylesheets as $stylesheet_path ) { + $block_type = str_replace( TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/', '', $stylesheet_path ); + $block_type = str_replace( '.css', '', $block_type ); + $asset_file = TENUP_THEME_DIST_PATH . 'blocks/autoenqueue/' . $block_type . '.asset.php'; + + if ( ! file_exists( $asset_file ) ) { + $asset_file = require $asset_file; + } else { + $asset_file = [ + 'version' => filemtime( $stylesheet_path ), + 'dependencies' => [], + ]; + } + + [$block_namespace, $block_name] = explode( '/', $block_type ); + + wp_register_style( + "tenup-theme-{$block_namespace}-{$block_name}", + TENUP_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.css', + $asset_file['version'], + $asset_file['dependencies'], + ); + + wp_enqueue_block_style( + $block_type, + [ + 'handle' => "tenup-theme-{$block_namespace}-{$block_name}", + 'path' => $stylesheet_path, + ] + ); + } + } + + /** + * Register block pattern categories + * + * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-patterns/ + * + * @return void + */ + public function register_block_pattern_categories() { + + // Register a block pattern category + register_block_pattern_category( + '10up-theme', + [ 'label' => __( '10up Theme', 'tenup-theme' ) ] + ); + } +} diff --git a/themes/10up-theme/src/ThemeCore.php b/themes/10up-theme/src/ThemeCore.php new file mode 100644 index 0000000..f85c276 --- /dev/null +++ b/themes/10up-theme/src/ThemeCore.php @@ -0,0 +1,121 @@ +<?php +/** + * ThemeCore module. + * + * @package TenUpTheme + */ + +namespace TenUpTheme; + +use TenupFramework\ModuleInitialization; + +/** + * ThemeCore module. + * + * @package TenUpTheme + */ +class ThemeCore { + + /** + * Default setup routine + * + * @return void + */ + public function setup() { + add_action( 'init', [ $this, 'init' ], apply_filters( 'tenup_theme_init_priority', 8 ) ); + add_action( 'after_setup_theme', [ $this, 'i18n' ] ); + add_action( 'after_setup_theme', [ $this, 'theme_setup' ] ); + + do_action( 'tenup_theme_loaded' ); + } + + /** + * Registers the default textdomain. + * + * @return void + */ + public function i18n() { + load_theme_textdomain( 'tenup-theme', TENUP_THEME_PATH . '/languages' ); + } + + /** + * Sets up theme defaults and registers support for various WordPress features. + * + * @return void + */ + public function theme_setup() { + add_theme_support( 'automatic-feed-links' ); + add_theme_support( 'title-tag' ); + add_theme_support( 'post-thumbnails' ); + add_theme_support( + 'html5', + array( + 'search-form', + 'gallery', + 'navigation-widgets', + ) + ); + + add_theme_support( 'editor-styles' ); + add_editor_style( 'dist/css/frontend.css' ); + + remove_theme_support( 'core-block-patterns' ); + + // by adding the `theme.json` file block templates automatically get enabled. + // because the template editor will need additional QA and work to get right + // the default is to disable this feature. + remove_theme_support( 'block-templates' ); + + // This theme uses wp_nav_menu() in three locations. + register_nav_menus( + array( + 'primary' => esc_html__( 'Primary Menu', 'tenup-theme' ), + ) + ); + } + + /** + * Initializes the plugin and fires an action other plugins can hook into. + * + * @return void + */ + public function init() { + do_action( 'tenup_theme_before_init' ); + + if ( ! class_exists( '\TenupFramework\ModuleInitialization' ) ) { + add_action( + 'admin_notices', + function () { + $class = 'notice notice-error'; + + printf( + '<div class="%1$s"><p>%2$s</p></div>', + esc_attr( $class ), + wp_kses_post( + __( + 'Please ensure the <a href="https://github.com/10up/wp-framework"><code>10up/wp-framework</code></a> composer package is installed.', + 'tenup-plugin' + ) + ) + ); + } + ); + + return; + } + + ModuleInitialization::instance()->init_classes( TENUP_THEME_INC ); + do_action( 'tenup_theme_init' ); + } + + /** + * Get an initialized class by its full class name, including namespace. + * + * @param string $class_name The class name including the namespace. + * + * @return false|\TenupFramework\ModuleInterface + */ + public static function get_module( $class_name ) { + return \TenupFramework\ModuleInitialization::get_module( $class_name ); + } +} diff --git a/themes/10up-theme/src/Traits/GetAssetInfo.php b/themes/10up-theme/src/Traits/GetAssetInfo.php new file mode 100644 index 0000000..d41d8ab --- /dev/null +++ b/themes/10up-theme/src/Traits/GetAssetInfo.php @@ -0,0 +1,43 @@ +<?php +/** + * Get asset info from extracted asset files + * + * @package TenUpTheme\Traits + */ + +namespace TenUpTheme\Traits; + +/** + * Trait GetAssetInfo + * + * @package TenUpTheme\Traits + */ +trait GetAssetInfo { + + /** + * Get asset info from extracted asset files + * + * @param string $slug Asset slug as defined in build/webpack configuration + * @param string $attribute Optional attribute to get. Can be version or dependencies + * + * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) + */ + protected function get_asset_info( $slug, $attribute = null ) { + if ( file_exists( TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_THEME_PATH . 'dist/js/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_THEME_PATH . 'dist/css/' . $slug . '.asset.php'; + } else { + $asset = [ + 'version' => TENUP_THEME_VERSION, + 'dependencies' => [], + ]; + } + + if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { + return $asset[ $attribute ]; + } + + return $asset; + } +} From 4339a636839787de143fbbca52c8812d6300bf24 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Thu, 6 Feb 2025 16:18:41 +0000 Subject: [PATCH 09/17] Move get_asset_info into trait --- mu-plugins/10up-plugin/src/Assets.php | 41 ++++------------- .../10up-plugin/src/Traits/GetAssetInfo.php | 45 +++++++++++++++++++ 2 files changed, 54 insertions(+), 32 deletions(-) create mode 100644 mu-plugins/10up-plugin/src/Traits/GetAssetInfo.php diff --git a/mu-plugins/10up-plugin/src/Assets.php b/mu-plugins/10up-plugin/src/Assets.php index a112228..60e2d22 100644 --- a/mu-plugins/10up-plugin/src/Assets.php +++ b/mu-plugins/10up-plugin/src/Assets.php @@ -9,6 +9,7 @@ use TenupFramework\Module; use TenupFramework\ModuleInterface; +use TenUpPlugin\Traits\GetAssetInfo; /** * Assets module. @@ -18,6 +19,7 @@ class Assets implements ModuleInterface { use Module; + use GetAssetInfo; /** * Can this module be registered? @@ -54,43 +56,15 @@ protected function get_enqueue_contexts() { return [ 'admin', 'frontend', 'shared' ]; } - /** - * Get asset info from extracted asset files - * - * @param string $slug Asset slug as defined in build/webpack configuration - * @param string $attribute Optional attribute to get. Can be version or dependencies - * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) - */ - public function get_asset_info( $slug, $attribute = null ) { - if ( file_exists( TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php'; - } elseif ( file_exists( TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php'; - } else { - $asset = [ - 'version' => TENUP_PLUGIN_VERSION, - 'dependencies' => [], - ]; - } - - // @var <array{version: string, dependencies: array<string>}> $asset - - if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { - return $asset[ $attribute ]; - } - - return $asset; - } - /** * Generate an URL to a script, taking into account whether SCRIPT_DEBUG is enabled. * - * @param string $script Script file name (no .js extension) + * @param string $script Script file name (no .js extension) * @param string $context Context for the script ('admin', 'frontend', or 'shared') * + * @return string URL * @throws \RuntimeException If an invalid $context is specified. * - * @return string URL */ public function script_url( $script, $context ) { @@ -105,11 +79,11 @@ public function script_url( $script, $context ) { * Generate an URL to a stylesheet, taking into account whether SCRIPT_DEBUG is enabled. * * @param string $stylesheet Stylesheet file name (no .css extension) - * @param string $context Context for the script ('admin', 'frontend', or 'shared') + * @param string $context Context for the script ('admin', 'frontend', or 'shared') * + * @return string URL * @throws \RuntimeException If an invalid $context is specified. * - * @return string URL */ public function style_url( $stylesheet, $context ) { @@ -225,6 +199,7 @@ public function admin_styles() { * Enqueue editor styles. Filters the comma-delimited list of stylesheets to load in TinyMCE. * * @param string $stylesheets Comma-delimited list of stylesheets. + * * @return string */ public function mce_css( $stylesheets ) { @@ -241,8 +216,10 @@ public function mce_css( $stylesheets ) { * Add async/defer attributes to enqueued scripts that have the specified script_execution flag. * * @link https://core.trac.wordpress.org/ticket/12009 + * * @param string $tag The script tag. * @param string $handle The script handle. + * * @return string|null */ public function script_loader_tag( $tag, $handle ) { diff --git a/mu-plugins/10up-plugin/src/Traits/GetAssetInfo.php b/mu-plugins/10up-plugin/src/Traits/GetAssetInfo.php new file mode 100644 index 0000000..6993d71 --- /dev/null +++ b/mu-plugins/10up-plugin/src/Traits/GetAssetInfo.php @@ -0,0 +1,45 @@ +<?php +/** + * Get asset info from extracted asset files + * + * @package TenUpPlugin\Traits + */ + +namespace TenUpPlugin\Traits; + +/** + * Trait GetAssetInfo + * + * @package TenUpPlugin\Traits + */ +trait GetAssetInfo { + + /** + * Get asset info from extracted asset files + * + * @param string $slug Asset slug as defined in build/webpack configuration + * @param string $attribute Optional attribute to get. Can be version or dependencies + * + * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) + */ + public function get_asset_info( $slug, $attribute = null ) { + if ( file_exists( TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_PLUGIN_PATH . 'dist/js/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_PLUGIN_PATH . 'dist/css/' . $slug . '.asset.php'; + } else { + $asset = [ + 'version' => TENUP_PLUGIN_VERSION, + 'dependencies' => [], + ]; + } + + // @var <array{version: string, dependencies: array<string>}> $asset + + if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { + return $asset[ $attribute ]; + } + + return $asset; + } +} From 30ba5b3987ef899e643c562fa4e48f77269530cc Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Thu, 6 Feb 2025 16:51:12 +0000 Subject: [PATCH 10/17] Oop the block theme --- .../{includes => }/blocks/.gitkeep | 0 themes/10up-block-theme/composer.json | 2 +- themes/10up-block-theme/composer.lock | 62 ++++--- themes/10up-block-theme/functions.php | 17 +- themes/10up-block-theme/includes/blocks.php | 101 ---------- themes/10up-block-theme/includes/core.php | 172 ------------------ .../includes/template-tags.php | 36 ---- themes/10up-block-theme/includes/utility.php | 42 ----- themes/10up-block-theme/package.json | 5 +- themes/10up-block-theme/src/Assets.php | 140 ++++++++++++++ themes/10up-block-theme/src/Blocks.php | 124 +++++++++++++ themes/10up-block-theme/src/TemplateTags.php | 50 +++++ themes/10up-block-theme/src/ThemeCore.php | 125 +++++++++++++ .../src/Traits/GetAssetInfo.php | 45 +++++ 14 files changed, 528 insertions(+), 393 deletions(-) rename themes/10up-block-theme/{includes => }/blocks/.gitkeep (100%) delete mode 100644 themes/10up-block-theme/includes/blocks.php delete mode 100755 themes/10up-block-theme/includes/core.php delete mode 100644 themes/10up-block-theme/includes/template-tags.php delete mode 100755 themes/10up-block-theme/includes/utility.php create mode 100644 themes/10up-block-theme/src/Assets.php create mode 100644 themes/10up-block-theme/src/Blocks.php create mode 100644 themes/10up-block-theme/src/TemplateTags.php create mode 100644 themes/10up-block-theme/src/ThemeCore.php create mode 100644 themes/10up-block-theme/src/Traits/GetAssetInfo.php diff --git a/themes/10up-block-theme/includes/blocks/.gitkeep b/themes/10up-block-theme/blocks/.gitkeep similarity index 100% rename from themes/10up-block-theme/includes/blocks/.gitkeep rename to themes/10up-block-theme/blocks/.gitkeep diff --git a/themes/10up-block-theme/composer.json b/themes/10up-block-theme/composer.json index 113490a..ef804ee 100644 --- a/themes/10up-block-theme/composer.json +++ b/themes/10up-block-theme/composer.json @@ -20,7 +20,7 @@ }, "autoload": { "psr-4": { - "TenupBlockTheme\\": "includes/classes/" + "TenupBlockTheme\\": "src/" } }, "config": { diff --git a/themes/10up-block-theme/composer.lock b/themes/10up-block-theme/composer.lock index baed750..e5a8ca1 100644 --- a/themes/10up-block-theme/composer.lock +++ b/themes/10up-block-theme/composer.lock @@ -55,16 +55,16 @@ }, { "name": "amphp/amp", - "version": "v3.0.2", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "138801fb68cfc9c329da8a7b39d01ce7291ee4b0" + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/138801fb68cfc9c329da8a7b39d01ce7291ee4b0", - "reference": "138801fb68cfc9c329da8a7b39d01ce7291ee4b0", + "url": "https://api.github.com/repos/amphp/amp/zipball/7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", "shasum": "" }, "require": { @@ -124,7 +124,7 @@ ], "support": { "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v3.0.2" + "source": "https://github.com/amphp/amp/tree/v3.1.0" }, "funding": [ { @@ -132,7 +132,7 @@ "type": "github" } ], - "time": "2024-05-10T21:37:46+00:00" + "time": "2025-01-26T16:07:39+00:00" }, { "name": "amphp/byte-stream", @@ -907,16 +907,16 @@ }, { "name": "illuminate/collections", - "version": "v11.38.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "9100b083eeb85d38d78fc1de28f7326596ab2eda" + "reference": "80c85f81573cc4c024da05312119f9149a6b64c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/9100b083eeb85d38d78fc1de28f7326596ab2eda", - "reference": "9100b083eeb85d38d78fc1de28f7326596ab2eda", + "url": "https://api.github.com/repos/illuminate/collections/zipball/80c85f81573cc4c024da05312119f9149a6b64c1", + "reference": "80c85f81573cc4c024da05312119f9149a6b64c1", "shasum": "" }, "require": { @@ -959,11 +959,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-12-18T14:14:45+00:00" + "time": "2025-01-24T15:40:32+00:00" }, { "name": "illuminate/conditionable", - "version": "v11.38.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", @@ -1009,7 +1009,7 @@ }, { "name": "illuminate/contracts", - "version": "v11.38.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -1057,7 +1057,7 @@ }, { "name": "illuminate/macroable", - "version": "v11.38.2", + "version": "v11.41.3", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", @@ -1619,27 +1619,27 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.18.2", + "version": "1.19.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "d41c44a7eab604c3eb0cad93210612d4c1429c20" + "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d41c44a7eab604c3eb0cad93210612d4c1429c20", - "reference": "d41c44a7eab604c3eb0cad93210612d4c1429c20", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", + "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", "shasum": "" }, "require": { - "illuminate/contracts": "^9.28|^10.0|^11.0", + "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0", "php": "^8.0" }, "require-dev": { "mockery/mockery": "^1.5", - "orchestra/testbench": "^7.7|^8.0|^9.0", - "pestphp/pest": "^1.22|^2", - "phpunit/phpunit": "^9.5.24|^10.5", + "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.23|^2.1|^3.1", + "phpunit/phpunit": "^9.5.24|^10.5|^11.5", "spatie/pest-plugin-test-time": "^1.1|^2.2" }, "type": "library", @@ -1667,7 +1667,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.18.2" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.19.0" }, "funding": [ { @@ -1675,7 +1675,7 @@ "type": "github" } ], - "time": "2025-01-20T14:14:17+00:00" + "time": "2025-02-06T14:58:20+00:00" }, { "name": "spatie/php-structure-discoverer", @@ -2425,16 +2425,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.11.2", + "version": "3.11.3", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", "shasum": "" }, "require": { @@ -2499,9 +2499,13 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-12-11T16:04:26+00:00" + "time": "2025-01-23T17:04:15+00:00" }, { "name": "wp-coding-standards/wpcs", diff --git a/themes/10up-block-theme/functions.php b/themes/10up-block-theme/functions.php index 39a5220..6cee7a0 100755 --- a/themes/10up-block-theme/functions.php +++ b/themes/10up-block-theme/functions.php @@ -11,12 +11,12 @@ define( 'TENUP_BLOCK_THEME_PATH', get_template_directory() . '/' ); define( 'TENUP_BLOCK_THEME_DIST_PATH', TENUP_BLOCK_THEME_PATH . 'dist/' ); define( 'TENUP_BLOCK_THEME_DIST_URL', TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/' ); -define( 'TENUP_BLOCK_THEME_INC', TENUP_BLOCK_THEME_PATH . 'includes/' ); +define( 'TENUP_BLOCK_THEME_INC', TENUP_BLOCK_THEME_PATH . 'blocks/' ); define( 'TENUP_BLOCK_THEME_BLOCK_DIST_DIR', TENUP_BLOCK_THEME_DIST_PATH . '/blocks/' ); // Require Composer autoloader if it exists. -if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require_once __DIR__ . '/vendor/autoload.php'; +if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + throw new Exception( 'Please run `composer install` in your theme directory.' ); } $is_local_env = in_array( wp_get_environment_type(), [ 'local', 'development' ], true ); @@ -31,12 +31,7 @@ } } -require_once TENUP_BLOCK_THEME_INC . 'core.php'; -require_once TENUP_BLOCK_THEME_INC . 'blocks.php'; -require_once TENUP_BLOCK_THEME_INC . 'template-tags.php'; -require_once TENUP_BLOCK_THEME_INC . 'utility.php'; +require_once __DIR__ . '/vendor/autoload.php'; -// Run the setup functions. -TenupBlockTheme\Core\setup(); -TenupBlockTheme\Blocks\setup(); -TenupBlockTheme\TemplateTags\setup(); +$theme_core = new \TenupBlockTheme\ThemeCore(); +$theme_core->setup(); diff --git a/themes/10up-block-theme/includes/blocks.php b/themes/10up-block-theme/includes/blocks.php deleted file mode 100644 index 4c3cd0c..0000000 --- a/themes/10up-block-theme/includes/blocks.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Blocks setup, site hooks and filters. - * - * @package TenupBlockTheme - */ - -namespace TenupBlockTheme\Blocks; - -use function TenupBlockTheme\Utility\get_asset_info; - -/** - * Set up theme defaults and register supported WordPress features. - * - * @return void - */ -function setup() { - add_action( 'init', 'TenupBlockTheme\Blocks\register_theme_blocks', 10, 0 ); - add_action( 'init', 'TenupBlockTheme\Blocks\enqueue_theme_block_styles', 10, 0 ); -} - -/** - * Automatically registers all blocks that are located within the includes/blocks directory - * - * @return void - */ -function register_theme_blocks() { - // Register all the blocks in the theme. - if ( file_exists( TENUP_BLOCK_THEME_BLOCK_DIST_DIR ) ) { - $block_json_files = glob( TENUP_BLOCK_THEME_BLOCK_DIST_DIR . '*/block.json' ); - $block_names = []; - - if ( empty( $block_json_files ) ) { - return; - } - - foreach ( $block_json_files as $filename ) { - $block_folder = dirname( $filename ); - $block = register_block_type_from_metadata( $block_folder ); - - if ( ! $block ) { - continue; - } - - $block_names[] = $block->name; - } - - add_filter( - 'allowed_block_types_all', - function ( array|bool $allowed_blocks ) use ( $block_names ): array|bool { - if ( ! is_array( $allowed_blocks ) ) { - return $allowed_blocks; - } - return array_merge( $allowed_blocks, $block_names ); - } - ); - } -} - -/** - * Enqueue block specific styles. - * - * @return void - */ -function enqueue_theme_block_styles() { - $stylesheets = glob( TENUP_BLOCK_THEME_DIST_PATH . '/blocks/autoenqueue/**/*.css' ); - - if ( empty( $stylesheets ) ) { - return; - } - - foreach ( $stylesheets as $stylesheet_path ) { - $block_type = str_replace( TENUP_BLOCK_THEME_DIST_PATH . '/blocks/autoenqueue/', '', $stylesheet_path ); - $block_type = str_replace( '.css', '', $block_type ); - - wp_register_style( - "tenup-theme-{$block_type}", - TENUP_BLOCK_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.css', - get_asset_info( 'blocks/autoenqueue/' . $block_type, 'dependencies' ), - get_asset_info( 'blocks/autoenqueue/' . $block_type, 'version' ), - ); - - wp_enqueue_block_style( - $block_type, - [ - 'handle' => "tenup-theme-{$block_type}", - 'path' => $stylesheet_path, - ] - ); - - if ( file_exists( TENUP_BLOCK_THEME_DIST_PATH . 'blocks/autoenqueue/' . $block_type . '.js' ) ) { - wp_enqueue_script( - $block_type, - TENUP_BLOCK_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.js', - get_asset_info( 'blocks/autoenqueue/' . $block_type, 'dependencies' ), - get_asset_info( 'blocks/autoenqueue/' . $block_type, 'version' ), - true - ); - } - } -} diff --git a/themes/10up-block-theme/includes/core.php b/themes/10up-block-theme/includes/core.php deleted file mode 100755 index 4bc4722..0000000 --- a/themes/10up-block-theme/includes/core.php +++ /dev/null @@ -1,172 +0,0 @@ -<?php -/** - * Core setup, site hooks and filters. - * - * @package TenupBlockTheme - */ - -namespace TenupBlockTheme\Core; - -use function TenupBlockTheme\Utility\get_asset_info; - -/** - * Set up theme defaults and register supported WordPress features. - * - * @return void - */ -function setup() { - add_action( 'init', 'TenupBlockTheme\Core\scripts' ); - add_action( 'init', 'TenupBlockTheme\Core\register_all_icons', 10 ); - add_action( 'after_setup_theme', 'TenupBlockTheme\Core\i18n' ); - add_action( 'after_setup_theme', 'TenupBlockTheme\Core\theme_setup' ); - add_action( 'wp_head', 'TenupBlockTheme\Core\js_detection', 0 ); - add_action( 'wp_head', 'TenupBlockTheme\Core\scrollbar_detection', 0 ); - add_action( 'wp_enqueue_scripts', 'TenupBlockTheme\Core\styles' ); - add_action( 'enqueue_block_editor_assets', 'TenupBlockTheme\Core\editor_style_overrides' ); -} - -/** - * Makes Theme available for translation. - * - * Translations can be added to the /languages directory. - * If you're building a theme based on "tenup-theme", change the - * filename of '/languages/TenupBlockTheme.pot' to the name of your project. - * - * @return void - */ -function i18n() { - load_theme_textdomain( 'tenup-theme', TENUP_BLOCK_THEME_PATH . '/languages' ); -} - -/** - * Sets up theme defaults and registers support for various WordPress features. - * - * @return void - */ -function theme_setup() { - add_theme_support( 'editor-styles' ); - add_editor_style( '/dist/css/frontend.css' ); - remove_theme_support( 'core-block-patterns' ); -} - -/** - * Enqueue scripts for front-end. - * - * @return void - */ -function scripts() { - - wp_enqueue_script( - 'frontend', - TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/js/frontend.js', - get_asset_info( 'frontend', 'dependencies' ), - get_asset_info( 'frontend', 'version' ), - [ - 'strategy' => 'defer', - ] - ); -} - - -/** - * Enqueue styles for front-end. - * - * @return void - */ -function styles() { - wp_enqueue_style( - 'tenup-theme-styles', - TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/css/frontend.css', - [], - get_asset_info( 'frontend', 'version' ) - ); -} - -/** - * Enqueue styles for editor only. - * - * @return void - */ -function editor_style_overrides() { - wp_enqueue_style( - 'tenup-theme-editor-style-overrides', - TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/css/editor-style-overrides.css', - [], - TENUP_BLOCK_THEME_VERSION - ); - - wp_enqueue_script( - 'tenup-theme-block-extensions', - TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/js/block-extensions.js', - get_asset_info( 'block-extensions', 'dependencies' ), - get_asset_info( 'block-extensions', 'version' ), - true - ); -} - -/** - * register all icons located in the dist/svg folder - * - * @return void - */ -function register_all_icons() { - if ( ! function_exists( '\UIKitCore\Helpers\register_icons' ) ) { - return; - } - - $icon_paths = glob( TENUP_BLOCK_THEME_DIST_PATH . 'svg/*.svg' ); - - if ( ! $icon_paths ) { - return; - } - - $icons = array_map( - function ( $icon_path ) { - $icon_name = preg_replace( '#\..*$#', '', basename( $icon_path ) ); - - if ( ! $icon_name || ! class_exists( '\UIKitCore\Icon' ) ) { - return false; - } - - return new \UIKitCore\Icon( - $icon_name, - ucwords( str_replace( '-', ' ', $icon_name ) ), - $icon_path - ); - }, - $icon_paths - ); - - \UIKitCore\Helpers\register_icons( - [ - 'name' => 'tenup', - 'label' => 'Theme Icons', - 'icons' => $icons, - ] - ); -} - -/** - * Handles JavaScript detection. - * - * Adds a `js` class to the root `<html>` element when JavaScript is detected. - * - * @return void - */ -function js_detection() { - - echo "<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>\n"; -} - -/** - * Handles scrollbar width detection. - * - * Adds a JavaScript event listener to the DOMContentLoaded event. When the DOM is fully loaded, - * it calculates the width of the scrollbar and sets a CSS variable `--wp--custom--scrollbar-width` with the width. - * It also adds an event listener to the window resize event to update the scrollbar width when the window is resized. - * - * @return void - */ -function scrollbar_detection() { - echo '<script>window.addEventListener("DOMContentLoaded",()=>{const t=()=>window.innerWidth-document.body.clientWidth;const e=()=>{document.documentElement.style.setProperty("--wp--custom--scrollbar-width",`${t()}px`)};e();});</script>' . "\n"; -} diff --git a/themes/10up-block-theme/includes/template-tags.php b/themes/10up-block-theme/includes/template-tags.php deleted file mode 100644 index 6a9176d..0000000 --- a/themes/10up-block-theme/includes/template-tags.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * Custom template tags for this theme. - * - * This file is for custom template tags only and it should not contain - * functions that will be used for filtering or adding an action. - * - * All functions should be prefixed with TenupBlockTheme in order to prevent - * pollution of the global namespace and potential conflicts with functions - * from plugins. - * Example: `TENUP_BLOCK_THEME_function()` - * - * @package TenupBlockTheme\TemplateTags - */ - -namespace TenupBlockTheme\TemplateTags; - -/** - * Set up theme defaults and register supported WordPress features. - * - * @return void - */ -function setup() { - add_action( 'wp_head', 'TenupBlockTheme\TemplateTags\add_viewport_meta_tag', 10, 0 ); -} - -/** - * Add viewport meta tag to head. - * - * @return void - */ -function add_viewport_meta_tag() { - ?> - <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> - <?php -} diff --git a/themes/10up-block-theme/includes/utility.php b/themes/10up-block-theme/includes/utility.php deleted file mode 100755 index ebbb5b6..0000000 --- a/themes/10up-block-theme/includes/utility.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Utility functions for the theme. - * - * This file is for custom helper functions. - * These should not be confused with WordPress template - * tags. Template tags typically use prefixing, as opposed - * to Namespaces. - * - * @link https://developer.wordpress.org/themes/basics/template-tags/ - * @package TenupBlockTheme - */ - -namespace TenupBlockTheme\Utility; - -/** - * Get asset info from extracted asset files - * - * @param string $slug Asset slug as defined in build/webpack configuration - * @param string $attribute Optional attribute to get. Can be version or dependencies - * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) - */ -function get_asset_info( $slug, $attribute = null ) { - if ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_BLOCK_THEME_PATH . 'dist/js/' . $slug . '.asset.php'; - } elseif ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_BLOCK_THEME_PATH . 'dist/css/' . $slug . '.asset.php'; - } elseif ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/' . $slug . '.asset.php' ) ) { - $asset = require TENUP_BLOCK_THEME_PATH . 'dist/' . $slug . '.asset.php'; - } else { - $asset = [ - 'version' => TENUP_BLOCK_THEME_VERSION, - 'dependencies' => [], - ]; - } - - if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { - return $asset[ $attribute ]; - } - - return $asset; -} diff --git a/themes/10up-block-theme/package.json b/themes/10up-block-theme/package.json index 0b32952..ca9ed8c 100644 --- a/themes/10up-block-theme/package.json +++ b/themes/10up-block-theme/package.json @@ -31,6 +31,9 @@ "editor-style-overrides": "./assets/css/editor-style-overrides.css", "frontend": "./assets/js/frontend.js", "block-extensions": "./assets/js/block-extensions.js" - } + }, + "paths": { + "blocksDir": "./blocks" + } } } diff --git a/themes/10up-block-theme/src/Assets.php b/themes/10up-block-theme/src/Assets.php new file mode 100644 index 0000000..80ea846 --- /dev/null +++ b/themes/10up-block-theme/src/Assets.php @@ -0,0 +1,140 @@ +<?php +/** + * Assets module. + * + * @package TenupBlockTheme + */ + +namespace TenupBlockTheme; + +use TenupFramework\Module; +use TenupFramework\ModuleInterface; +use TenupBlockTheme\Traits\GetAssetInfo; + +/** + * Assets module. + * + * @package TenupBlockTheme + */ +class Assets implements ModuleInterface { + + use Module; + use GetAssetInfo; + + /** + * Can this module be registered? + * + * @return bool + */ + public function can_register() { + return true; + } + + /** + * Register any hooks and filters. + * + * @return void + */ + public function register() { + add_action( 'init', [ $this, 'scripts' ] ); + add_action( 'init', [ $this, 'register_all_icons' ], 10 ); + add_action( 'wp_enqueue_scripts', [ $this, 'styles' ] ); + add_action( 'enqueue_block_editor_assets', [ $this, 'editor_style_overrides' ] ); + } + + /** + * Enqueue scripts for front-end. + * + * @return void + */ + public function scripts() { + + wp_enqueue_script( + 'frontend', + TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/js/frontend.js', + $this->get_asset_info( 'frontend', 'dependencies' ), + $this->get_asset_info( 'frontend', 'version' ), + [ + 'strategy' => 'defer', + ] + ); + } + + /** + * Enqueue styles for front-end. + * + * @return void + */ + public function styles() { + wp_enqueue_style( + 'tenup-theme-styles', + TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/css/frontend.css', + [], + $this->get_asset_info( 'frontend', 'version' ) + ); + } + + /** + * Enqueue styles for editor only. + * + * @return void + */ + public function editor_style_overrides() { + wp_enqueue_style( + 'tenup-theme-editor-style-overrides', + TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/css/editor-style-overrides.css', + [], + TENUP_BLOCK_THEME_VERSION + ); + + wp_enqueue_script( + 'tenup-theme-block-extensions', + TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/js/block-extensions.js', + $this->get_asset_info( 'block-extensions', 'dependencies' ), + $this->get_asset_info( 'block-extensions', 'version' ), + true + ); + } + + /** + * register all icons located in the dist/svg folder + * + * @return void + */ + public function register_all_icons() { + if ( ! function_exists( '\UIKitCore\Helpers\register_icons' ) ) { + return; + } + + $icon_paths = glob( TENUP_BLOCK_THEME_DIST_PATH . 'svg/*.svg' ); + + if ( ! $icon_paths ) { + return; + } + + $icons = array_map( + function ( $icon_path ) { + $icon_name = preg_replace( '#\..*$#', '', basename( $icon_path ) ); + + if ( ! $icon_name || ! class_exists( '\UIKitCore\Icon' ) ) { + return false; + } + + return new \UIKitCore\Icon( + $icon_name, + ucwords( str_replace( '-', ' ', $icon_name ) ), + $icon_path + ); + }, + $icon_paths + ); + + \UIKitCore\Helpers\register_icons( + [ + 'name' => 'tenup', + 'label' => 'Theme Icons', + 'icons' => $icons, + ] + ); + } +} diff --git a/themes/10up-block-theme/src/Blocks.php b/themes/10up-block-theme/src/Blocks.php new file mode 100644 index 0000000..dc7b38c --- /dev/null +++ b/themes/10up-block-theme/src/Blocks.php @@ -0,0 +1,124 @@ +<?php +/** + * Gutenberg Blocks setup + * + * @package TenupBlockTheme + */ + +namespace TenupBlockTheme; + +use TenupFramework\Module; +use TenupFramework\ModuleInterface; +use TenupBlockTheme\Traits\GetAssetInfo; + +/** + * Blocks module. + * + * @package TenupBlockTheme + */ +class Blocks implements ModuleInterface { + + use Module; + use GetAssetInfo; + + /** + * Can this module be registered? + * + * @return bool + */ + public function can_register() { + return true; + } + + /** + * Register any hooks and filters. + * + * @return void + */ + public function register() { + add_action( 'init', [ $this, 'register_theme_blocks' ], 10, 0 ); + add_action( 'init', [ $this, 'enqueue_theme_block_styles' ], 10, 0 ); + } + + + /** + * Automatically registers all blocks that are located within the includes/blocks directory + * + * @return void + */ + public function register_theme_blocks() { + // Register all the blocks in the theme. + if ( file_exists( TENUP_BLOCK_THEME_BLOCK_DIST_DIR ) ) { + $block_json_files = glob( TENUP_BLOCK_THEME_BLOCK_DIST_DIR . '*/block.json' ); + $block_names = []; + + if ( empty( $block_json_files ) ) { + return; + } + + foreach ( $block_json_files as $filename ) { + $block_folder = dirname( $filename ); + $block = register_block_type_from_metadata( $block_folder ); + + if ( ! $block ) { + continue; + } + + $block_names[] = $block->name; + } + + add_filter( + 'allowed_block_types_all', + function ( array|bool $allowed_blocks ) use ( $block_names ): array|bool { + if ( ! is_array( $allowed_blocks ) ) { + return $allowed_blocks; + } + return array_merge( $allowed_blocks, $block_names ); + } + ); + } + } + + /** + * Enqueue block specific styles. + * + * @return void + */ + public function enqueue_theme_block_styles() { + $stylesheets = glob( TENUP_BLOCK_THEME_DIST_PATH . '/blocks/autoenqueue/**/*.css' ); + + if ( empty( $stylesheets ) ) { + return; + } + + foreach ( $stylesheets as $stylesheet_path ) { + $block_type = str_replace( TENUP_BLOCK_THEME_DIST_PATH . '/blocks/autoenqueue/', '', $stylesheet_path ); + $block_type = str_replace( '.css', '', $block_type ); + + wp_register_style( + "tenup-theme-{$block_type}", + TENUP_BLOCK_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.css', + $this->get_asset_info( 'blocks/autoenqueue/' . $block_type, 'dependencies' ), + $this->get_asset_info( 'blocks/autoenqueue/' . $block_type, 'version' ), + ); + + wp_enqueue_block_style( + $block_type, + [ + 'handle' => "tenup-theme-{$block_type}", + 'path' => $stylesheet_path, + ] + ); + + if ( file_exists( TENUP_BLOCK_THEME_DIST_PATH . 'blocks/autoenqueue/' . $block_type . '.js' ) ) { + wp_enqueue_script( + $block_type, + TENUP_BLOCK_THEME_DIST_URL . 'blocks/autoenqueue/' . $block_type . '.js', + $this->get_asset_info( 'blocks/autoenqueue/' . $block_type, 'dependencies' ), + $this->get_asset_info( 'blocks/autoenqueue/' . $block_type, 'version' ), + true + ); + } + } + } +} diff --git a/themes/10up-block-theme/src/TemplateTags.php b/themes/10up-block-theme/src/TemplateTags.php new file mode 100644 index 0000000..95e77e5 --- /dev/null +++ b/themes/10up-block-theme/src/TemplateTags.php @@ -0,0 +1,50 @@ +<?php +/** + * TemplateTags module. + * + * @package TenupBlockTheme + */ + +namespace TenupBlockTheme; + +use TenupFramework\Module; +use TenupFramework\ModuleInterface; + +/** + * TemplateTags module. + * + * @package TenupBlockTheme + */ +class TemplateTags implements ModuleInterface { + + use Module; + + /** + * Can this module be registered? + * + * @return bool + */ + public function can_register() { + return true; + } + + /** + * Register any hooks and filters. + * + * @return void + */ + public function register() { + add_action( 'wp_head', [ $this, 'add_viewport_meta_tag' ], 10, 0 ); + } + + /** + * Add viewport meta tag to head. + * + * @return void + */ + public function add_viewport_meta_tag() { + ?> + <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> + <?php + } +} diff --git a/themes/10up-block-theme/src/ThemeCore.php b/themes/10up-block-theme/src/ThemeCore.php new file mode 100644 index 0000000..20deae0 --- /dev/null +++ b/themes/10up-block-theme/src/ThemeCore.php @@ -0,0 +1,125 @@ +<?php +/** + * ThemeCore module. + * + * @package TenupBlockTheme + */ + +namespace TenupBlockTheme; + +use TenupFramework\ModuleInitialization; + +/** + * ThemeCore module. + * + * @package TenupBlockTheme + */ +class ThemeCore { + + /** + * Default setup routine + * + * @return void + */ + public function setup() { + add_action( 'init', [ $this, 'init' ], apply_filters( 'tenup_block_theme_init_priority', 8 ) ); + add_action( 'after_setup_theme', [ $this, 'i18n' ] ); + add_action( 'after_setup_theme', [ $this, 'theme_setup' ] ); + + add_action( 'wp_head', [ $this, 'js_detection' ], 0 ); + add_action( 'wp_head', [ $this, 'scrollbar_detection' ], 0 ); + + do_action( 'tenup_block_theme_loaded' ); + } + + /** + * Registers the default textdomain. + * + * @return void + */ + public function i18n() { + load_theme_textdomain( 'tenup-theme', TENUP_BLOCK_THEME_PATH . '/languages' ); + } + + /** + * Sets up theme defaults and registers support for various WordPress features. + * + * @return void + */ + public function theme_setup() { + add_theme_support( 'editor-styles' ); + add_editor_style( '/dist/css/frontend.css' ); + remove_theme_support( 'core-block-patterns' ); + } + + /** + * Initializes the plugin and fires an action other plugins can hook into. + * + * @return void + */ + public function init() { + do_action( 'tenup_block_theme_before_init' ); + + if ( ! class_exists( '\TenupFramework\ModuleInitialization' ) ) { + add_action( + 'admin_notices', + function () { + $class = 'notice notice-error'; + + printf( + '<div class="%1$s"><p>%2$s</p></div>', + esc_attr( $class ), + wp_kses_post( + __( + 'Please ensure the <a href="https://github.com/10up/wp-framework"><code>10up/wp-framework</code></a> composer package is installed.', + 'tenup-plugin' + ) + ) + ); + } + ); + + return; + } + + ModuleInitialization::instance()->init_classes( TENUP_BLOCK_THEME_INC ); + do_action( 'tenup_block_theme_init' ); + } + + /** + * Handles JavaScript detection. + * + * Adds a `js` class to the root `<html>` element when JavaScript is detected. + * + * @return void + */ + public function js_detection() { + + echo "<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>\n"; + } + + /** + * Handles scrollbar width detection. + * + * Adds a JavaScript event listener to the DOMContentLoaded event. When the DOM is fully loaded, + * it calculates the width of the scrollbar and sets a CSS variable `--wp--custom--scrollbar-width` with the width. + * It also adds an event listener to the window resize event to update the scrollbar width when the window is + * resized. + * + * @return void + */ + public function scrollbar_detection() { + echo '<script>window.addEventListener("DOMContentLoaded",()=>{const t=()=>window.innerWidth-document.body.clientWidth;const e=()=>{document.documentElement.style.setProperty("--wp--custom--scrollbar-width",`${t()}px`)};e();});</script>' . "\n"; + } + + /** + * Get an initialized class by its full class name, including namespace. + * + * @param string $class_name The class name including the namespace. + * + * @return false|\TenupFramework\ModuleInterface + */ + public static function get_module( $class_name ) { + return \TenupFramework\ModuleInitialization::get_module( $class_name ); + } +} diff --git a/themes/10up-block-theme/src/Traits/GetAssetInfo.php b/themes/10up-block-theme/src/Traits/GetAssetInfo.php new file mode 100644 index 0000000..5126a0f --- /dev/null +++ b/themes/10up-block-theme/src/Traits/GetAssetInfo.php @@ -0,0 +1,45 @@ +<?php +/** + * Get asset info from extracted asset files + * + * @package TenupBlockTheme\Traits + */ + +namespace TenupBlockTheme\Traits; + +/** + * Trait GetAssetInfo + * + * @package TenupBlockTheme\Traits + */ +trait GetAssetInfo { + + /** + * Get asset info from extracted asset files + * + * @param string $slug Asset slug as defined in build/webpack configuration + * @param string $attribute Optional attribute to get. Can be version or dependencies + * + * @return ($attribute is null ? array{version: string, dependencies: array<string>} : $attribute is 'dependencies' ? array<string> : string) + */ + protected function get_asset_info( $slug, $attribute = null ) { + if ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/js/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_BLOCK_THEME_PATH . 'dist/js/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/css/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_BLOCK_THEME_PATH . 'dist/css/' . $slug . '.asset.php'; + } elseif ( file_exists( TENUP_BLOCK_THEME_PATH . 'dist/' . $slug . '.asset.php' ) ) { + $asset = require TENUP_BLOCK_THEME_PATH . 'dist/' . $slug . '.asset.php'; + } else { + $asset = [ + 'version' => TENUP_BLOCK_THEME_VERSION, + 'dependencies' => [], + ]; + } + + if ( ! empty( $attribute ) && isset( $asset[ $attribute ] ) ) { + return $asset[ $attribute ]; + } + + return $asset; + } +} From 47c728659e7a1a39dc4f27b6ed25cd83f028988c Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Thu, 6 Feb 2025 16:51:23 +0000 Subject: [PATCH 11/17] Linting fix --- mu-plugins/10up-plugin/src/Assets.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/mu-plugins/10up-plugin/src/Assets.php b/mu-plugins/10up-plugin/src/Assets.php index 60e2d22..e33db69 100644 --- a/mu-plugins/10up-plugin/src/Assets.php +++ b/mu-plugins/10up-plugin/src/Assets.php @@ -64,7 +64,6 @@ protected function get_enqueue_contexts() { * * @return string URL * @throws \RuntimeException If an invalid $context is specified. - * */ public function script_url( $script, $context ) { @@ -83,7 +82,6 @@ public function script_url( $script, $context ) { * * @return string URL * @throws \RuntimeException If an invalid $context is specified. - * */ public function style_url( $stylesheet, $context ) { From 01baf5eb5cddf410fb417bda577ecd932d0238d7 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 10:28:05 +0000 Subject: [PATCH 12/17] Include name --- package-lock.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package-lock.json b/package-lock.json index df2e472..b86968c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20615,6 +20615,7 @@ } }, "themes/10up-block-theme": { + "name": "tenup-block-theme", "version": "1.0.0", "dependencies": { "@10up/block-components": "^1.19.4", From 27d971d82a1abd5743a708a879dd24b451768d43 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 10:37:35 +0000 Subject: [PATCH 13/17] PR feedback --- themes/10up-block-theme/package.json | 6 +++--- themes/10up-block-theme/src/Assets.php | 1 - themes/10up-theme/src/Assets.php | 4 ---- themes/10up-theme/src/Blocks.php | 2 -- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/themes/10up-block-theme/package.json b/themes/10up-block-theme/package.json index ca9ed8c..b6277f9 100644 --- a/themes/10up-block-theme/package.json +++ b/themes/10up-block-theme/package.json @@ -32,8 +32,8 @@ "frontend": "./assets/js/frontend.js", "block-extensions": "./assets/js/block-extensions.js" }, - "paths": { - "blocksDir": "./blocks" - } + "paths": { + "blocksDir": "./blocks" + } } } diff --git a/themes/10up-block-theme/src/Assets.php b/themes/10up-block-theme/src/Assets.php index 80ea846..a8d0ced 100644 --- a/themes/10up-block-theme/src/Assets.php +++ b/themes/10up-block-theme/src/Assets.php @@ -48,7 +48,6 @@ public function register() { * @return void */ public function scripts() { - wp_enqueue_script( 'frontend', TENUP_BLOCK_THEME_TEMPLATE_URL . '/dist/js/frontend.js', diff --git a/themes/10up-theme/src/Assets.php b/themes/10up-theme/src/Assets.php index 46a5d6f..1a2cbaa 100644 --- a/themes/10up-theme/src/Assets.php +++ b/themes/10up-theme/src/Assets.php @@ -54,7 +54,6 @@ public function register() { * @return void */ public function scripts() { - /** * Enqueuing frontend.js is required to get css hot reloading working in the frontend * If you're not shipping any front-end js wrap this enqueue in a SCRIPT_DEBUG check. @@ -131,7 +130,6 @@ public function enqueue_block_editor_scripts() { * @return void */ public function admin_styles() { - wp_enqueue_style( 'admin-style', TENUP_THEME_TEMPLATE_URL . '/dist/css/admin.css', @@ -172,7 +170,6 @@ public function styles() { * @return void */ public function js_detection() { - echo "<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>\n"; } @@ -224,7 +221,6 @@ public function script_loader_tag( $tag, $handle ) { * @return void */ public function embed_ct_css() { - $debug_performance = rest_sanitize_boolean( boolval( filter_input( INPUT_GET, 'debug_perf', FILTER_SANITIZE_NUMBER_INT ) ) ); if ( ! $debug_performance ) { diff --git a/themes/10up-theme/src/Blocks.php b/themes/10up-theme/src/Blocks.php index 94b6909..89423a9 100644 --- a/themes/10up-theme/src/Blocks.php +++ b/themes/10up-theme/src/Blocks.php @@ -42,7 +42,6 @@ public function register() { add_action( 'init', [ $this, 'register_block_pattern_categories' ] ); } - /** * Automatically registers all blocks that are located within the includes/blocks directory * @@ -173,7 +172,6 @@ public function enqueue_block_specific_styles() { * @return void */ public function register_block_pattern_categories() { - // Register a block pattern category register_block_pattern_category( '10up-theme', From 1d4e80cb7a737e5ecc8897febe162f16c2acae26 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 10:53:14 +0000 Subject: [PATCH 14/17] Add new template-tags.php file --- themes/10up-block-theme/functions.php | 2 ++ themes/10up-block-theme/template-tags.php | 34 +++++++++++++++++++++++ themes/10up-theme/functions.php | 2 ++ themes/10up-theme/template-tags.php | 34 +++++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 themes/10up-block-theme/template-tags.php create mode 100644 themes/10up-theme/template-tags.php diff --git a/themes/10up-block-theme/functions.php b/themes/10up-block-theme/functions.php index 6cee7a0..c80db34 100755 --- a/themes/10up-block-theme/functions.php +++ b/themes/10up-block-theme/functions.php @@ -33,5 +33,7 @@ require_once __DIR__ . '/vendor/autoload.php'; +require_once __DIR__ . '/template-tags.php'; + $theme_core = new \TenupBlockTheme\ThemeCore(); $theme_core->setup(); diff --git a/themes/10up-block-theme/template-tags.php b/themes/10up-block-theme/template-tags.php new file mode 100644 index 0000000..7ff24d6 --- /dev/null +++ b/themes/10up-block-theme/template-tags.php @@ -0,0 +1,34 @@ +<?php +/** + * Template Tags + * + * This file contains **only** pure functions that relate to templating. + * + * Rules: + * - Functions in this file **must be pure** (i.e., they must not cause side effects). + * - No hooks, filters, or global state modifications should be added here. + * - If a function has side effects (e.g., enqueuing scripts, modifying post data, adding filters), + * it should be encapsulated within a class in the `src/` directory. + * + * A pure function: + * - Given the same input, it always returns the same output. + * - Does not modify external state (no global variables, no database writes, etc.). + * - Does not rely on WordPress hooks or filters. + * + * Example of an allowed function: + * ```php + * function get_custom_excerpt( string $content, int $length = 50 ): string { + * return wp_trim_words( $content, $length ); + * } + * ``` + * + * Example of a function **that does not belong here**: + * ```php + * function modify_post_title( string $title ): string { + * return 'My Great ' . $title; + * } + * add_filter( 'the_title', 'modify_post_title' ); + * ``` + * + * Keeping this file limited to pure functions ensures maintainability and a clear separation of concerns. + */ diff --git a/themes/10up-theme/functions.php b/themes/10up-theme/functions.php index d1d99cc..877c270 100755 --- a/themes/10up-theme/functions.php +++ b/themes/10up-theme/functions.php @@ -34,5 +34,7 @@ require_once __DIR__ . '/vendor/autoload.php'; +require_once __DIR__ . '/template-tags.php'; + $theme_core = new \TenUpTheme\ThemeCore(); $theme_core->setup(); diff --git a/themes/10up-theme/template-tags.php b/themes/10up-theme/template-tags.php new file mode 100644 index 0000000..7ff24d6 --- /dev/null +++ b/themes/10up-theme/template-tags.php @@ -0,0 +1,34 @@ +<?php +/** + * Template Tags + * + * This file contains **only** pure functions that relate to templating. + * + * Rules: + * - Functions in this file **must be pure** (i.e., they must not cause side effects). + * - No hooks, filters, or global state modifications should be added here. + * - If a function has side effects (e.g., enqueuing scripts, modifying post data, adding filters), + * it should be encapsulated within a class in the `src/` directory. + * + * A pure function: + * - Given the same input, it always returns the same output. + * - Does not modify external state (no global variables, no database writes, etc.). + * - Does not rely on WordPress hooks or filters. + * + * Example of an allowed function: + * ```php + * function get_custom_excerpt( string $content, int $length = 50 ): string { + * return wp_trim_words( $content, $length ); + * } + * ``` + * + * Example of a function **that does not belong here**: + * ```php + * function modify_post_title( string $title ): string { + * return 'My Great ' . $title; + * } + * add_filter( 'the_title', 'modify_post_title' ); + * ``` + * + * Keeping this file limited to pure functions ensures maintainability and a clear separation of concerns. + */ From 14a07de1a70dbe4e1b897dca0d9c4d4a07ca2bdd Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 10:58:56 +0000 Subject: [PATCH 15/17] Add namespaces --- themes/10up-block-theme/template-tags.php | 2 ++ themes/10up-theme/template-tags.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/themes/10up-block-theme/template-tags.php b/themes/10up-block-theme/template-tags.php index 7ff24d6..e0b3824 100644 --- a/themes/10up-block-theme/template-tags.php +++ b/themes/10up-block-theme/template-tags.php @@ -32,3 +32,5 @@ * * Keeping this file limited to pure functions ensures maintainability and a clear separation of concerns. */ + +namespace TenupBlockTheme; diff --git a/themes/10up-theme/template-tags.php b/themes/10up-theme/template-tags.php index 7ff24d6..5cc67ba 100644 --- a/themes/10up-theme/template-tags.php +++ b/themes/10up-theme/template-tags.php @@ -32,3 +32,5 @@ * * Keeping this file limited to pure functions ensures maintainability and a clear separation of concerns. */ + +namespace TenupTheme; From 5ed65f09d7d543fdb676c4856f0659935599e2b8 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 11:08:47 +0000 Subject: [PATCH 16/17] Fix linting issue --- themes/10up-block-theme/template-tags.php | 2 ++ themes/10up-theme/template-tags.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/themes/10up-block-theme/template-tags.php b/themes/10up-block-theme/template-tags.php index e0b3824..b7edca6 100644 --- a/themes/10up-block-theme/template-tags.php +++ b/themes/10up-block-theme/template-tags.php @@ -2,6 +2,8 @@ /** * Template Tags * + * @package TenUpBlockTheme + * * This file contains **only** pure functions that relate to templating. * * Rules: diff --git a/themes/10up-theme/template-tags.php b/themes/10up-theme/template-tags.php index 5cc67ba..87745ed 100644 --- a/themes/10up-theme/template-tags.php +++ b/themes/10up-theme/template-tags.php @@ -2,6 +2,8 @@ /** * Template Tags * + * @package TenUpTheme + * * This file contains **only** pure functions that relate to templating. * * Rules: From c7be1c8c41c81dd5e57f5b909b13ae9760291034 Mon Sep 17 00:00:00 2001 From: Daryll Doyle <daryll.doyle@10up.com> Date: Mon, 17 Feb 2025 11:17:54 +0000 Subject: [PATCH 17/17] Docs update --- docs/registering-classes.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/registering-classes.md b/docs/registering-classes.md index b221dd1..4f5b058 100644 --- a/docs/registering-classes.md +++ b/docs/registering-classes.md @@ -1,8 +1,8 @@ # Registering Classes in the MU-Plugin -The MU-Plugin and the theme utilize a system to uniformly, auto-register classes that lie within their namespaces. Whilst there are a few constraints, it eases the requirements for engineers to add their classes to multiple locations each time they add one to the system. +The MU-Plugin and the themes utilize a system to uniformly, auto-register classes that lie within their namespaces. Whilst there are a few constraints, it eases the requirements for engineers to add their classes to multiple locations each time they add one to the system. -To do this, it uses the [haydenpierce/class-finder](https://packagist.org/packages/haydenpierce/class-finder) package, which reads the `composer.json` file to help locate files that belong in certain namespaces. +To learn more about this, check out the class within TenUpFramework that handles this: [`TenupFramework\ModuleInitialization`](https://github.com/10up/wp-framework/blob/trunk/src/ModuleInitialization.php). ## How do I define a class to be auto-registered? @@ -141,11 +141,11 @@ class SiteSettings implements \TenupFramework\ModuleInterface { The old way of doing this would be to use the `get_plugin_support()` function. As we no longer define and register our classes in the same way, this doesn't work. -The best way now, is to use the `get_module()` function that ships with the plugin and the theme. +The best way now, is to use the `get_module()` static method that ships with the plugin and the theme. ```php -$site_settings = \TenUpPlugin\get_module( '\TenUpPlugin\Admin\SiteSettings' ); -$a_theme_class = \TenUpTheme\get_module( '\TenUpTheme\Some\Theme\Class' ); +$site_settings = \TenUpPlugin\PluginCore::get_module( '\TenUpPlugin\Admin\SiteSettings' ); +$a_theme_class = \TenUpTheme\ThemeCore::get_module( '\TenUpTheme\Some\Theme\Class' ); ``` If it can't find the class, it will return `false`. @@ -156,9 +156,9 @@ One major difference between the old way and the new way is that when calling th By default classes will be loaded in the order they're found. It'd often required to load certain classes before another, for example, loading Taxonomies before Post Types. -To get around this, there is a `$load_order` property available on the `Module` abstract classes. +To get around this, there is a `load_order` method defined in the `ModuleInterface` interface. If you're using the `Module` trait, this is pre-defined for you. -`$load_order` accepts an integer and lets us choose which classes will load first. It has no correlation to the `init` priority to a class, but works in the same way, the lower numbers will load first. +`load_order()` returns an integer and lets us choose which classes will load first. It has no correlation to the `init` priority to a class, but works in the same way, the lower numbers will load first. To see it in action, see below. @@ -172,7 +172,18 @@ class TaxonomyFactory implements \TenupFramework\ModuleInterface { use \TenupFramework\Module; - public $load_order = 9; + /** + * Used to alter the order in which clases are initialized. + * + * Lower number will be initialized first. + * + * @note This has no correlation to the `init` priority. It's just a way to allow certain classes to be initialized before others. + * + * @return int The priority of the module. + */ + public function load_order() { + return 9; + } // Rest of class removed for brevity. }