TechEarl
Topic · WordPress

WordPress

Building, hardening, and unbreaking WordPress without losing weekends to plugin updates.

85 articlesWritten by Ishan Karunaratne
WordPress development and security guides on plugin updates, malware removal, and production patterns.
More in WordPress
Run a scheduled WooCommerce sale across thousands of products from a Google Sheet: a WP-CLI command sets sale price and on-sale dates via the CRUD. Dry-run, change-only.

Bulk Schedule WooCommerce Sale Prices From a Google Sheet

Run a site-wide or category sale from a sheet of sku, sale_price, start and end dates. A WP-CLI command reads the sheet, sets scheduled sale dates through the WooCommerce CRUD, and lets WooCommerce flip and unflip the price on its own. Dry-run and change-only.

Sync a WordPress business directory of thousands of listings to a Google Sheet: a change-only WP-CLI pull command, structured hours, and a closed status that keeps the page for SEO.

Update a WordPress Business Directory From a Google Sheet

Keep a directory of thousands of listings in sync with a Google Sheet a non-dev maintains: a WP-CLI pull command that reconciles each listing change-only, parses structured hours, and flips permanently-closed places to a closed status instead of deleting them.

Push one change to a fleet of WordPress installs from one Google Sheet: group rows by a website column, fan each batch out to its site, with partial-failure handling.

Manage Multiple WordPress Sites From One Google Sheet

Run a fleet of WordPress installs from a single Google Sheet: a website column per row, a small controller that groups the rows by site and pushes each batch to that site's endpoint, and partial-failure handling so one dead site never blocks the rest.

Hardening a custom WordPress REST API write endpoint against unauthorized and replayed requests

Securing a WordPress REST API Write Endpoint

A custom write endpoint accepts changes from the open internet. Harden it step by step: header secret, constant-time compare, HMAC signatures, replay protection, rate limiting, secret out of the repo, and a hidden route.

Running a safe bulk custom-field update in WordPress with a dry run, backup gate, and change-only changelog

Safely Bulk-Update Custom Fields in WordPress

A bulk custom-field update with no undo is one typo away from wrecking thousands of posts. Here is a safe pattern (and a downloadable WP-CLI command) with a dry run, a backup gate, a change-only changelog, and idempotent writes.

Comparing Advanced Custom Fields with native WordPress post meta, and how both store data in the same wp_postmeta table

ACF Fields vs Native Post Meta in WordPress

ACF and native post meta both write to the same wp_postmeta table. Here is what register_post_meta gives you, what ACF adds on top, and the read/write rules so a bulk script and a content editor never fight over the same field.

How to catch and route your own 404s in WordPress: hook template_redirect, check is_404(), parse the requested path, then resolve to content with status_header(200), 301-redirect with wp_safe_redirect(), or let it fall through to the real 404.

Catch and Route Your Own 404s in WordPress

Intercept requests that would 404 in WordPress on template_redirect, then resolve them to real content with status_header(200), 301 to the right URL with wp_safe_redirect(), or let them fall through. A fallback router for dynamic and legacy slugs you cannot enumerate.

Rank Math vs Yoast SEO compared by feature, performance, schema, pricing, and migration cost. The honest agency take on which to pick for a WordPress site in 2026.

Rank Math vs Yoast SEO: Which WordPress SEO Plugin to Use in 2026

Rank Math's free tier covers roughly what Yoast Premium does, schema support is broader, and the plugin is lighter on resources. Yoast still has brand recognition and a more guided editor flow. The honest agency comparison, by feature, performance, schema, pricing, and migration cost.

Bluehost honest review. Where it fits in 2026, the real operational ceiling, the migration path when sites outgrow it. From an agency operator's perspective.

Bluehost for WordPress: Honest Take for Small Sites

Bluehost has the WordPress.org recommendation and the lowest entry-tier price in mainstream hosting. The honest take on where Bluehost legitimately fits in 2026, the real operational ceiling, and the migration path for sites that outgrow it.

Kinsta managed WordPress hosting reviewed for agencies. Where value justifies price, where it does not, agency partner program, alternatives at each tier.

Kinsta for WordPress Agencies: Honest Review

