Skip to content

Theme Development

Building WordPress themes with the Wikit framework, modern build tools, and best practices.

Quick Start

bash
# Create new Wikit-based theme
wdg theme create my-site custom-theme

# Start development server
wdg theme dev my-site custom-theme

# Build for production
wdg theme build my-site custom-theme

Theme Structure

custom-theme/
├── style.css              # Theme header (required)
├── functions.php          # Theme functions
├── index.php              # Main template
├── header.php             # Site header
├── footer.php             # Site footer
├── sidebar.php            # Sidebar template
├── inc/                   # PHP includes
│   ├── blocks/           # Block registrations
│   ├── patterns/         # Block patterns
│   ├── post-types/       # Custom post types
│   └── utilities/        # Helper functions
├── templates/             # Block templates
│   ├── single.php
│   ├── archive.php
│   └── page.php
├── parts/                 # Template parts
│   ├── content.php
│   ├── content-single.php
│   └── navigation.php
├── assets/                # Source files
│   ├── js/
│   │   ├── main.js
│   │   └── editor.js
│   ├── scss/
│   │   ├── style.scss
│   │   └── editor.scss
│   └── images/
├── dist/                  # Compiled assets
│   ├── main.js
│   └── style.css
├── package.json           # Node dependencies
├── webpack.config.js      # Build configuration
└── screenshot.png         # Theme screenshot

Theme Header (style.css)

css
/*
Theme Name: Custom Theme
Theme URI: https://example.com
Author: WDG Development Team
Author URI: https://wdg.com
Description: Custom WordPress theme built on Wikit framework
Version: 1.0.0
License: Proprietary
License URI: #
Text Domain: custom-theme
*/

functions.php

php
<?php
/**
 * Custom Theme Functions
 *
 * @package CustomTheme
 */

// Wikit framework
require_once get_template_directory() . '/inc/wikit-setup.php';

// Theme setup
function custom_theme_setup() {
    // Add theme support
    add_theme_support('title-tag');
    add_theme_support('post-thumbnails');
    add_theme_support('html5', ['search-form', 'comment-form', 'gallery', 'caption']);
    add_theme_support('custom-logo');

    // Register menus
    register_nav_menus([
        'primary' => __('Primary Menu', 'custom-theme'),
        'footer' => __('Footer Menu', 'custom-theme')
    ]);

    // Add image sizes
    add_image_size('hero', 1920, 1080, true);
    add_image_size('thumbnail-large', 600, 400, true);
}
add_action('after_setup_theme', 'custom_theme_setup');

// Enqueue assets
function custom_theme_scripts() {
    // Styles
    wp_enqueue_style(
        'custom-theme-style',
        get_template_directory_uri() . '/dist/style.css',
        [],
        wp_get_theme()->get('Version')
    );

    // Scripts
    wp_enqueue_script(
        'custom-theme-script',
        get_template_directory_uri() . '/dist/main.js',
        ['jquery'],
        wp_get_theme()->get('Version'),
        true
    );

    // Localize script
    wp_localize_script('custom-theme-script', 'themeData', [
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('custom-theme-nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'custom_theme_scripts');

// Include custom functionality
require_once get_template_directory() . '/inc/post-types/portfolio.php';
require_once get_template_directory() . '/inc/blocks/custom-blocks.php';
require_once get_template_directory() . '/inc/utilities/helpers.php';

Development Workflow

1. Start Development Mode

bash
wdg theme dev my-site custom-theme

This runs npm start which:

  • Watches for file changes
  • Compiles SCSS to CSS
  • Bundles JavaScript
  • Enables hot module replacement
  • Generates source maps

2. Make Changes

Edit source files in assets/:

  • assets/js/ - JavaScript files
  • assets/scss/ - Sass stylesheets
  • assets/images/ - Images

Changes auto-rebuild and reload in browser.

3. Build for Production

bash
wdg theme build my-site custom-theme

Creates optimized production assets:

  • Minified CSS
  • Uglified JavaScript
  • Optimized images
  • No source maps

Asset Management

JavaScript

javascript
// assets/js/main.js
import $ from 'jquery';
import Navigation from './components/navigation';
import Slider from './components/slider';

// Initialize on DOM ready
$(document).ready(() => {
    new Navigation();
    new Slider('.hero-slider');
});

// Export for global access if needed
window.CustomTheme = { Navigation, Slider };

Sass/SCSS

scss
// assets/scss/style.scss
@import 'variables';
@import 'mixins';
@import 'base/reset';
@import 'base/typography';
@import 'layout/header';
@import 'layout/footer';
@import 'components/buttons';
@import 'blocks/hero';
@import 'blocks/testimonials';

// Global styles
body {
    font-family: $font-primary;
    color: $color-text;
    background: $color-bg;
}

Block Templates

Template Parts

php
<!-- parts/content.php -->
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php the_title('<h2 class="entry-title">', '</h2>'); ?>
    </header>

    <div class="entry-content">
        <?php the_content(); ?>
    </div>

    <footer class="entry-footer">
        <?php edit_post_link('Edit', '<span class="edit-link">', '</span>'); ?>
    </footer>
</article>

Full Site Editing (Block Themes)

html
<!-- templates/index.html -->
<!-- wp:template-part {"slug":"header"} /-->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
    <!-- wp:query -->
    <div class="wp-block-query">
        <!-- wp:post-template -->
            <!-- wp:post-title {"isLink":true} /-->
            <!-- wp:post-excerpt /-->
        <!-- /wp:post-template -->
    </div>
    <!-- /wp:query -->
</div>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer"} /-->

Custom Blocks

Register Custom Block

php
// inc/blocks/custom-blocks.php
function register_custom_blocks() {
    register_block_type(__DIR__ . '/../blocks/testimonial', [
        'render_callback' => 'render_testimonial_block'
    ]);
}
add_action('init', 'register_custom_blocks');

function render_testimonial_block($attributes) {
    $quote = $attributes['quote'] ?? '';
    $author = $attributes['author'] ?? '';

    ob_start();
    ?>
    <blockquote class="testimonial">
        <p class="testimonial__quote"><?php echo esc_html($quote); ?></p>
        <cite class="testimonial__author"><?php echo esc_html($author); ?></cite>
    </blockquote>
    <?php
    return ob_get_clean();
}

Testing

Linting

bash
# PHP linting with PHPCS
wdg theme lint my-site custom-theme

# Fix automatically
wdg theme lint my-site custom-theme --fix

Browser Testing

bash
# Test in different browsers using Chrome DevTools MCP
# Start browser automation
wdg browser test my-site

Deployment

Package Theme

bash
wdg theme package my-site custom-theme

Creates custom-theme-1.0.0.zip with:

  • Production-ready code
  • Compiled assets
  • No development files

Deploy to Server

bash
# Manual upload via WP Admin or:
wdg theme deploy my-site custom-theme production

Best Practices

  1. Use Wikit Blocks - Leverage existing blocks before creating custom
  2. Mobile-First - Design for mobile, enhance for desktop
  3. Accessibility - Follow WCAG guidelines
  4. Performance - Optimize images, lazy load, minimize JS
  5. Security - Escape output, sanitize input, use nonces

See Also:

Released under the MIT License.