| title | {{name}} - Development Guide |
|---|---|
| version | {{version}} |
| last_updated | 2024-10-18 |
| author | {{author}} |
| description | Comprehensive development guide for {{name}} |
| type | documentation |
This document provides comprehensive information for developers working on {{name}}.
- Node.js 18.0+ and npm 8.0+
- PHP 8.0+ with Composer
- WordPress 6.0+ (for testing)
- Git for version control
npm install
composer install
git clone https://github.com/{{author}}/{{plugin_slug}}.git
cd {{plugin_slug}}
npm install
composer installWe use @wordpress/env for local development:
# Start WordPress environment
npm run env:start
# Visit your site
open http://localhost:8888
# WordPress admin
open http://localhost:8888/wp-admin
# Username: admin
# Password: password# Start development with hot reload
npm run start
# In another terminal, watch for PHP changes
composer run test -- --watchThe plugin follows WordPress block development best practices with multiple blocks:
src/
├── index.js # Main entry point - registers all blocks
├── {{block_slug}}/ # Block directory
│ ├── block.json # Block metadata and configuration
│ ├── edit.js # Editor component (React)
│ ├── save.js # Frontend save component
│ ├── index.js # Block registration
│ ├── render.php # Server-side render callback
│ └── style.scss # Block-specific styles
├── {{block_slug}}/ # Another block
│ └── ...
└── shared/ # Shared between blocks
├── components/ # Shared React components
├── hooks/ # Shared hooks
└── utils/ # Shared utilities
All files use mustache-style placeholders for customization:
The build system supports these mustache transforms:
{{slug}}- Original kebab-case{{slug|snakeCase}}- snake_case transformation{{slug|pascalCase}}- PascalCase transformation{{slug|camelCase}}- camelCase transformation{{namespace|upper}}- UPPERCASE transformation
Template files use placeholder syntax:
{{slug}}.php- Main plugin filesrc/{{block-slug}}/- Block directory
The plugin is fully prepared for internationalization:
import { __ } from '@wordpress/i18n';
// Basic translation
const text = __( 'Hello World', '{{textdomain}}' );
// With context
const text = _x( 'Post', 'noun', '{{textdomain}}' );
// Pluralization
const text = _n( '%d item', '%d items', count, '{{textdomain}}' );// Basic translation
$text = __( 'Hello World', '{{textdomain}}' );
// Escaped output
echo esc_html__( 'Hello World', '{{textdomain}}' );
// With context
$text = _x( 'Post', 'noun', '{{textdomain}}' );We follow WordPress coding standards strictly:
- PSR-4 autoloading
- WordPress PHP Coding Standards
- DocBlock comments for all functions/classes
- Type hints where possible (PHP 8.0+)
- @wordpress/eslint-plugin for linting
- Prettier for code formatting
- JSDoc comments for functions
- React hooks patterns
- @wordpress/stylelint-config for linting
- BEM methodology for CSS class naming
- Mobile-first responsive design
- CSS custom properties for theming
src/
├── {{block-slug-1}}/ # Block 1
│ ├── components/ # Reusable React components
│ ├── hooks/ # Custom React hooks
│ ├── utils/ # Utility functions
│ └── styles/ # SCSS partials
├── {{block-slug-2}}/ # Block 2
│ └── ...
├── scss/ # Global styles
│ ├── abstracts/ # Variables, mixins, functions
│ ├── base/ # Reset, typography, etc.
│ ├── components/ # UI components
│ └── utilities/ # Utility classes
└── shared/ # Shared between blocks
├── components/ # Shared React components
├── hooks/ # Shared hooks
└── utils/ # Shared utilities
We use Jest and Testing Library:
# Run all tests
npm run test:unit
# Watch mode
npm run test:unit -- --watch
# Coverage report
npm run test:unit -- --coverageimport { render, screen } from '@testing-library/react';
import { Edit } from '../edit';
describe( '{{slug}} Edit Component', () => {
it( 'renders correctly', () => {
const attributes = { content: 'Test content' };
const setAttributes = jest.fn();
render( <Edit attributes={ attributes } setAttributes={ setAttributes } /> );
expect( screen.getByText( 'Test content' ) ).toBeInTheDocument();
} );
} );We use PHPUnit with WordPress test framework:
# Run PHP tests
composer run test
# Install test database (first time only)
./bin/install-wp-tests.sh {{slug|snakeCase}}_test root '' localhost latest<?php
class Test_{{namespace|pascalCase}}_Block extends WP_UnitTestCase {
public function test_block_registration() {
$this->assertTrue(
WP_Block_Type_Registry::get_instance()->is_registered( '{{namespace}}/{{block-slug}}' )
);
}
public function test_render_callback() {
$attributes = array( 'content' => 'Test content' );
$result = {{namespace}}_{{block-slug|snakeCase}}_render_callback( $attributes, '', null );
$this->assertStringContainsString( 'Test content', $result );
}
}We use Playwright for E2E testing:
# Run E2E tests
npm run test:e2e
# Debug mode
npm run test:e2e -- --debugnpm run startThis starts webpack in watch mode with:
- Hot module replacement
- Source maps
- Development optimizations
npm run buildThis creates optimized assets in build/:
- Minified JavaScript
- Compressed CSS
- Asset manifests
- Source maps (separate files)
The build process is configured via:
webpack.config.js- Custom webpack configuration.babelrc- Babel transpilation settingspostcss.config.js- PostCSS processing
The webpack.config.js extends @wordpress/scripts with custom settings:
Entry Points:
index- Main plugin entry (src/index.js)- Multiple block entries (
src/{{block-slug}}/index.js)
Path Aliases:
@→src/directory@blocks→src/directory@utils→src/shared/utils/directory@components→src/shared/components/directory
Custom Loaders:
- SVG files processed with
@svgr/webpackandurl-loader - Supports inline SVG imports in React components
Optimization:
- Separate CSS bundles for styles and editor
- Code splitting for better performance
- Asset size limits: 512KB per chunk
Example usage of path aliases:
// Instead of:
import MyComponent from '../../../shared/components/MyComponent';
// Use:
import MyComponent from '@components/MyComponent';Use the version update script:
# Update to new version
node scripts/update-version.js 1.2.0This updates version numbers in:
package.jsoncomposer.json{{plugin_slug}}.phpsrc/*/block.jsonREADME.md
- Update version using the script above
- Test thoroughly - run all tests and manual testing
- Build production assets with
npm run build - Create git tag and push
- GitHub Actions will automatically create release assets
npm run plugin-zipThis creates a distribution-ready ZIP file excluding:
- Development files (
src/,tests/) - Configuration files (
.eslintrc, etc.) - Dependencies (
node_modules/,vendor/)
Configure Xdebug in your environment and use the VSCode launch configuration:
- Start Xdebug in your WordPress environment
- Open VSCode
- Set breakpoints in PHP files
- Start debugging with F5
Use browser developer tools or VSCode:
// Add debugging statements
debugger; // Breakpoint in browserEnable debugging in wp-config.php:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );- Use React.memo() for expensive components
- Implement proper dependencies in useEffect hooks
- Code splitting with dynamic imports
- Tree shaking to remove unused code
- Critical CSS inlining for above-the-fold content
- CSS purging to remove unused styles
- CSS custom properties for efficient theming
- Mobile-first responsive design
- Transient caching for expensive operations
- Object caching where available
- Database query optimization
- Proper sanitization and validation
- Clear caches:
npm run clean && rm -rf node_modules && npm install - Check Node version: Must be 18.0+
- Update dependencies:
npm update
- Reset environment:
npm run env:destroy && npm run env:start - Check ports: Ensure 8888 is available
- Docker issues: Restart Docker Desktop
- Update snapshots:
npm run test:unit -- --updateSnapshot - Check database: Ensure test database is configured
- Clear test cache:
npm run test:unit -- --clearCache
- Check existing GitHub Issues
- Read WordPress Block Editor Handbook
- Join WordPress Slack #core-editor channel
- Review LightSpeed Standards
See CONTRIBUTING.md for detailed contribution guidelines.