Skip to content

Commit

Permalink
Merge pull request #31 from BlackbirdDigital/feature/asset-registrati…
Browse files Browse the repository at this point in the history
…on-utils

Feature/asset registration utils
  • Loading branch information
cr0ybot committed May 11, 2022
2 parents e8a468e + 817cb4a commit d4e3d42
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 46 deletions.
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,33 @@ In this scaffold, we make use of the `settings.custom` property to define all of

The `inc` folder houses the majority of the PHP files for the theme outside of the standard template hierarchy files.

#### Components: /inc/components
### Components: /components

Templates that are meant to be self-contained and composable. Insert them with `get_component()`.
Templates that are meant to be self-contained (not using contextual functions/template tags) and composable. Insert them with `ThemeScaffold\Utilities\get_component()`.

#### Modules: /inc/modules
See the [Components README](./components/README.md) for more information.

More "traditional" theme scaffolds might have called this the "template-parts" folder. Insert them with `get_module()`.
### Template Parts: /template-parts

Template parts for building page and post templates modularly. Unlike Components, these should make full use of contextual functions/template tags. The scaffolding includes a starting point for organizing these into subfolders.

*See the file header of all of the templates below for more info.*

#### Content: /template-parts/content

These files are explicitly for outputting content for posts, pages, and custom post types. They are named according to their role:

- `entry.php`: For any post type that can by syndicated, meaning timestamped with author information. Create variations for different post types.
- `page.php`: Not just for actual pages, but also any post type that is not syndicated, meaning not timestamped with author information and thus not compatible with an RSS-type feed. Create variations for different post types.
- `excerpt.php`: For displaying a summary of a post meant to link to the content. Create variations for different styles of excerpt.

#### Loop: /template-parts/loop

These files are for outputting content in a classic `WP_Query` loop. Generally they are used on archive pages, but can also be used for template parts that display a list of recent posts, for example.

#### Site: /template-parts/site

These files make up the modular components of the site structure.

### Source Files: /src

Expand All @@ -62,7 +82,9 @@ For a brief intro to the basic foundation of our scaffold styling system, see th

There is a nod to SMACSS in our approach, but it is altered/extended for the WordPress theme context and ease-of-use. Most of the partial files throughout the folder structure are imported automatically without you having to remember to import them into an entrypoint file every time. This means that some ideas from SMACSS are bent or extended in order for automatic imports to work within the cascade.

