PHP Customizations
warning
Any PHP error can take the site down. Always test on staging, commit changes, and keep a rollback command ready.
PHP Customizations Explained
| Technique | Use case | Where |
|---|---|---|
| Hooks | Inject markup or run logic | inc/hooks.php |
| Filters | Change a decision/value | inc/filters.php |
| Shortcodes | Reusable snippets in content/elements | functions.php |
| Site plugin | Site-wide logic beyond theme | wp-content/mu-plugins/ or custom plugin |
Why It Matters
- Hook-first changes survive GeneratePress updates.
- Modular structure makes reviews and debugging easier.
- Secure output patterns prevent XSS and injection.
How It Works
WordPress loads the parent theme, then child theme, then runs hooks during rendering. Your custom code attaches to those hooks and filters.
flowchart LR
WP[WordPress] --> GP[GeneratePress]
GP --> CHILD[Child theme]
CHILD --> HOOKS[Hooks/filters]
HOOKS --> OUT[Output]
Practical Walkthrough
Step 1: Verify Child Theme Is Active
verify-child-theme-active.sh
cd /var/www/html
wp option get stylesheet
Step 2: Add a Small Hook Callback
wp-content/themes/generatepress-child/inc/hooks.php
<?php
add_action( 'generate_after_header', function() {
echo '<div class="gp-php-custom">' . esc_html__( 'Custom PHP hook output', 'generatepress-child' ) . '</div>';
} );
Step 3: Add a Small Filter
wp-content/themes/generatepress-child/inc/filters.php
<?php
add_filter( 'body_class', function( $classes ) {
$classes[] = 'gp-php-customizations';
return $classes;
} );
Step 4: Validate Syntax Before Deploy
basic-syntax-check.sh
cd /var/www/html
php -l wp-content/themes/generatepress-child/functions.php 2>/dev/null || true
Step 5: Consider a Site Plugin for Site-Wide Logic (Optional)
If logic is not theme-specific, put it in an mu-plugin.
create-mu-plugin.sh
cd /var/www/html
mkdir -p wp-content/mu-plugins
cat > wp-content/mu-plugins/site-custom.php <<'EOF'
<?php
// Site customizations (loaded before themes)
EOF
Practical Examples
Example 1: Conditional Output
wp-content/themes/generatepress-child/inc/hooks.php
<?php
add_action( 'generate_before_footer', function() {
if ( is_page( 'contact' ) ) {
echo '<div class="contact-cta">Contact us today</div>';
}
} );
Example 2: Avoid Template Overrides by Using Hooks
If the change is "add a block near content", a hook is typically better than copying a template.
Example 3: Remove a Default Callback (Pattern)
wp-content/themes/generatepress-child/functions.php
<?php
add_action( 'after_setup_theme', function() {
// Pattern only: replace with a real callback you discovered via grep.
// remove_action( 'generate_footer', 'generate_some_callback', 10 );
} );
Best Practices
| Practice | Why |
|---|---|
| Escape output | Prevent XSS |
| Keep callbacks small | Easier rollback |
| Use version control | Audit trail |
| Avoid secrets in code | Prevent leaks |
| Prefer mu-plugins for non-theme logic | Cleaner responsibility |
| Keep conditionals explicit | Avoid random behavior |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| White screen | PHP fatal | Check /usr/local/lsws/logs/error.log and roll back |
| Hook not firing | Wrong hook or conditional | Confirm hook exists and test scope |
| Changes not visible | Cache | Purge LSCache and test logged-out |
| Syntax check passes but site fails | Included file error | Validate included inc/*.php files too |
Hands-On
- Add one hook callback that outputs a banner.
- Add one filter that changes body classes.
- Commit changes and practice rollback by reverting the commit.
- Create a simple mu-plugin and confirm it loads.
Quick Reference
php-customizations-cheatsheet.sh
cd /var/www/html/wp-content/themes/generatepress-child
grep -R "add_action\|add_filter" -n inc | head
What's Next
- Next: Hook Elements (GP Premium)
- Related: Working with GeneratePress Hooks