Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions docs/Asset-Loading.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Asset Loading

## Overview
Use the `TenupFramework\Assets\GetAssetInfo` trait to read dependency and version metadata generated by your build (the `.asset.php` sidecar files). The trait looks for files in:
Use the `TenupFramework\Assets\GetAssetInfo` trait to read dependency and version metadata generated by your build (the `.asset.php` sidecar files). The trait supports two approaches for locating asset files:

### Prefix-based paths (recommended)
When you specify a prefix in the slug, the trait looks for files directly in the corresponding subdirectory:
- `get_asset_info('css/admin')` → `dist/css/admin.asset.php`
- `get_asset_info('js/admin')` → `dist/js/admin.asset.php`
- `get_asset_info('blocks/my-block')` → `dist/blocks/my-block.asset.php`

### Fallback behavior
For slugs without prefixes, the trait searches in this order:
- `dist/js/{slug}.asset.php`
- `dist/css/{slug}.asset.php`
- `dist/blocks/{slug}.asset.php`
Expand Down Expand Up @@ -55,6 +64,19 @@ Notes:
- If your build produces multiple variants (e.g., `admin.js` vs `admin.min.js`), you can conditionally enqueue based on `SCRIPT_DEBUG` or `wp_get_environment_type() === 'development'`.

## Enqueuing scripts

### Using prefix-based paths (recommended)
```php
wp_enqueue_script(
'tenup_plugin_admin',
YOUR_PLUGIN_URL . 'dist/js/admin.js',
$this->get_asset_info( 'js/admin', 'dependencies' ),
$this->get_asset_info( 'js/admin', 'version' ),
true
);
```