An important point to note is that there is a `context` tool available that allows you to manage what styles are output in the main stylesheet vs the editor stylesheet. See the [tools/_context.scss](src/styles/tools/_context.scss) file for usage information.
Please be aware that this scaffolding makes use of the latest features of Sass, particularly [Sass modules](https://sass-lang.com/blog/the-module-system-is-launched). Various tools are available that you muse `@use` in order to import into the current file's context, and they are namespaced to avoid global context pollution.

An important tool you should familiarize yourself with is the `context` tool that allows you to manage what styles are output in the main stylesheet vs the editor stylesheet. See the [tools/_context.scss](src/styles/tools/_context.scss) file for usage information.

The folders in import order:

Expand All @@ -82,6 +104,8 @@ Utility classes, which SMACSS doesn't really account for, are generally classes

These are our main BEM component class files. Each module file should be named the same as the "block" (from BEM's **Block**-Element-Modifier) so that when you need to update a module it is easy to find the file it resides in.

*Note that many of these files correspond to the structure of the `template-parts` folder.*

**4. Blocks**

Here is where there is an exception made to the standard concept of modules: Gutenberg blocks. Custom block styles should be added to the `blocks` subfolder and named with their block name (minus the namespace). There is a subfolder in `blocks` for core blocks to distinguish them from custom blocks.
Expand Down
30 changes: 15 additions & 15 deletions inc/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace ThemeScaffold\Setup;

use function ThemeScaffold\Utilities\register_script;
use function ThemeScaffold\Utilities\register_style;

/**
* Sets up theme defaults and registers support for various WordPress features.
*
Expand Down Expand Up @@ -35,16 +38,16 @@ function setup() {
add_theme_support( 'title-tag' );

/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );

/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
Expand Down Expand Up @@ -146,13 +149,11 @@ function register_assets() {
* Enqueue scripts and styles.
*/
function enqueue_assets() {
$style_asset = require get_template_directory() . '/dist/css/style.asset.php';
wp_enqueue_style( 'theme-scaffold-style', get_template_directory_uri() . '/dist/css/style.css', array(), $style_asset['version'] );
wp_enqueue_style( 'google-fonts' );

$themejs_asset = require get_template_directory() . '/dist/js/theme.asset.php';
wp_enqueue_script( 'theme-scaffold-script', get_template_directory_uri() . '/dist/js/theme.js', array(), $themejs_asset['version'], true );
register_style( 'style', true );

wp_enqueue_style( 'google-fonts' );
register_script( 'theme', true );

if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
Expand All @@ -166,10 +167,9 @@ function enqueue_assets() {
* Note: individual blocks from /src/blocks are enqueued automatically by /inc/blocks.php.
*/
function editor_assets() {
$editorjs_asset = require get_template_directory() . '/dist/js/editor.asset.php';
wp_enqueue_script( 'blackbird-blocks', get_template_directory_uri() . '/dist/js/editor.js', $editorjs_asset['dependencies'], $editorjs_asset['version'], true );

wp_enqueue_style( 'google-fonts' );

register_script( 'editor', true );
}
add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\editor_assets' );

Expand Down
103 changes: 77 additions & 26 deletions inc/utilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@

namespace ThemeScaffold\Utilities;

/**
* Return a subset of an array based on an array of keys.
*
* @param array $array Array to subset.
* @param string[] $keys Array of keys to pull from $array.
*/
function array_subset( $array = array(), $keys = array() ) {
return array_intersect_key( $array, array_flip( $keys ) );
}

/**
* Output attributes for an HTML tag from an array of key => value pairs.
*
* @param array $array Array of key => vaue pairs.
*/
function attributes_from_array( $array ) {
$atts = array_reduce(
array_keys( $array ),
function( $acc, $key ) use ( $array ) {
$value = $array[ $key ];
// Skip null values.
if ( $value === null ) {
return $acc;
}
// Transform boolean to string.
if ( is_bool( $value ) ) {
$value = $value ? 'true' : 'false';
}
$acc[] = esc_html( $key ) . '="' . esc_attr( $array[ $key ] ) . '"';
return $acc;
},
array()
);

echo join( ' ', $atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}

/**
* Print a variable inside a <pre> tag with `print_r()`.
* Only outputs if WP_DEBUG = true.
Expand All @@ -26,6 +63,15 @@ function debug( $var ) {
}
}

/**
* Get a script or style asset handle for registration/enqueuing.
*
* @param string $name Asset file name without extension.
*/
function get_asset_handle( string $name ) {
return 'theme-scaffold-' . $name;
}

/**
* Output a template from the components folder using `get_template_part()`.
*
Expand All @@ -40,38 +86,43 @@ function get_component( $name, $args = array() ) {
}

/**
* Return a subset of an array based on an array of keys.
* Enqueue a script asset.
*
* @param array $array Array to subset.
* @param string[] $keys Array of keys to pull from $array.
* @param string $name File name without extension.
* @param boolean $enqueue Optional. Whether to enqueue the asset.
* Default false.
* @param array $dependencies Optional. Additional dependencies to include,
* aside from any found in the asset file.
* @param boolean $footer Optional. Whether to enqueue in the footer.
* Default true.
*/
function array_subset( $array = array(), $keys = array() ) {
return array_intersect_key( $array, array_flip( $keys ) );
function register_script( string $name, bool $enqueue = false, array $dependencies = array(), bool $footer = true ) {
$asset = require get_template_directory() . '/dist/js/' . $name . '.asset.php';
$handle = get_asset_handle( $name );

wp_register_script( $handle, get_template_directory_uri() . '/dist/js/' . $name . '.js', array_merge( $asset['dependencies'], $dependencies ), $asset['version'], $footer );

if ( $enqueue ) {
wp_enqueue_script( $handle );
}
}

/**
* Output attributes for an HTML tag from an array of key => value pairs.
* Enqueue a style asset.
*
* @param array $array Array of key => vaue pairs.
* @param string $name File name without extension.
* @param boolean $enqueue Optional. Whether to enqueue the asset.
* Default false.
* @param array $dependencies Optional. Additional dependencies to include,
* aside from any found in the asset file.
*/
function attributes_from_array( $array ) {
$atts = array_reduce(
array_keys( $array ),
function( $acc, $key ) use ( $array ) {
$value = $array[ $key ];
// Skip null values.
if ( $value === null ) {
return $acc;
}
// Transform boolean to string.
if ( is_bool( $value ) ) {
$value = $value ? 'true' : 'false';
}
$acc[] = esc_html( $key ) . '="' . esc_attr( $array[ $key ] ) . '"';
return $acc;
},
array()
);
function register_style( string $name, bool $enqueue = false, array $dependencies = array() ) {
$asset = require get_template_directory() . '/dist/css/' . $name . '.asset.php';
$handle = get_asset_handle( $name );

echo join( ' ', $atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
wp_register_style( $handle, get_template_directory_uri() . '/dist/css/' . $name . '.css', array_merge( $asset['dependencies'], $dependencies ), $asset['version'] );

if ( $enqueue ) {
wp_enqueue_style( $handle );
}
}

0 comments on commit d4e3d42

Please sign in to comment.