Files
claude-websimple-devops/references/wp-theme-dev.md

9.1 KiB

WP Theme Dev

Use this skill for general Websimple WordPress theme PHP development conventions.

Do not use this skill for PHPCS tooling setup or formatting commands; use references/wp-code-style.md. Use references/wp-browser.md for visual/frontend checks and references/wp-xdebug.md for runtime PHP debugging.

Scope boundaries

This skill covers:

  • theme PHP file/folder organization;
  • functions.php organization;
  • actions and filters;
  • function naming and namespacing/prefixing;
  • template conventions for regular WordPress themes;
  • comments/docblocks style;
  • escaping, sanitization, translation, and preferred output syntax;
  • safe PHP/theme refactoring workflow.

Defer specialized areas to dedicated skills when they apply:

  • Kaliroots child themes: use/refine the references/wp-kaliroots.md conventions instead of this skill's template guidance.
  • PHPCS/PHPCBF/tooling: use references/wp-code-style.md.
  • ACF architecture/conventions: use references/wp-acf.md.
  • Asset pipeline details, bundler config, and build commands: use references/wp-assets.md.
  • Vue/React/headless conventions beyond source placement: use dedicated skills when available.

Theme structure

Prefer small, discoverable theme files over large catch-all files.

  • Keep all PHP logic under includes/, grouped by category.
  • Keep functions.php as a categorized bootstrap/loader for includes/ files.
  • Use category directories such as includes/admin/, includes/core/, includes/cpt/, includes/taxonomies/, includes/forms/, includes/roles/, includes/schemas/, includes/sections/, includes/shortcodes/, includes/vendors/, includes/widgets/, and includes/woocommerce/ as applicable.
  • Keep helpers/utilities separate from hook callback registration when practical.
  • Use src/ for CSS/SCSS, JavaScript, TypeScript, Vue, React, and similar source assets that are compiled or bundled.
  • Preserve the existing project structure unless the user asks for reorganization.
  • Do not introduce a new architecture into an established theme without approval.

Preferred functions.php pattern: keep it as a categorized loader for files under includes/.

<?php

// Administration
require_once __DIR__ . '/includes/admin/attachment.php';
require_once __DIR__ . '/includes/admin/user.php';

// Core
require_once __DIR__ . '/includes/core/assets.php';
require_once __DIR__ . '/includes/core/helpers.php';
require_once __DIR__ . '/includes/core/theme-setup.php';

// Custom Post Types
require_once __DIR__ . '/includes/cpt/project.php';

// Custom Taxonomies
require_once __DIR__ . '/includes/taxonomies/project-category.php';

// Roles
require_once __DIR__ . '/includes/roles/editor.php';

// Shortcodes
require_once __DIR__ . '/includes/shortcodes/alert.php';

// Vendors
require_once __DIR__ . '/includes/vendors/acf.php';
require_once __DIR__ . '/includes/vendors/gravityforms.php';
require_once __DIR__ . '/includes/vendors/polylang.php';
require_once __DIR__ . '/includes/vendors/tinymce.php';

// Widgets
require_once __DIR__ . '/includes/widgets/contact-info.php';

// WooCommerce
require_once __DIR__ . '/includes/woocommerce/cart.php';
require_once __DIR__ . '/includes/woocommerce/checkout.php';
require_once __DIR__ . '/includes/woocommerce/product.php';

Keep empty category headers when they make the intended structure clearer or match the project convention.

Avoid modifying WordPress core, vendor directories, uploads, caches, compiled assets, or unrelated themes.

Templates and template parts

For themes that are child themes of Kaliroots, do not apply generic template conventions. Refer to references/wp-kaliroots.md instead.

For regular WordPress themes, templates should live under templates/ and be grouped by rendering purpose:

templates/
  html/       # outer high-level templates
  site/       # global site header/footer and site-wide layout parts
  content/    # content-related templates
    loops/    # loop wrappers and loop item templates
  emails/     # outgoing email templates

Each template group may have a partials/ subdirectory for smaller local partials.

Use templates/content/loops/ for loop templates. Prefer paired names where the outer loop and item template share a base name:

templates/content/loops/events.php
templates/content/loops/events-item.php
templates/content/loops/posts.php
templates/content/loops/posts-item.php

