Classic theme assets build
Skill Lonsdale201/wp-agent-skills/theme-development/classic-theme-assets-build
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill classic-theme-assets-buildAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build or audit frontend asset loading for classic PHP WordPress themes on WP 7.0. Covers `wp_enqueue_scripts`, child-theme-safe `get_theme_file_uri()` and `get_theme_file_path()`, cache-busting with `filemtime()`, script args with `strategy` and `in_footer`, conditional enqueues, `comment-reply`, RTL style data, inline data with `wp_json_encode()` and `wp_add_inline_script()`, build output folders, preload/resource hints, and common mistakes such as hardcoded tags, enqueues inside templates, and invalid file paths.
SKILL.md
8.1 KB, as published. Nobody here has run it
Classic Theme Assets and Build Output
Use this when adding or reviewing CSS, JavaScript, fonts, images, build artifacts, cache busting, or conditional frontend assets in a classic PHP theme.
This skill is for the frontend theme layer. Admin, editor, and block-specific asset loading are separate concerns.
When to Use This Skill
- Adding
assets/css/*.css,assets/js/*.js, build output, or a bundler manifest. - Replacing hardcoded
<link>or<script>tags inheader.phporfooter.php. - Adding conditional CSS/JS for navigation, comments, templates, sliders, galleries, maps, or page-specific UI.
- Reviewing cache busting, defer/async, RTL styles, inline data, or asset paths in a classic theme.
Hook and Path Rules
Frontend theme assets load on wp_enqueue_scripts.
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
function mytheme_enqueue_assets() {
$theme = wp_get_theme();
wp_enqueue_style(
'mytheme-style',
get_stylesheet_uri(),
array(),
$theme->get( 'Version' )
);
}
Rules:
- Use
wp_enqueue_scriptsfor public frontend CSS/JS. - Use
admin_enqueue_scriptsonly for admin screens. - Use
customize_controls_enqueue_scriptsandcustomize_preview_initfor Customizer-specific assets. - Use
get_theme_file_uri()andget_theme_file_path()for theme files that may be overridden by a child theme. - Use
get_stylesheet_uri()for the active theme's rootstyle.css. - Do not hardcode theme URLs or filesystem paths.
- Do not enqueue assets inside
header.php,footer.php, template parts, or loops.
Cache Busting
Use filemtime() for local built files when the file exists. Fall back to the theme version.
function mytheme_asset_version( $relative_path ) {
$path = get_theme_file_path( $relative_path );
if ( file_exists( $path ) ) {
return (string) filemtime( $path );
}
return wp_get_theme()->get( 'Version' );
}
Example:
wp_enqueue_style(
'mytheme-main',
get_theme_file_uri( 'assets/css/main.css' ),
array(),
mytheme_asset_version( 'assets/css/main.css' )
);
Rules:
- Call
filemtime()on filesystem paths, never URLs. - Keep version values deterministic. Do not use
time()for production cache busting. - If a bundler writes a manifest, parse it once and fail gracefully when an entry is missing.
JavaScript Loading
WP 7.0 supports the modern $args array for wp_enqueue_script().
wp_enqueue_script(
'mytheme-navigation',
get_theme_file_uri( 'assets/js/navigation.js' ),
array(),
mytheme_asset_version( 'assets/js/navigation.js' ),
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
Rules:
- Use
strategy => 'defer'when the script does not need to block parsing. - Use
strategy => 'async'only for scripts that are order-independent. - Keep dependencies accurate. WordPress may adjust strategies to preserve dependency order.
- Prefer small, focused frontend scripts over one global file that runs on every page.
- Do not pass the old boolean footer parameter in new code unless maintaining legacy style.
Inline Data
Use wp_add_inline_script() for boot data and encode PHP data with wp_json_encode().
$data = array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'mytheme_public_action' ),
);
wp_add_inline_script(
'mytheme-navigation',
'window.MyTheme = ' . wp_json_encode( $data ) . ';',
'before'
);
Rules:
- Do not include
<script>tags inwp_add_inline_script(); core strips/warns about them. - Do not use
wp_localize_script()for arbitrary config objects. Use it for translation-style localization. - Do not expose privileged data or long-lived secrets to frontend JavaScript.
- Any nonce exposed to the frontend must still be paired with capability checks server-side where permissions matter.
Conditional Enqueues
Load assets only where they are needed.
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
if ( is_page_template( 'page-templates/landing.php' ) ) {
wp_enqueue_style(
'mytheme-landing',
get_theme_file_uri( 'assets/css/landing.css' ),
array( 'mytheme-main' ),
mytheme_asset_version( 'assets/css/landing.css' )
);
}
Good gating signals:
is_singular(),is_archive(),is_search(),is_front_page(),is_home().is_page_template( 'page-templates/example.php' ).has_nav_menu( 'primary' )for navigation behavior.comments_open()andget_option( 'thread_comments' )forcomment-reply.
Avoid running expensive queries just to decide whether to enqueue a file.
RTL, Preload, and Resource Hints
If the theme ships an RTL replacement stylesheet, register it with style data:
wp_style_add_data( 'mytheme-main', 'rtl', 'replace' );
Use resource hints sparingly:
wp_resource_hintscan add DNS-prefetch/preconnect URLs.wp_preload_resourcescan add preload links for critical resources.- Do not preload everything. Preload only resources needed very early.
For fonts:
- Prefer self-hosted fonts when licensing allows.
- Declare
font-displaydeliberately. - Avoid loading multiple remote font families and weights by default.
Build Output Layout
A practical classic theme layout:
mytheme/
|-- assets/
| |-- src/
| | |-- js/
| | `-- css/
| |-- css/
| | `-- main.css
| |-- js/
| | `-- navigation.js
| `-- manifest.json
Rules:
- Public files enqueued by WordPress must exist in predictable paths.
- Source files may live under
assets/src/, but templates should reference built public files. - Do not require Node, Vite, webpack, or npm at runtime.
- Keep source maps out of production packages unless the project explicitly allows them.
Review Checklist
- Frontend assets are hooked to
wp_enqueue_scripts. - No hardcoded asset tags in
header.php/footer.php. - Handles are unique and prefixed with the theme slug.
- Local asset versions use
filemtime()on paths or the theme version. - Script dependencies and loading strategy are explicit.
comment-replyloads only when needed.- RTL style data is registered when RTL files exist.
- Inline data uses
wp_json_encode()andwp_add_inline_script(). - Conditional enqueues do not run heavy database work.
- Build output paths exist and are child-theme-safe when override support is intended.
Common Mistakes
filemtime( get_theme_file_uri( ... ) ), which passes a URL to a filesystem function.- Adding
<script>insidewp_add_inline_script(). - Enqueueing every page-specific asset globally.
- Using
time()as a version in production. - Loading
comment-replyon every page. - Forgetting that
get_template_directory_uri()always points to the parent theme. - Breaking child theme overrides by using parent-only path helpers for overridable files.
References
- Official documentation: https://developer.wordpress.org/themes/core-concepts/including-assets/
- Official documentation: https://developer.wordpress.org/reference/hooks/wp_enqueue_scripts/
- Verified source paths:
wp-includes/script-loader.phpwp-includes/functions.wp-scripts.phpwp-includes/functions.wp-styles.phpwp-includes/class-wp-scripts.phpwp-includes/class-wp-styles.phpwp-includes/link-template.phpwp-includes/general-template.phpwp-content/themes/storefront/inc/class-storefront.phpwp-content/themes/generatepress/inc/general.php