- Automation Scripts
- WP-CLI Commands
- Development Setup
- Security Best Practices
- Debugging & Troubleshooting
- Performance Optimization
- Theme Development
- Plugin Development
#!/bin/bash
# WordPress Local Development Setup Script
# Usage: ./WordPress.sh
# Color codes for output
R='\033[0;31m'
G='\033[0;32m'
Y='\033[1;33m'
B='\033[0;96m'
NC='\033[0m'
# Configuration variables (replace with your values)
IP='{ip}'
SITE='{domain}'
DBUSER='{user}'
DBPASSWORD='{password}'
DBNAME='{db}'
WPUSER='{admin}'
WPPASSWORD='{pass}'
WPEMAIL='{email}'
LOCAL='en_US'
# Function to print colored output
print_status() {
echo -e "${G}[INFO]${NC} $1"
}
print_error() {
echo -e "${R}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${Y}[WARNING]${NC} $1"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root"
exit 1
fi
# Check if WP-CLI is installed
if ! command -v wp &> /dev/null; then
print_error "WP-CLI is not installed. Please install it first."
exit 1
fi
print_status "Setting up WordPress site: ${SITE}"
# Add site to hosts file
print_status "Adding ${SITE} to hosts file..."
if ! grep -q "${IP} ${SITE}" /etc/hosts; then
echo "${IP} ${SITE}" >> /etc/hosts
print_status "Host entry added successfully"
else
print_warning "Host entry already exists"
fi
sleep 1
clear
# Create Apache virtual host
print_status "Creating Apache virtual host..."
VHOST_FILE="/etc/apache2/sites-available/${SITE}.conf"
if [ ! -f "$VHOST_FILE" ]; then
cat > "$VHOST_FILE" << EOF
<VirtualHost *:80>
ServerAdmin ${WPUSER}@${SITE}
ServerName ${SITE}
ServerAlias www.${SITE}
DocumentRoot "/var/www/html/${SITE}"
DirectoryIndex index.php index.html
<Directory "/var/www/html/${SITE}/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
# Enable mod_rewrite for pretty permalinks
RewriteEngine On
# Logging
ErrorLog \${APACHE_LOG_DIR}/${SITE}_error.log
CustomLog \${APACHE_LOG_DIR}/${SITE}_access.log combined
</VirtualHost>
EOF
a2ensite ${SITE}
systemctl reload apache2
print_status "Virtual host created and enabled"
else
print_warning "Virtual host already exists"
fi
sleep 1
clear
# Create database and user
print_status "Setting up database..."
mysql -u root << EOF
CREATE USER IF NOT EXISTS '${DBUSER}'@'localhost' IDENTIFIED BY '${DBPASSWORD}';
GRANT ALL PRIVILEGES ON ${DBNAME}.* TO '${DBUSER}'@'localhost';
FLUSH PRIVILEGES;
CREATE DATABASE IF NOT EXISTS ${DBNAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EOF
if [ $? -eq 0 ]; then
print_status "Database setup completed"
else
print_error "Database setup failed"
exit 1
fi
# Create WordPress directory and install
print_status "Installing WordPress..."
SITE_DIR="/var/www/html/${SITE}"
if [ ! -d "$SITE_DIR" ]; then
mkdir -p "$SITE_DIR"
fi
cd "$SITE_DIR"
# Download WordPress core
wp core download --locale=${LOCAL} --skip-content --allow-root
# Create wp-config.php with debug settings
wp config create \
--dbname=${DBNAME} \
--dbuser=${DBUSER} \
--dbpass=${DBPASSWORD} \
--dbhost=localhost \
--dbcharset=utf8mb4 \
--allow-root \
--extra-php << 'PHP'
// Debug settings
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);
define('SCRIPT_DEBUG', true);
// Security keys (should be unique in production)
define('WP_CACHE', false);
define('AUTOMATIC_UPDATER_DISABLED', true);
// Memory limit
ini_set('memory_limit', '256M');
PHP
# Install WordPress
wp core install \
--url=${SITE} \
--title="WordPress Development Site" \
--admin_user=${WPUSER} \
--admin_password=${WPPASSWORD} \
--admin_email=${WPEMAIL} \
--skip-email \
--allow-root
# Set proper file permissions
chown -R www-data:www-data "$SITE_DIR"
find "$SITE_DIR" -type d -exec chmod 755 {} \;
find "$SITE_DIR" -type f -exec chmod 644 {} \;
# Install and activate themes
print_status "Installing themes..."
wp theme install twentytwentyfour --allow-root
wp theme install generatepress --activate --allow-root
# Install development plugins
print_status "Installing development plugins..."
PLUGINS=(
"wp-crontrol"
"transients-manager"
"query-monitor"
"debug-bar"
"health-check"
"wp-reset"
"show-hooks"
"theme-check"
"plugin-check"
)
for plugin in "${PLUGINS[@]}"; do
wp plugin install "$plugin" --activate --allow-root
print_status "Installed and activated: $plugin"
done
# Configure basic settings
wp option update permalink_structure '/%postname%/' --allow-root
wp option update timezone_string 'America/New_York' --allow-root
wp option update start_of_week 1 --allow-root
print_status "WordPress installation completed successfully!"
print_status "Site URL: http://${SITE}"
print_status "Admin URL: http://${SITE}/wp-admin"
print_status "Username: ${WPUSER}"
print_status "Password: ${WPPASSWORD}"
sleep 2
clear# Download WordPress core
wp core download --locale=en_US
# Update WordPress core
wp core update
# Check WordPress version
wp core version
# Verify WordPress installation
wp core verify-checksums# Export database
wp db export backup.sql
# Import database
wp db import backup.sql
# Search and replace URLs
wp search-replace 'oldurl.com' 'newurl.com'
# Reset database (requires WP Reset plugin)
wp plugin install wp-reset --activate
wp reset --yes# List all plugins
wp plugin list
# Install and activate plugin
wp plugin install plugin-name --activate
# Deactivate all plugins
wp plugin deactivate --all
# Update all plugins
wp plugin update --all
# Check for plugin vulnerabilities
wp plugin list --field=name | xargs -I {} wp plugin get {} --field=version# List themes
wp theme list
# Install theme
wp theme install theme-name
# Activate theme
wp theme activate theme-name
# Delete theme
wp theme delete theme-name# Create admin user
wp user create username [email protected] --role=administrator --user_pass=password
# List users
wp user list
# Update user password
wp user update username --user_pass=newpassword
# Grant super admin privileges (multisite)
wp super-admin add username# Import content from XML file
wp import content.xml --authors=create
# Generate dummy content
wp post generate --count=50
# Delete all posts
wp post delete $(wp post list --post_status=any --format=ids)
# Flush rewrite rules
wp rewrite flush# Download and install XAMPP
# Start Apache and MySQL services
# Create database through phpMyAdmin
# Download WordPress to htdocs folder# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp-content:/var/www/html/wp-content
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_ROOT_PASSWORD: rootpassword
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:- Query Monitor - Debug queries, hooks, conditionals
- Debug Bar - Debug information in admin bar
- WP Crontrol - Manage WordPress cron events
- Health Check - Site health and troubleshooting
- Show Hooks - Display WordPress hooks on pages
- Theme Check - Test themes for WordPress standards
VSCode settings.json for WordPress.
{
"php.suggest.basic": false,
"php.validate.enable": false,
"intelephense.files.associations": ["*.php", "*.phtml"],
"emmet.includeLanguages": {
"php": "html"
},
"files.associations": {
"*.php": "php"
}
}// Security keys (generate at https://api.wordpress.org/secret-key/1.1/salt/)
define('AUTH_KEY', 'your-unique-key-here');
define('SECURE_AUTH_KEY', 'your-unique-key-here');
define('LOGGED_IN_KEY', 'your-unique-key-here');
define('NONCE_KEY', 'your-unique-key-here');
define('AUTH_SALT', 'your-unique-key-here');
define('SECURE_AUTH_SALT', 'your-unique-key-here');
define('LOGGED_IN_SALT', 'your-unique-key-here');
define('NONCE_SALT', 'your-unique-key-here');
// Disable file editing
define('DISALLOW_FILE_EDIT', true);
// Disable plugin/theme installation
define('DISALLOW_FILE_MODS', true);
// Force SSL admin
define('FORCE_SSL_ADMIN', true);
// Limit post revisions
define('WP_POST_REVISIONS', 3);
// Automatic updates
define('WP_AUTO_UPDATE_CORE', true);# Block access to wp-config.php
<files wp-config.php>
order allow,deny
deny from all
</files>
# Block access to sensitive files
<FilesMatch "^.*(error_log|wp-config\.php|php.ini|\.[hH][tT][aApP].*)$">
Order deny,allow
Deny from all
</FilesMatch>
# Disable directory browsing
Options All -Indexes
# Block suspicious request methods
<LimitExcept GET POST HEAD>
deny from all
</LimitExcept>
# Protect against code injection
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC]
RewriteRule ^(.*)$ - [F,L]
</IfModule># Recommended file permissions
find /path/to/wordpress/ -type d -exec chmod 755 {} \;
find /path/to/wordpress/ -type f -exec chmod 644 {} \;
chmod 600 wp-config.php// wp-config.php debug settings
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', false);
define('WP_DEBUG_LOG', true);
define('SCRIPT_DEBUG', true);
define('SAVEQUERIES', true);
// Custom error logging
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/php-error.log');# Check error logs
tail -f /var/log/apache2/error.log
# Enable WP_DEBUG
# Check plugin conflicts
wp plugin deactivate --all
# Check theme issues
wp theme activate twentytwentyfour// Increase memory limit
ini_set('memory_limit', '512M');
define('WP_MEMORY_LIMIT', '512M');# Test database connection
wp db check
# Repair database
wp db repair
# Check database credentials in wp-config.php// Debug function for variables
function debug_to_console($data) {
echo '<script>console.log(' . json_encode($data) . ');</script>';
}
// Log to WordPress debug.log
if (WP_DEBUG === true) {
if (is_array($variable) || is_object($variable)) {
error_log(print_r($variable, true));
} else {
error_log($variable);
}
}
// Display all WordPress hooks
function show_hooks() {
global $wp_filter;
echo '<pre>';
print_r($wp_filter);
echo '</pre>';
}// Object caching
wp_cache_set('my_key', $data, 'my_group', 3600);
$data = wp_cache_get('my_key', 'my_group');
// Transients for database caching
set_transient('my_transient', $data, 3600);
$data = get_transient('my_transient');# Optimize database tables
wp db optimize
# Clean up spam and trash
wp comment delete $(wp comment list --status=spam --format=ids)
wp post delete $(wp post list --post_status=trash --format=ids)
# Remove unused plugins and themes
wp plugin delete $(wp plugin list --status=inactive --field=name)
wp theme delete $(wp theme list --status=inactive --field=name)// Add image size for optimization
add_image_size('optimized-thumbnail', 300, 200, true);
// Disable WordPress image compression
add_filter('jpeg_quality', function($quality) {
return 100;
});theme-name/
├── style.css
├── index.php
├── functions.php
├── header.php
├── footer.php
├── sidebar.php
├── single.php
├── page.php
├── archive.php
├── search.php
├── 404.php
├── template-parts/
├── assets/
│ ├── css/
│ ├── js/
│ └── images/
└── languages/
// functions.php essentials
function theme_setup() {
// Theme support
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support('custom-logo');
add_theme_support('html5', array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
));
// Menus
register_nav_menus(array(
'primary' => 'Primary Menu',
'footer' => 'Footer Menu',
));
// Image sizes
add_image_size('hero-image', 1200, 600, true);
}
add_action('after_setup_theme', 'theme_setup');
// Enqueue scripts and styles
function theme_scripts() {
wp_enqueue_style('theme-style', get_stylesheet_uri());
wp_enqueue_script('theme-script', get_template_directory_uri() . '/js/script.js', array('jquery'), '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'theme_scripts');// Register custom post type
function register_portfolio_post_type() {
$args = array(
'labels' => array(
'name' => 'Portfolio',
'singular_name' => 'Portfolio Item',
),
'public' => true,
'has_archive' => true,
'supports' => array('title', 'editor', 'thumbnail'),
'menu_icon' => 'dashicons-portfolio',
);
register_post_type('portfolio', $args);
}
add_action('init', 'register_portfolio_post_type');<?php
/**
* Plugin Name: My Custom Plugin
* Description: A brief description of what the plugin does.
* Version: 1.0.0
* Author: Your Name
* License: GPL v2 or later
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}// Activation hook
register_activation_hook(__FILE__, 'my_plugin_activate');
function my_plugin_activate() {
// Create database tables, set options, etc.
flush_rewrite_rules();
}
// Deactivation hook
register_deactivation_hook(__FILE__, 'my_plugin_deactivate');
function my_plugin_deactivate() {
// Clean up, flush rewrite rules, etc.
flush_rewrite_rules();
}
// Uninstall hook
register_uninstall_hook(__FILE__, 'my_plugin_uninstall');
function my_plugin_uninstall() {
// Delete options, drop tables, etc.
delete_option('my_plugin_options');
}// Add admin menu
add_action('admin_menu', 'my_plugin_admin_menu');
function my_plugin_admin_menu() {
add_options_page(
'My Plugin Settings',
'My Plugin',
'manage_options',
'my-plugin',
'my_plugin_admin_page'
);
}
function my_plugin_admin_page() {
?>
<div class="wrap">
<h1>My Plugin Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields('my_plugin_options');
do_settings_sections('my_plugin_options');
submit_button();
?>
</form>
</div>
<?php
}// PHP handler
add_action('wp_ajax_my_action', 'handle_my_ajax');
add_action('wp_ajax_nopriv_my_action', 'handle_my_ajax');
function handle_my_ajax() {
// Verify nonce
if (!wp_verify_nonce($_POST['nonce'], 'my_ajax_nonce')) {
wp_die('Security check failed');
}
// Process request
$result = array('success' => true, 'data' => 'Response data');
wp_send_json($result);
}
// JavaScript
jQuery(document).ready(function($) {
$('#my-button').click(function() {
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'my_action',
nonce: my_ajax_object.nonce
},
success: function(response) {
console.log(response);
}
});
});
});This guide covers essential WordPress development practices. Always test changes in a development environment before applying to production sites.