Additional conventions:

  • Use WordPress template hierarchy intentionally.
  • Keep template files readable and focused on rendering.
  • Use template parts for repeated markup or meaningful sections.
  • Prefer clear names that describe the rendered section or component.
  • Keep heavy data preparation, custom queries, and complex conditionals out of templates when a helper or setup function would make the template clearer.
  • Keep markup/output close to templates and reusable data/logic close to includes/ helpers/modules.

Do not mass-reorganize template files without explicit approval.

Actions and filters

Register hooks in predictable locations, following the theme's existing organization.

  • Prefer named callbacks over anonymous closures when the callback is reused, non-trivial, or likely to need debugging.
  • Use clear project/theme-prefixed or namespaced callback names.
  • Keep callback names tied to the hook purpose.
  • Avoid hidden side effects in filters unless intentional and documented by context.
  • Preserve important priorities and accepted-argument counts.
  • Document or call out non-obvious hook ordering dependencies.

Example pattern:

// Enqueue theme assets.
add_action( 'wp_enqueue_scripts', 'example_enqueue_assets' );
function example_enqueue_assets(): void {
    wp_enqueue_style(
        'example-theme',
        get_stylesheet_directory_uri() . '/dist/css/theme.css',
        [],
        wp_get_theme()->get( 'Version' )
    );
}

// Add a body class on the front page.
add_filter( 'body_class', 'example_add_body_classes' );
function example_add_body_classes( array $classes ): array {
    if ( is_front_page() ) {
        $classes[] = 'is-front-page';
    }

    return $classes;
}

When refactoring hooks, verify behavior with the smallest meaningful check: WP-CLI, browser smoke test, or Xdebug when needed.

Function naming

Follow the existing theme convention first. When adding new global functions, avoid generic names.

Prefer one of:

  • a theme/project prefix, e.g. example_get_hero_title();
  • a namespace if the theme already uses namespaces;
  • a class/static method only when the theme already uses that style or it genuinely improves organization.

Keep helper names descriptive. Separate hook callbacks from pure/data helpers when it improves readability.

Comments and docblocks

Keep the project's existing commenting style coherent.

Comments may be explicit and simple, including human-readable descriptions of what a function does. Do not remove comments just because they restate the function name if that style is consistent in the project.

Use comments/docblocks to improve scanability and clarify intent, inputs, outputs, side effects, or hook context when useful. Avoid stale, misleading, or decorative comments.

Escaping, sanitization, translation, and output syntax

Escape dynamic values at output time unless WordPress or the data source has already produced safe markup for that exact context.

Common choices:

  • esc_html() for plain text;
  • esc_attr() for attribute values;
  • esc_url() for URLs;
  • wp_kses_post() for trusted post-like HTML;
  • wp_json_encode() for JSON output.

Sanitize input before saving or using it in queries. Use WordPress translation helpers for user-facing theme strings when appropriate.

Prefer compact PHP output tags for template output:

<?= esc_html( $title ); ?>
<?= esc_url( $url ); ?>
<?= wp_kses_post( $content ); ?>

Do not rewrite existing <?php echo ...; ?> output solely for style unless the user asked for cleanup or the surrounding file is already being touched.

Data and query conventions

  • Use core WordPress APIs where possible.
  • Reset post data after custom WP_Query loops.
  • Avoid relying on surprising global state.
  • Avoid expensive queries inside repeated template parts.
  • Add caching only when justified by a concrete performance issue.

Refactoring workflow

  1. Inspect the theme structure, active child/parent theme relationship, and existing conventions.
  2. If the theme is a Kaliroots child theme, defer template decisions to Kaliroots-specific conventions.
  3. Make small coherent changes that preserve behavior unless the user requested redesign.
  4. Avoid mixing formatting-only and behavior changes.
  5. Run lint/style checks via references/wp-code-style.md when PHP files changed.
  6. Use references/wp-browser.md for frontend smoke checks when templates/output changed.
  7. Use references/wp-xdebug.md when runtime behavior is unclear.
  8. Inspect the diff before claiming success.

Safety

  • Do not mass-reorganize a theme without explicit approval.
  • Do not touch core, vendor, uploads, caches, compiled assets, or unrelated themes.
  • Do not silently force conventions when the existing project clearly uses a different coherent pattern; call out the tradeoff.
  • Keep changes reversible and scoped to the user's request.