Kinsta is the premium managed WordPress host most agencies eventually consider. The honest take: where the value justifies the price, where it does not, the agency partner program math, and the alternatives at each tier.

WP Engine managed WordPress reviewed for agencies. Performance, support, partner program, ACF acquisition implications, where it wins or loses.

WP Engine for WordPress Agencies: Honest Review

WP Engine is the most-recognized managed WordPress host and the default pick for many agencies. The honest take on performance, support, the agency partner program, the recent ACF acquisition implications, and where WP Engine wins or loses against alternatives.

Managed WordPress vs VPS for agencies. Simplicity vs flexibility, price premium vs lower per-resource cost. The break-even math with real numbers.

Managed WordPress Hosting vs VPS for Agencies

Managed WordPress hosting buys you operational simplicity at a per-site price premium. VPS buys you flexibility and lower per-resource cost at the price of in-house sysadmin time. The honest comparison and the agency-side break-even math.

Hosting for WordPress agency clients by traffic tier and workload type: shared, managed WordPress, managed VPS, self-managed. Agency-side implications.

A WordPress Hosting Decision Tree for Agencies

Hosting choices for WordPress agency clients are operational decisions, not pricing decisions. The decision tree by traffic tier and workload type: shared, managed WordPress, managed VPS, self-managed VPS. Plus the agency-side implications of each.

ACF Flexible Content + template parts + a shared library is a lightweight component system for WordPress. Patterns and comparison to React alternatives.

Using ACF Like a Lightweight Component System

ACF Flexible Content plus template parts plus a shared component library is effectively a lightweight component system for WordPress. The patterns: one component per layout, props via sub-fields, composition over inheritance, and how it compares to React-based alternatives.

Naming conventions for ACF field groups, field names, and field keys that keep a multi-year codebase navigable. Real patterns from directory-scale work.

ACF Field Naming Conventions That Actually Scale

A few naming conventions for ACF field groups, field names, and field keys keep a multi-year codebase navigable: snake_case names, hierarchy-encoded keys, post-type prefixes, sub-field consistency. The cost is zero; the benefit compounds.

Six root causes of ACF slowness at scale: object cache, oversized Repeaters, deep nesting, meta_query, field count, field-key overhead. Real fixes.

Common ACF Performance Problems on Large WordPress Sites

ACF performance problems at scale almost always trace to one of six things: missing object cache, oversized Repeaters, deeply nested Flexible Content, meta_query usage on ACF fields, too many fields per post type, or the field-key reference overhead. Here is what to look for and fix in each.

Set static defaults in the field group, dynamic defaults via acf/load_value, multi-select array defaults, and behavior when the default does not match.

How to Set Default Values in ACF Select Fields

ACF Select fields have a Default Value setting in the field group editor that handles the simple case. For dynamic defaults (computed from another field, role-based, or per-post-type), the acf/load_value filter is the right tool.

Elementor Pro's ACF Dynamic Tags. Every field type, Loop widget for Repeater, Theme Builder integration for archives. The mature reference.

Using ACF with Elementor Dynamic Fields

Elementor Pro's Dynamic Tags integration with ACF is the mature reference for binding custom field values to widget properties. Coverage for every field type, including Repeater via the Loop widget, and the Theme Builder integration for archive templates.

Three patterns for counting ACF Repeater rows: count() on the raw field, get_field_count, and a fast meta-only count without loading the rows.

How to Count Rows in an ACF Repeater Field

Counting ACF Repeater rows is three short patterns: count() on the raw field, get_field_count() inside a loop, and a faster meta-only count that skips loading the rows. Each has its right use case.

ACF True/False stores 1 or 0 but appears as boolean in PHP. Four causes of unexpected behavior: loose comparison, defaults, conditional logic, meta_query.

Why ACF True/False Fields Sometimes Behave Unexpectedly

ACF True/False fields store 1 or 0 in the database but appear as booleans in PHP. Loose-comparison bugs, empty-row defaults, conditional logic visibility, and meta_query gotchas are the four causes of unexpected behavior. Here is the fix for each.

ACF Checkbox returns arrays because they're multi-select. The 3 return formats, rendering patterns, query patterns, when to switch to Select or Radio.