### Using fallback behavior
```php
wp_enqueue_script(
'tenup_plugin_admin',
Expand All @@ -68,6 +90,18 @@ wp_enqueue_script(
- version: string used for cache busting

## Enqueuing styles

### Using prefix-based paths (recommended)
```php
wp_enqueue_style(
'tenup_plugin_admin',
YOUR_PLUGIN_URL . 'dist/css/admin.css',
[], // CSS dependencies are uncommon; pass [] unless needed
$this->get_asset_info( 'css/admin', 'version' )
);
```

### Using fallback behavior
```php
wp_enqueue_style(
'tenup_plugin_admin',
Expand All @@ -78,7 +112,17 @@ wp_enqueue_style(
```

## Working with blocks
If you build blocks, pass the block slug used by your build tool:

### Using prefix-based paths (recommended)
```php
$deps = $this->get_asset_info( 'blocks/my-block', 'dependencies' );
$ver = $this->get_asset_info( 'blocks/my-block', 'version' );
$handle = 'tenup_my_block';

wp_register_script( $handle, YOUR_PLUGIN_URL . 'dist/blocks/my-block.js', $deps, $ver, true );
```

### Using fallback behavior
```php
$deps = $this->get_asset_info( 'my-block', 'dependencies' );
$ver = $this->get_asset_info( 'my-block', 'version' );
Expand All @@ -88,6 +132,21 @@ wp_register_script( $handle, YOUR_PLUGIN_URL . 'dist/blocks/my-block.js', $deps,
```
The trait automatically checks `dist/blocks/my-block.asset.php` if present.

## Resolving asset conflicts

When you have JS and CSS assets with the same handle (e.g., both `admin.js` and `admin.css`), use prefix-based paths to avoid conflicts:

```php
// ❌ Problematic: Both would load the same asset data
$this->get_asset_info( 'admin', 'dependencies' ); // Could load JS instead of CSS data if both CSS and JS files exist with the same name.

// ✅ Recommended: Explicitly specify the asset type
$this->get_asset_info( 'js/admin', 'dependencies' ); // Always loads JS asset data
$this->get_asset_info( 'css/admin', 'dependencies' ); // Always loads CSS asset data
```

This ensures that each asset type gets its correct dependencies and version information.

## Error handling and fallbacks
```php
try {
Expand All @@ -105,6 +164,8 @@ try {
- Keep your dist path stable across environments (use constants for PATH and URL).
- Use the version from `.asset.php` for reliable cache busting in production.
- For admin-only assets, enqueue on `admin_enqueue_scripts`; for frontend, use `wp_enqueue_scripts`.
- **Use prefix-based paths** (`'js/admin'`, `'css/admin'`, `'blocks/my-block'`) to avoid conflicts when you have assets with the same handle across different types.
- Prefix-based paths are **backwards compatible** - existing code using fallback behavior will continue to work.

## See also
- [Docs Home](README.md)
Expand Down
1 change: 1 addition & 0 deletions fixtures/assets/dist/blocks/test-block.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array( 'test-block-deps' ), 'version' => 'test-block-version');
4 changes: 3 additions & 1 deletion src/Assets/GetAssetInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ public function get_asset_info( string $slug, ?string $attribute = null ): strin
throw new RuntimeException( 'Asset variables not set. Please run setup_asset_vars() before calling get_asset_info().' );
}

if ( file_exists( $this->dist_path . 'js/' . $slug . '.asset.php' ) ) {
if ( file_exists( $this->dist_path . $slug . '.asset.php' ) ) {
$asset = require $this->dist_path . $slug . '.asset.php';
} elseif ( file_exists( $this->dist_path . 'js/' . $slug . '.asset.php' ) ) {
$asset = require $this->dist_path . 'js/' . $slug . '.asset.php';
} elseif ( file_exists( $this->dist_path . 'css/' . $slug . '.asset.php' ) ) {
$asset = require $this->dist_path . 'css/' . $slug . '.asset.php';
Expand Down
113 changes: 113 additions & 0 deletions tests/Assets/GetAssetInfoTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,117 @@ public function test_get_asset_info_throws_exception_when_called_without_setting
slug: 'test-script'
);
}

/**
* Test get_asset_info with prefix-based slug handling (css/, js/, blocks/).
*
* @return void
*/
public function test_get_asset_info_with_prefix_based_slug() {
$asset_info = new class() {
use GetAssetInfo;
};

$asset_info->setup_asset_vars(
dist_path: dirname( __DIR__, 2 ) . '/fixtures/assets/dist',
fallback_version: '1.0.0'
);

// Test CSS prefix with existing fixture
$asset = $asset_info->get_asset_info( slug: 'css/test-style' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/css/test-style.asset.php';
$this->assertEquals( $vars, $asset );

// Test JS prefix with existing fixture
$asset = $asset_info->get_asset_info( slug: 'js/test-script' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/js/test-script.asset.php';
$this->assertEquals( $vars, $asset );

// Test blocks prefix with existing fixture
$asset = $asset_info->get_asset_info( slug: 'blocks/test-block' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/blocks/test-block.asset.php';
$this->assertEquals( $vars, $asset );
}

/**
* Test get_asset_info priority order: prefix-based slugs take priority over fallback.
*
* @return void
*/
public function test_get_asset_info_priority_order_prefix_vs_fallback() {
$asset_info = new class() {
use GetAssetInfo;
};

$asset_info->setup_asset_vars(
dist_path: dirname( __DIR__, 2 ) . '/fixtures/assets/dist',
fallback_version: '1.0.0'
);

// Test that prefix-based slug works with existing fixtures
$asset = $asset_info->get_asset_info( slug: 'css/test-style' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/css/test-style.asset.php';
$this->assertEquals( $vars, $asset );

// Test that fallback still works for non-prefixed slugs
$asset = $asset_info->get_asset_info( slug: 'test-script' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/js/test-script.asset.php';
$this->assertEquals( $vars, $asset );
}

/**
* Test get_asset_info fallback behavior when direct file doesn't exist.
*
* @return void
*/
public function test_get_asset_info_fallback_when_direct_file_missing() {
$asset_info = new class() {
use GetAssetInfo;
};

$asset_info->setup_asset_vars(
dist_path: dirname( __DIR__, 2 ) . '/fixtures/assets/dist',
fallback_version: '1.0.0'
);

// Test that it falls back to JS directory first (priority order: js -> css -> blocks)
// Using existing fixture that exists in js/ directory
$asset = $asset_info->get_asset_info( slug: 'test-script' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/js/test-script.asset.php';
$this->assertEquals( $vars, $asset );

// Test CSS fallback with existing fixture
$asset = $asset_info->get_asset_info( slug: 'test-style' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/css/test-style.asset.php';
$this->assertEquals( $vars, $asset );

// Test blocks fallback with existing fixture
$asset = $asset_info->get_asset_info( slug: 'test-block' );
$this->assertIsArray( $asset );
$this->assertArrayHasKey( 'version', $asset );
$this->assertArrayHasKey( 'dependencies', $asset );
$vars = require dirname( __DIR__, 2 ) . '/fixtures/assets/dist/blocks/test-block.asset.php';
$this->assertEquals( $vars, $asset );
}
}