diff --git a/README.md b/README.md index 13b1c048..82df1b31 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Theme Elementary +![image](https://user-images.githubusercontent.com/59014930/187202051-df015d4a-f885-40cb-9fc9-c13991d3216d.png) + A starter theme that facilitates a quick head start for developing new [block-based themes](https://developer.wordpress.org/block-editor/how-to-guides/themes/block-theme-overview/) along with a bunch of developer-friendly features. - [Understand the Folder Structure](https://github.com/rtCamp/theme-elementary#understand-the-folder-structure-open_file_folder) diff --git a/assets/src/css/core-navigation.scss b/assets/src/css/core-navigation.scss new file mode 100644 index 00000000..34cf0a96 --- /dev/null +++ b/assets/src/css/core-navigation.scss @@ -0,0 +1,3 @@ +/** + * Custom styles required for the core Navigatino block. + */ diff --git a/assets/src/js/core-navigation.js b/assets/src/js/core-navigation.js new file mode 100644 index 00000000..0b470122 --- /dev/null +++ b/assets/src/js/core-navigation.js @@ -0,0 +1,8 @@ +/** + * Custom script required for the core Navigatino block. + */ + +/** + * Internal dependencies + */ +import '../css/core-navigation.scss'; diff --git a/assets/src/js/index.js b/assets/src/js/index.js deleted file mode 100644 index e69de29b..00000000 diff --git a/inc/classes/class-assets.php b/inc/classes/class-assets.php new file mode 100644 index 00000000..895c3e2c --- /dev/null +++ b/inc/classes/class-assets.php @@ -0,0 +1,163 @@ +setup_hooks(); + + } + + /** + * Setup hooks. + * + * @since 1.0.0 + */ + public function setup_hooks() { + add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ] ); + add_filter( 'render_block', [ $this, 'enqueue_block_specific_assets' ], 10, 2 ); + } + + /** + * Register assets. + * + * @since 1.0.0 + * + * @action wp_enqueue_scripts + */ + public function register_assets() { + + $this->register_script( 'core-navigation', 'js/core-navigation.js' ); + $this->register_style( 'core-navigation', 'css/core-navigation.css' ); + } + + /** + * Enqueue block specific assets. + * + * @param string $markup Markup of the block. + * @param array $block Array with block information. + * + * @since 1.0.0 + */ + public function enqueue_block_specific_assets( $markup, $block ) { + if ( is_array( $block ) && ! empty( $block['blockName'] ) && 'core/navigation' === $block['blockName'] ) { + wp_enqueue_script( 'core-navigation' ); + wp_enqueue_style( 'core-navigation' ); + } + + return $markup; + } + + /** + * Get asset dependencies and version info from {handle}.asset.php if exists. + * + * @param string $file File name. + * @param array $deps Script dependencies to merge with. + * @param string $ver Asset version string. + * + * @return array + */ + public function get_asset_meta( $file, $deps = [], $ver = false ) { + $asset_meta_file = sprintf( '%s/js/%s.asset.php', untrailingslashit( ELEMENTARY_THEME_BUILD_DIR ), basename( $file, '.' . pathinfo( $file )['extension'] ) ); + $asset_meta = is_readable( $asset_meta_file ) + ? require $asset_meta_file + : [ + 'dependencies' => [], + 'version' => $this->get_file_version( $file, $ver ), + ]; + + $asset_meta['dependencies'] = array_merge( $deps, $asset_meta['dependencies'] ); + + return $asset_meta; + } + + /** + * Register a new script. + * + * @param string $handle Name of the script. Should be unique. + * @param string|bool $file script file, path of the script relative to the assets/build/ directory. + * @param array $deps Optional. An array of registered script handles this script depends on. Default empty array. + * @param string|bool|null $ver Optional. String specifying script version number, if not set, filetime will be used as version number. + * @param bool $in_footer Optional. Whether to enqueue the script before instead of in the . + * Default 'false'. + * @return bool Whether the script has been registered. True on success, false on failure. + */ + public function register_script( $handle, $file, $deps = [], $ver = false, $in_footer = true ) { + + $file_path = sprintf( '%s/%s', ELEMENTARY_THEME_BUILD_DIR, $file ); + + if ( ! \file_exists( $file_path ) ) { + return false; + } + + $src = sprintf( ELEMENTARY_THEME_BUILD_URI . '/%s', $file ); + $asset_meta = $this->get_asset_meta( $file, $deps ); + + return wp_register_script( $handle, $src, $asset_meta['dependencies'], $asset_meta['version'], $in_footer ); + } + + /** + * Register a CSS stylesheet. + * + * @param string $handle Name of the stylesheet. Should be unique. + * @param string|bool $file style file, path of the script relative to the assets/build/ directory. + * @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array. + * @param string|bool|null $ver Optional. String specifying script version number, if not set, filetime will be used as version number. + * @param string $media Optional. The media for which this stylesheet has been defined. + * Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like + * '(orientation: portrait)' and '(max-width: 640px)'. + * + * @return bool Whether the style has been registered. True on success, false on failure. + */ + public function register_style( $handle, $file, $deps = [], $ver = false, $media = 'all' ) { + + $file_path = sprintf( '%s/%s', ELEMENTARY_THEME_BUILD_DIR, $file ); + + if ( ! \file_exists( $file_path ) ) { + return false; + } + + $src = sprintf( ELEMENTARY_THEME_BUILD_URI . '/%s', $file ); + $asset_meta = $this->get_asset_meta( $file, $deps ); + + return wp_register_style( $handle, $src, $asset_meta['dependencies'], $asset_meta['version'], $media ); + } + + /** + * Get file version. + * + * @param string $file File path. + * @param int|string|boolean $ver File version. + * + * @return bool|false|int + */ + public function get_file_version( $file, $ver = false ) { + if ( ! empty( $ver ) ) { + return $ver; + } + + $file_path = sprintf( '%s/%s', ELEMENTARY_THEME_BUILD_DIR, $file ); + + return file_exists( $file_path ) ? filemtime( $file_path ) : false; + } + +} diff --git a/inc/classes/class-elementary-theme.php b/inc/classes/class-elementary-theme.php index 5aa5887f..03443e74 100644 --- a/inc/classes/class-elementary-theme.php +++ b/inc/classes/class-elementary-theme.php @@ -9,6 +9,7 @@ use Elementary_Theme\Traits\Singleton; use Elementary_Theme\Patterns\Block_Patterns; +use Elementary_Theme\Assets; /** * Class Elementary_Theme @@ -25,6 +26,7 @@ class Elementary_Theme { protected function __construct() { // Instantiate classes. Block_Patterns::get_instance(); + Assets::get_instance(); // Setup hooks. $this->setup_hooks(); @@ -36,7 +38,7 @@ protected function __construct() { * @since 1.0.0 */ public function setup_hooks() { - add_action( 'after_setup_theme', array( $this, 'elementary_theme_support' ) ); + add_action( 'after_setup_theme', [ $this, 'elementary_theme_support' ] ); } /** diff --git a/inc/classes/patterns/class-block-patterns.php b/inc/classes/patterns/class-block-patterns.php index be3308c1..46dea1c7 100644 --- a/inc/classes/patterns/class-block-patterns.php +++ b/inc/classes/patterns/class-block-patterns.php @@ -55,17 +55,17 @@ public function setup_hooks() { * @since 1.0.0 */ public function elementary_theme_register_block_patterns_categories() { - $block_pattern_categories = array( - 'featured' => array( + $block_pattern_categories = [ + 'featured' => [ 'label' => __( 'Featured', 'elementary-theme' ), - ), - 'footer' => array( + ], + 'footer' => [ 'label' => __( 'Footer', 'elementary-theme' ), - ), - 'query' => array( + ], + 'query' => [ 'label' => __( 'Query', 'elementary-theme' ), - ), - ); + ], + ]; /** * Filters the block pattern categories. @@ -87,10 +87,10 @@ public function elementary_theme_register_block_patterns_categories() { * @since 1.0.0 */ public function elementary_theme_register_block_patterns() { - $block_patterns_classes = array( + $block_patterns_classes = [ 'footer' => 'Footer', 'hidden-404' => 'Hidden_404', - ); + ]; /** * Filters the theme block patterns. diff --git a/inc/classes/patterns/content/class-footer.php b/inc/classes/patterns/content/class-footer.php index 80f9afc2..f5e4656f 100644 --- a/inc/classes/patterns/content/class-footer.php +++ b/inc/classes/patterns/content/class-footer.php @@ -22,12 +22,12 @@ final class Footer extends Block_Pattern_Base { * @return array Block pattern properties. */ public function block_pattern() { - return array( + return [ 'title' => __( 'Footer', 'elementary-theme' ), - 'categories' => array( 'footer' ), - 'blockTypes' => array( 'core/template-part/footer' ), + 'categories' => [ 'footer' ], + 'blockTypes' => [ 'core/template-part/footer' ], 'content' => $this->block_pattern_content(), - ); + ]; } /** @@ -36,6 +36,7 @@ public function block_pattern() { * @return string Block pattern content. */ public function block_pattern_content() { + // phpcs:disable WordPressVIPMinimum.Security.Mustache.OutputNotation ob_start(); ?> @@ -57,5 +58,6 @@ public function block_pattern_content() { __( '404 content', 'elementary-theme' ), 'inserter' => false, 'content' => $this->block_pattern_content(), - ); + ]; } /** diff --git a/index.php b/index.php deleted file mode 100644 index 8a649776..00000000 --- a/index.php +++ /dev/null @@ -1,8 +0,0 @@ -=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/argparse": { @@ -1937,9 +1940,9 @@ "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2014,6 +2017,19 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -9877,14 +9893,15 @@ } }, "node_modules/eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.0", + "@eslint/eslintrc": "^1.3.1", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -9894,7 +9911,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -9919,8 +9936,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -10126,19 +10142,19 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "26.8.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", - "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.0.0.tgz", + "integrity": "sha512-z+xyBosph1kSffGEbsDz4EgdzRnpdKzrPHgVtiQ9hcZsTKl8EOo6yLhNn55tGfJSEmJdEVqpXv1g+ZmTbT9rEQ==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -10577,9 +10593,9 @@ } }, "node_modules/espree": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", - "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -25876,14 +25892,14 @@ } }, "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -25899,9 +25915,9 @@ "dev": true }, "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -25956,6 +25972,12 @@ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", "dev": true }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -31946,14 +31968,15 @@ } }, "eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz", - "integrity": "sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.0", + "@eslint/eslintrc": "^1.3.1", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -31963,7 +31986,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.3", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -31988,8 +32011,7 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { "ansi-styles": { @@ -32286,9 +32308,9 @@ } }, "eslint-plugin-jest": { - "version": "26.8.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", - "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.0.0.tgz", + "integrity": "sha512-z+xyBosph1kSffGEbsDz4EgdzRnpdKzrPHgVtiQ9hcZsTKl8EOo6yLhNn55tGfJSEmJdEVqpXv1g+ZmTbT9rEQ==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -32455,9 +32477,9 @@ "dev": true }, "espree": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", - "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { "acorn": "^8.8.0", diff --git a/package.json b/package.json index 27575618..008e6357 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,10 @@ "browserslist": "4.21.3", "cross-env": "7.0.3", "css-minimizer-webpack-plugin": "4.0.0", - "eslint": "8.22.0", + "eslint": "8.23.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.26.0", - "eslint-plugin-jest": "26.8.7", + "eslint-plugin-jest": "27.0.0", "husky": "8.0.1", "jest-silent-reporter": "0.5.0", "lint-staged": "13.0.3", diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 00000000..544a1817 Binary files /dev/null and b/screenshot.png differ diff --git a/webpack.config.js b/webpack.config.js index 2a03e195..59c45890 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -76,15 +76,14 @@ const styles = { }; -/* Example of how to add a new entry point for a JS file. -const exampleJS = { +const scripts = { ...sharedConfig, entry: { - 'example-js': path.resolve(process.cwd(), 'assets', 'src', 'js', 'example.js'), + 'core-navigation': path.resolve( process.cwd(), 'assets', 'src', 'js', 'core-navigation.js' ), }, }; - */ module.exports = [ - styles, // Do not remove this. + scripts, + styles, ];