Why Your ACF Checkbox Field Returns an Array

ACF Checkbox fields return arrays because they support multiple selections. The shape varies by Return Format. Here's what each option returns, the patterns for rendering and querying, and when to switch to a Select or Radio field instead.

Get alt text from an ACF Image field. Per return format: Image Array, Image ID, Image URL. The cleanest always-correct pattern for accessible output.

How to Get ALT Text from an ACF Image Field

Getting alt text from an ACF Image field depends on the field's Return Format. Image Array gives you the alt directly. ID and URL formats need a wp_get_attachment helper. Plus the cleanest pattern for always-correct alt output.

Clean responsive images from ACF Image fields. ID + wp_get_attachment_image for auto srcset, manual srcset control, picture element for art direction.

Proper Responsive Images with ACF Image Fields

The cleanest pattern for responsive images from an ACF Image field: ID return format plus wp_get_attachment_image, which produces a complete srcset and sizes attribute from registered image sizes. Plus the manual srcset pattern when you need control.

Useful acf/save_post patterns: derived fields, taxonomy sync, search-index refresh, ACF-to-meta mirroring, validation, audit logging, with code examples.

Useful Things You Can Do with acf/save_post

acf/save_post is the hook that fires after ACF saves a post's custom fields. Useful patterns: derived field computation, taxonomy sync, search-index refresh, ACF-to-meta mirroring, validation, audit logging. Plus the gotchas.

Canonical guide to update_field(): signature, Repeater and Flexible Content writes, field keys vs names, options pages, user meta, and the gotchas.

How to Update ACF Fields Programmatically

update_field() is the canonical way to write ACF data programmatically: the function signature, how to write to Repeater and Flexible Content fields, when to use field keys instead of names, options pages and user meta, and the gotchas that bite.

ACF Repeater first row appears blank? Three causes: missing the_row, incorrect sub-field name, accidental data overwrite. Real fixes with code examples.

Why Your First ACF Repeater Row Appears Empty

An ACF Repeater where the first row's data looks blank is almost always one of three things: missing the_row(), incorrect sub-field name, or accidental data overwrite via update_field with the wrong field reference.

Visitors see a fake Cloudflare verification on your WordPress site asking them to paste a command. That's ClickFix. Detection, removal, and persistence cleanup so it doesn't return.

The Fake Cloudflare Verification Attack on WordPress (ClickFix): What It Is and How to Remove It

Visitors to your WordPress site see a fake 'Cloudflare verification' page telling them to paste a command into Windows Run or Terminal. That's ClickFix, the social-engineering campaign that first appeared in early 2024 and exploded across compromised WordPress sites by autumn. What it does, where the injection lives in your site, and how to clean it without missing the persistence.

Step-by-step WordPress malware removal: identify the attack vector (files, database, .htaccess, wp-config), clean every layer, rotate credentials, and lock down to prevent reinfection. Cross-platform scripts for Linux and macOS.

How to Remove WordPress Malware: The Practitioner's Playbook

A step-by-step methodology for finding and removing malware from a compromised WordPress site, written by a Security+ certified engineer who's been cleaning sites since the early WordPress 2.x era. Covers every attack vector: file backdoors, database injections, .htaccess hijacks, wp-config tampering, and recurring reinfection. Originally written in 2016, updated regularly as new patterns emerge.

Four reliable ways to change a WordPress password: admin dashboard, WP-CLI, direct in the database, or email reset. Includes the WP 6.8+ bcrypt hash format.

How to Change a WordPress Password

Four reliable ways to change a WordPress password: admin dashboard, WP-CLI, directly in the database with the correct phpass or bcrypt hash, and the lost-password email reset.

Wire ElasticPress to WP_Query so WordPress queries hit Elasticsearch instead of MySQL. Install, indexable post types, ep_integrate, wp-cli index, faceted aggregations, and when ES actually beats MySQL FULLTEXT.

How to Use ElasticPress with WP_Query

Wire ElasticPress to WP_Query so WordPress queries hit Elasticsearch instead of MySQL. Covers installation, indexable post types, ep_integrate, the wp-cli index command, faceted search with aggregations, and when ES actually beats MySQL FULLTEXT.