WP-Battery is a WordPress MU-Plugin that makes WordPress theme development easier. It combines Advanced Custom Fields Pro, Timber, and WordPress Block Editor into one simple setup tool. The plugin handles common theme tasks through file-based configuration and a simple API, reducing boilerplate code and speeding up development.
Blocks, pages, menus and options can be added following simple conventions. Adding them is even easier and fastest with our recommended companion Plugin: WP-Battery CLI
- Twig Templates:
-
ACF Pro Blocks:
- Create your own ACF Pro Blocks easily
- optionally: disable core-blocks and limit yourself to your own ACF Pro Blocks
-
Supercharging ACF:
- Automatically synchronize all ACF Pro field groups you create into your theme directory
-
Menus and Option Pages:
- Automatic registration of WP menus and ACF Pro Options Pages
- Simple file-based configuration
-
Custom Post Type and Taxonomy Registration:
- Register your custom post types and taxonomies from separate configuration files
- Simplified registration based on structure and convention
-
Enable Vite.js for your WordPress frontend:
- WP-Battery is ready for Vite-Asset-Collector-WP
-
Asset Management:
- Separate frontend and admin CSS/JS inclusion
- Option to include block specific CSS/JS
- Theme Support Management: Easily enable WordPress theme features
-
WordPress Cleanup: Don't copy-paste the same snippets into your functions.php over and over. WP-Battery can:
- Add theme support
- Remove comments
- Enable SVG uploads
- ... and much more in the future
-
Contact Form 7 Integration:
- Custom file-based template support
- WordPress >= 6.5
- PHP 8.0+
- Timber >= 2.0
- Advanced Custom Fields PRO >= 6.3
- Contact Form 7
In a WordPress composer based setup with Bedrock, this plugin will be automatically symlinked into your web/app/mu-plugins directory, and become available in your WP.
composer require larsgowebdev/wp-battery
Create a new instance of WP-Battery in your theme's functions.php
Initialize the plugin in your theme's functions.php
:
$wpBattery = new WPBattery(
themeNamespace: 'your-theme-name',
settings: [
// Your configuration here
]
);
💡 Development Tip
Consider using WP-Battery CLI to automate the creation of components and folder structure:wp init-wpb # Creates the full directory structure wp create-wpb-block # Creates new blocks wp create-wpb-page # Creates page templates wp create-wpb-menu # Creates menu configurations wp create-wpb-options # Creates options pages
Start by creating a wpb
folder in your theme directory. This folder will contain all your templates, blocks, and configurations.
wpb/
├── acf-sync/ # ACF field group JSON files
├── blocks/ # Block templates and renderers
├── cf7-templates/ # Contact Form 7 templates
├── menus/ # Menu configurations
├── options/ # ACF options pages
├── pages/ # Page templates
└── template-parts/ # Reusable template parts
💡 Quick Start (recommended)
Initialize this entire structure automatically:wp init-wpb
💡 Quick Start (recommended)
Create blocks quickly using WP-Battery CLI:wp create-wpb-block --name=project-info --title="Project Info"
If you need to add or modify blocks manually or just want to dig deeper:
- Create a folder
blocks
in yourwpb
directory - For each block, create a new folder (e.g.,
project-info
) - Add required files:
{
"name": "acf/project-info",
"title": "Project Info",
"description": "Project Info",
"category": "common",
"icon": "visibility",
"keywords": ["project-info"],
"acf": {
"mode": "preview",
"renderCallback": ["Larsgowebdev\\WPBattery\\Renderer\\BlockRenderer", "renderACFBlock"]
}
}
Create project-info-block-template.twig
:
{% block content %}
<!-- put your template content here -->
{% endblock %}
Create project-info-block-renderer.php
if you need additional data processing:
<?php
function render_project_info($context)
{
$context['foo'] = 'bar';
return $context;
}
// You can have multiple render functions - they'll be executed in order
function render_project_info_additional($context)
{
$context['foo2'] = 'bar2';
return $context;
}
$context will be made available in your block's twig template
By Default, your block twig template will have the following variables available:
- field: All of the ACF field data
- attributes, previewFieldObjects: (ACF) Block metadata, can be used for a customized editor preview.
- isPreview: true when rendering the block preview in the editor, can be used for a customized editor preview. Irrelevant for frontend rendering.
💡 Quick Start (recommended)
Create page templates easily using WP-Battery CLI:wp create-wpb-page --name=standard
If you need to add or modify pages manually or just want to dig deeper:
- Create a folder
pages
in yourwpb
directory - For each template type, create a new folder (e.g.,
standard
) - Add required files:
Create standard-page-template.twig
:
<!doctype html>
<html {{ site.language_attributes }}>
<title>{{ wp_title }} | {{ site.name }}</title>
{{ function('wp_head') }}
<body class="{{ body_class }}">
{% block header %}
{% include 'pages/header.twig' %}
{% endblock %}
{% block content %}
{{post.content}}
{% endblock %}
{% block footer %}
{% include 'pages/footer.twig' %}
{% endblock %}
{{ function('wp_footer') }}
</body>
</html>
Create standard-page-renderer.php
if you need additional data processing:
<?php
function render_standard($context)
{
$context['foo'] = 'bar';
return $context;
}
// You can have multiple render functions - they'll be executed in order
function render_standard2($context)
{
$context['foo2'] = 'bar2';
return $context;
}
$context will be made available in your page's twig template
By Default, your page twig template will have the following variables available:
- post: The Post object of the current page
- options: Custom values from options pages
- menus: Array of all menus that you registered (see below).
- fields: ACF fields attached to this page (see get_fields())
💡 Quick Start (recommended)
Create menu configurations quickly using WP-Battery CLI:wp create-wpb-menu --name=main
If you need to add or modify menus manually or just want to dig deeper:
- Create a folder
menus
in yourwpb
directory - Add PHP files for each menu configuration:
Menu configuration files return an associative array defining the menu structure:
- the menu name/ identifier as key
- under the key items, you can predefine items always added to the menu
- see wp_create_nav_menu() and wp_update_nav_menu_item()
<?php
// menus/main-menu.php
return [
'Menu Name' => [
'items' => [
[
'menu-item-title' => 'New Menu Item Title',
'menu-item-url' => 'http://example.com/new-url',
],
],
],
];
💡 Quick Start (recommended)
Create options pages easily using WP-Battery CLI:wp create-wpb-options --name=site-settings
If you need to add or modify menus manually or just want to dig deeper:
- Create a folder
options
in yourwpb
directory - Add PHP files for each options page:
Options configuration files return an associative array defining the ACF options page.
- the option page identifier as key
- the configuration as value - internally, acf_add_options_page() is used
<?php
// options/site-settings.php
return [
'identifier' => [
'page_title' => 'Page Title',
'menu_title' => 'Menu Title',
'menu_slug' => 'menu-slug',
'capability' => 'edit_posts',
'position' => '25',
'redirect' => false
]
];
💡 Quick Start (recommended)
Create custom post types easily using WP-Battery CLI:wp create-wpb-post-type --name=product --namespace=my-theme
If you need to add or modify post types manually or just want to dig deeper:
- Create a folder
post-types
in yourwpb
directory - Add PHP files for each custom post type
Custom Post Types configuration files return an associative array:
- the post type name as key (in this example 'product')
- the configuration as value - consult the WordPress Post Type API for that
<?php
// post-types/post-type-product.php
return [
'product' => [
'label' => __( 'Products', 'my-theme'),
'description' => __( 'Products offered in the store', 'my-theme'),
'labels' => [
'name' => _x( 'Products', 'Post Type General Name', 'my-theme'),
],
// Features this CPT supports in Post Editor
'supports' => [
'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields', 'page-attributes'
],
// You can associate this CPT with a taxonomy or custom taxonomy.
'taxonomies' => [
'product-category', 'product-location'
],
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'capability_type' => 'post',
// read the WP developer docs for more options
],
];
💡 Quick Start (recommended)
Create custom post types easily using WP-Battery CLI:wp create-wpb-taxonomy --name=product-category --namespace=my-theme --post-type=product
If you need to add or modify post types manually or just want to dig deeper:
- Create a folder
taxonomies
in yourwpb
directory - Add PHP files for each custom taxonomy you want to add
Taxonomy configuration files return an associative array:
- the taxonomy name as key (in this example 'product-category')
- the configuration array as value - make sure to consult the WordPress API documentation for register_taxonomy()
- important: To connect a taxonomy with a post-type, the array item 'for_post_types' is required, which will be converted to the second parameter for register_taxonomy (Object type or array of object types with which the taxonomy should be associated.)
<?php
// taxonomies/taxonomy-product-category.php
return [
'product-category' => [
'labels' => [
'name' => _x( 'Product Categories', 'my-theme' ),
],
'hierarchical' => true,
'show_ui' => true,
'public' => true,
'show_in_rest' => true,
'show_admin_column' => true,
'query_var' => true,
// consult the WP docs on register_taxonomy() for more options.
//
// for_post_types is not part of the WordPress API,
// but is required for WP-Battery's taxonomy registration mechanism
'for_post_types' => [
'product'
],
],
];
- Create a folder
template-parts
in yourwpb
directory - Organize partials in subfolders (e.g.,
blocks/
,pages/
) - Reference partials in your templates:
{% block header %}
{% include 'pages/header.twig' %}
{% endblock %}
When enableACFSync
is enabled in your configuration:
- ACF field group changes are synchronized to JSON files in the
acf-sync
directory - One JSON file per field group
- Important: In production environments, changes deployed via code must be synchronized manually
This enables you to keep your CF7 templates in files.
- Create a folder
cf7-templates
in yourwpb
directory - Add your Contact Form 7 template files here
- Reference them in your configuration using the form hash:
'contactForm7Templates' => [
'48899ec' => 'contact-form.twig',
]
Here's a comprehensive example showing all available options:
$wpBattery = new WPBattery(
themeNamespace: 'my-theme',
settings: [
'themeSupport' => [
'menus',
'post-thumbnails',
'editor-styles',
'responsive-embeds',
'align-wide',
],
'registerBlocks' => true,
'registerMenus' => true,
'registerOptions' => true,
'enableACFSync' => true,
'allowSVGUploads' => true,
'disallowNonACFBlocks' => true,
'disableComments' => true,
'enableViteAssets' => true,
'viteBuildDir' => 'build',
'viteEntryPoint' => 'frontend/vite.entry.js',
'includeFrontendCSS' => [
'main-style' => [
'path' => get_stylesheet_directory_uri() . '/assets/css/main.css',
'dependencies' => [],
'version' => '1.0.0',
'media' => 'all'
]
],
'includeFrontendJS' => [
'main-script' => [
'path' => get_stylesheet_directory_uri() . '/assets/js/main.js',
'dependencies' => ['jquery'],
'version' => '1.0.0',
'args' => ['strategy' => 'defer']
]
],
'includeAdminCSS' => [
'admin-style' => [
'path' => get_stylesheet_directory_uri() . '/assets/admin/admin.css',
]
],
'includeAdminJS' => [
'admin-script' => [
'path' => get_stylesheet_directory_uri() . '/assets/admin/admin.js',
'dependencies' => ['wp-blocks'],
]
],
'contactForm7Templates' => [
'48899ec' => 'contact-form.twig',
],
'addMetaTags' => [
'viewport' => 'width=device-width, initial-scale=1, shrink-to-fit=no',
],
],
enableCache: true
);
Array of WordPress theme features to enable. Common options include:
'themeSupport' => [
'menus', // Enable WordPress menus
'post-thumbnails', // Enable featured images
'editor-styles', // Enable block editor styles
'responsive-embeds', // Enable responsive embedded content
'align-wide', // Enable wide/full alignment for blocks
'custom-logo', // Enable custom logo support
// etc...
]
When enabled, automatically registers all block.json files found in your theme's blocks directory.
'registerBlocks' => true // Scans and registers all block.json files
When enabled, processes menu configuration files from your theme's menu directory.
'registerMenus' => true // Registers menus from PHP configuration files
Automatically registers ACF options pages from configuration files.
'registerOptions' => true // Creates ACF options pages from config files
Enables ACF field synchronization using PHP files.
'enableACFSync' => true // Enables ACF JSON sync functionality
Enables SVG file uploads in the WordPress media library.
'allowSVGUploads' => true // Allows SVG file uploads
Restricts the block editor to only show ACF blocks.
'disallowNonACFBlocks' => true // Hides all non-ACF blocks
Completely removes WordPress comment functionality.
'disableComments' => true // Removes all comment functionality
Configure Vite.js asset building:
'enableViteAssets' => true,
'viteBuildDir' => 'build', // Directory for compiled assets
'viteEntryPoint' => 'frontend/vite.entry.js' // Main entry point
Include CSS and JavaScript files in the frontend:
'includeFrontendCSS' => [
'main-style' => [
'path' => get_stylesheet_directory_uri() . '/assets/css/main.css',
'dependencies' => [],
'version' => '1.0.0',
'media' => 'all'
]
],
'includeFrontendJS' => [
'main-script' => [
'path' => get_stylesheet_directory_uri() . '/assets/js/main.js',
'dependencies' => ['jquery'],
'version' => '1.0.0',
'args' => ['strategy' => 'defer']
]
]
Include CSS and JavaScript files in the admin area:
'includeAdminCSS' => [
'admin-style' => [
'path' => get_stylesheet_directory_uri() . '/assets/admin/admin.css',
'dependencies' => [],
'version' => '1.0.0',
'media' => 'all'
]
],
'includeAdminJS' => [
'admin-script' => [
'path' => get_stylesheet_directory_uri() . '/assets/admin/admin.js',
'dependencies' => ['wp-blocks'],
'version' => '1.0.0',
'args' => []
]
]
Map Contact Form 7 forms to Twig templates:
'contactForm7Templates' => [
'48899ec' => 'contact-form.twig', // Form hash => template path
]
Provide additional meta tags for wp_head as an array (key = tag name, value = tag content).
'addMetaTags' => [
'viewport' => 'width=device-width, initial-scale=1, shrink-to-fit=no',
],
The plugin includes a caching system for better performance. You can manage it using:
// Clear cache for specific theme
WPBattery::clearCache('theme-namespace');
// Clear all WP-Battery cache
WPBattery::clearAllCache();
This project is licensed under the GPL-2.0 License - see the LICENSE file for details.