<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Anatoliy Dovgun</title>
    <description>The latest articles on Forem by Anatoliy Dovgun (@adovgun).</description>
    <link>https://forem.com/adovgun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F183424%2F2ad467b6-c4be-4f40-816c-ab26b47dacff.png</url>
      <title>Forem: Anatoliy Dovgun</title>
      <link>https://forem.com/adovgun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adovgun"/>
    <language>en</language>
    <item>
      <title>Open/Closed Principle in WordPress Architecture</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Sun, 01 Mar 2026 15:26:58 +0000</pubDate>
      <link>https://forem.com/adovgun/openclosed-principle-in-wordpress-architecture-4f3l</link>
      <guid>https://forem.com/adovgun/openclosed-principle-in-wordpress-architecture-4f3l</guid>
      <description>&lt;p&gt;WordPress plugins rarely collapse because of complexity.&lt;/p&gt;

&lt;p&gt;They collapse because of change.&lt;/p&gt;

&lt;p&gt;New payment gateway.&lt;br&gt;&lt;br&gt;
New notification channel.&lt;br&gt;&lt;br&gt;
New integration.&lt;br&gt;&lt;br&gt;
New business rule.&lt;/p&gt;

&lt;p&gt;And suddenly — you are modifying the same class again.&lt;/p&gt;

&lt;p&gt;That’s exactly what the &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt; is designed to prevent.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Open/Closed Principle Really Means
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities should be open for extension, but closed for modification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; mean your code never changes.&lt;/p&gt;

&lt;p&gt;It means:&lt;/p&gt;

&lt;p&gt;Core behavior remains stable.&lt;br&gt;&lt;br&gt;
New functionality is added by extension — not by editing existing logic.&lt;/p&gt;

&lt;p&gt;If every new feature requires touching old code, your architecture is fragile.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Typical WordPress Anti-Pattern
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php
class PaymentProcessor {
    public function process(string $method, float $amount): void {
        if ($method === 'paypal') {
            // PayPal logic
        }

        if ($method === 'stripe') {
            // Stripe logic
        }

        if ($method === 'bank') {
            // Bank transfer logic
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Works fine.&lt;/p&gt;

&lt;p&gt;Until business says:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add Apple Pay&lt;/li&gt;
&lt;li&gt;Add crypto&lt;/li&gt;
&lt;li&gt;Add installment payments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each time → modify the same class.&lt;/p&gt;

&lt;p&gt;That’s not closed for modification.&lt;/p&gt;

&lt;p&gt;That’s conditional chaos.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Better Architectural Direction
&lt;/h2&gt;

&lt;p&gt;Introduce abstraction.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interface PaymentMethod {&lt;br&gt;
    public function process(float $amount): void;&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Concrete implementations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PayPalPayment implements PaymentMethod {}
class StripePayment implements PaymentMethod {}
class BankTransferPayment implements PaymentMethod {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Processor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PaymentProcessor {
    public function __construct(private PaymentMethod $method) {}

    public function process(float $amount): void {
        $this-&amp;gt;method-&amp;gt;process($amount);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;p&gt;Adding Apple Pay = new class.&lt;br&gt;
No modification of existing logic.&lt;/p&gt;

&lt;p&gt;That’s Open/Closed in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why WordPress Developers Struggle with OCP
&lt;/h2&gt;

&lt;p&gt;WordPress encourages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature flags inside giant classes&lt;/li&gt;
&lt;li&gt;Conditionals inside hooks&lt;/li&gt;
&lt;li&gt;Direct API calls&lt;/li&gt;
&lt;li&gt;Procedural branching logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But scalable systems require extension-based thinking.&lt;/p&gt;

&lt;p&gt;If your architecture grows by adding if statements — it won’t scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Apply OCP in WordPress
&lt;/h2&gt;

&lt;p&gt;Use it for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment gateways&lt;/li&gt;
&lt;li&gt;Notification systems (email, SMS, Slack)&lt;/li&gt;
&lt;li&gt;Export formats (CSV, PDF, JSON)&lt;/li&gt;
&lt;li&gt;Caching strategies&lt;/li&gt;
&lt;li&gt;Storage drivers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any place where variation is expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;Open/Closed Principle enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safer refactoring&lt;/li&gt;
&lt;li&gt;Replaceable infrastructure&lt;/li&gt;
&lt;li&gt;Testable components&lt;/li&gt;
&lt;li&gt;Plugin-style extensibility&lt;/li&gt;
&lt;li&gt;Long-term maintainability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your plugin is constantly rewritten, OCP is missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Most WordPress plugins are built to work.&lt;/p&gt;

&lt;p&gt;Few are built to evolve.&lt;/p&gt;

&lt;p&gt;Open/Closed Principle is what makes the difference.&lt;/p&gt;

&lt;p&gt;Full breakdown:&lt;br&gt;
&lt;a href="https://4wp.dev/architectures/solid/open-closed-principle/" rel="noopener noreferrer"&gt;https://4wp.dev/architectures/solid/open-closed-principle/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>4wpdev</category>
      <category>wordpress</category>
      <category>solidprinciples</category>
    </item>
    <item>
      <title>Single Responsibility Principle for OOP WordPress Developers</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Sat, 28 Feb 2026 17:55:21 +0000</pubDate>
      <link>https://forem.com/adovgun/single-responsibility-principle-for-oop-wordpress-developers-1700</link>
      <guid>https://forem.com/adovgun/single-responsibility-principle-for-oop-wordpress-developers-1700</guid>
      <description>&lt;p&gt;If you want to grow as an OOP WordPress developer, understanding the Single Responsibility Principle (SRP) is not optional — it’s foundational.&lt;/p&gt;

&lt;p&gt;SRP is the first principle from the well-known SOLID design principles. It states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  That sounds simple. In practice — especially in WordPress — it’s often ignored.
&lt;/h2&gt;

&lt;p&gt;The Real Problem in WordPress Projects&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many WordPress developers still build:&lt;/li&gt;
&lt;li&gt;Massive utility classes&lt;/li&gt;
&lt;li&gt;God-like service objects&lt;/li&gt;
&lt;li&gt;Theme functions.php monsters&lt;/li&gt;
&lt;li&gt;Plugins that do “everything”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tight coupling&lt;/li&gt;
&lt;li&gt;Hard-to-test code&lt;/li&gt;
&lt;li&gt;Fear of refactoring&lt;/li&gt;
&lt;li&gt;Fragile architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an OOP WordPress developer, this becomes a career bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Single Responsibility Really Means
&lt;/h2&gt;

&lt;p&gt;SRP does NOT mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One method per class&lt;/li&gt;
&lt;li&gt;Ultra-micro classes&lt;/li&gt;
&lt;li&gt;Artificial splitting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SRP means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have one clear responsibility in the business domain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Bad:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class OrderManager {&lt;br&gt;
    public function createOrder() {}&lt;br&gt;
    public function sendEmail() {}&lt;br&gt;
    public function generateInvoicePDF() {}&lt;br&gt;
    public function logActivity() {}&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Good:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class OrderCreator {}&lt;br&gt;
class OrderMailer {}&lt;br&gt;
class InvoiceGenerator {}&lt;br&gt;
class ActivityLogger {}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each class now has one reason to change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying SRP in WordPress Architecture
&lt;/h2&gt;

&lt;p&gt;For a professional OOP WordPress developer, SRP applies to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Plugin Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controllers&lt;/li&gt;
&lt;li&gt;Services&lt;/li&gt;
&lt;li&gt;Repositories&lt;/li&gt;
&lt;li&gt;Integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MyPlugin.php (3000 lines)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/&lt;br&gt;
 ├── Application/&lt;br&gt;
 ├── Domain/&lt;br&gt;
 ├── Infrastructure/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Hooks &amp;amp; WordPress Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avoid this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add_action('init', function () {&lt;br&gt;
    register_post_type(...);&lt;br&gt;
    sendEmails();&lt;br&gt;
    syncWithAPI();&lt;br&gt;
});&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Instead, delegate:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add_action('init', [PostTypeRegistrar::class, 'register']);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Theme Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In modern block themes and FSE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Templates define structure&lt;/li&gt;
&lt;li&gt;Patterns define reusable UI&lt;/li&gt;
&lt;li&gt;PHP handles domain logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mixing all of this breaks SRP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for an OOP WordPress Developer
&lt;/h2&gt;

&lt;p&gt;If you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work on enterprise WordPress projects&lt;/li&gt;
&lt;li&gt;Pass technical interviews&lt;/li&gt;
&lt;li&gt;Build scalable products&lt;/li&gt;
&lt;li&gt;Refactor safely&lt;/li&gt;
&lt;li&gt;Collaborate in teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SRP is your baseline.&lt;/p&gt;

&lt;p&gt;Without it, you are just writing procedural code wrapped in classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common SRP Mistakes in WordPress
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fat service classes&lt;/li&gt;
&lt;li&gt;Overloaded helpers&lt;/li&gt;
&lt;li&gt;Static utility dumping grounds&lt;/li&gt;
&lt;li&gt;Mixed domain + infrastructure logic&lt;/li&gt;
&lt;li&gt;Business logic inside template files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this sounds familiar — your architecture needs refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the Full Architecture Breakdown
&lt;/h2&gt;

&lt;p&gt;This article is a short overview.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;For a deeper architectural breakdown, examples, and structured explanation, read the original post:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
👉 &lt;a href="https://4wp.dev/architectures/solid/single-responsibility/" rel="noopener noreferrer"&gt;https://4wp.dev/architectures/solid/single-responsibility/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thought&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being an OOP WordPress developer is not about using classes.&lt;br&gt;
It’s about understanding responsibility boundaries.&lt;br&gt;
Master SRP — and the rest of SOLID becomes easier.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>oop</category>
      <category>solidprinciples</category>
      <category>4wpev</category>
    </item>
    <item>
      <title>4WP.dev — Modular WordPress Architecture, Gutenberg Custom Blocks, SEO &amp; Automation</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Sat, 14 Feb 2026 23:05:31 +0000</pubDate>
      <link>https://forem.com/adovgun/4wpdev-modular-wordpress-architecture-gutenberg-custom-blocks-seo-automation-3if2</link>
      <guid>https://forem.com/adovgun/4wpdev-modular-wordpress-architecture-gutenberg-custom-blocks-seo-automation-3if2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“When you have one plugin — it’s great. When you have several — even better. When they are actively used — perfect. But then the real pain begins…”&lt;br&gt;
— Full-stack WordPress developer with open two eyes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have 12+ plugins and over 30+ projects where use it and know how management it from one place:&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://4wp.dev/plugin/" rel="noopener noreferrer"&gt;https://4wp.dev/plugin/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/4wpdev/4wpdev" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wpdev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple example: one WordPress project uses multiple plugins. Then more projects reuse them. Over time the ecosystem grows — modules increase, dependencies expand, logic overlaps, responsibilities blur, performance fluctuates, updates introduce risks, and maintenance becomes unpredictable.&lt;/p&gt;

&lt;p&gt;4WP.dev is a modular WordPress development framework designed to solve this problem and scale complex Gutenberg-based projects efficiently.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>add_filter(‘practice_case_b2b_migration’): Why Using __return_false Changes the Core Email Flow in WordPress</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Sat, 07 Feb 2026 21:03:49 +0000</pubDate>
      <link>https://forem.com/adovgun/addfilterpracticecaseb2bmigration-why-using-returnfalse-changes-the-core-email-flow-in-2p2a</link>
      <guid>https://forem.com/adovgun/addfilterpracticecaseb2bmigration-why-using-returnfalse-changes-the-core-email-flow-in-2p2a</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_filter( 'send_email_change_email', '__return_false' )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why Returning False Changes the Core Email Flow in WordPress&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Filters in WordPress are often described as tools for modifying data.&lt;/p&gt;

&lt;p&gt;In real-world systems — they control behavior.&lt;/p&gt;

&lt;p&gt;And in complex architectures, they prevent infrastructure-level failures.&lt;/p&gt;

&lt;p&gt;This article walks through a real B2B marketplace migration case and explains why returning false in specific filters is not a hack — but an architectural control decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Scenario: B2B Marketplace + CRM Migration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imagine:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are building a B2B marketplace.&lt;/li&gt;
&lt;li&gt;The source of truth for users is an external CRM.&lt;/li&gt;
&lt;li&gt;Thousands of users must be migrated or synchronized.&lt;/li&gt;
&lt;li&gt;During synchronization, user emails may change.&lt;/li&gt;
&lt;li&gt;Users do not initiate these changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first glance, this looks like a standard import task.&lt;/p&gt;

&lt;p&gt;It isn’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What WordPress Does by Default&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When wp_update_user() runs and detects an email change, WordPress:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Detects the email difference.&lt;/li&gt;
&lt;li&gt;Prepares a notification. &lt;/li&gt;
&lt;li&gt;Applies the filter send_email_change_email.&lt;/li&gt;
&lt;li&gt;If the filter returns true → the email is sent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally, depending on context, WordPress may also trigger:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New user notification&lt;/li&gt;
&lt;li&gt;Password change notification&lt;/li&gt;
&lt;li&gt;Email verification flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For interactive user behavior — this is correct.&lt;/p&gt;

&lt;p&gt;For CRM-driven migration — this is dangerous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Infrastructure Risk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uncontrolled email triggers during migration can cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thousands of unintended emails&lt;/li&gt;
&lt;li&gt;SMTP throttling&lt;/li&gt;
&lt;li&gt;Domain reputation damage&lt;/li&gt;
&lt;li&gt;Confused users&lt;/li&gt;
&lt;li&gt;Support overload&lt;/li&gt;
&lt;li&gt;Trust erosion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a minor technical detail.&lt;/p&gt;

&lt;p&gt;This is product-level and infrastructure-level risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The First Layer of Control (And Why It Wasn’t Enough)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During initial system design, we anticipated user creation issues.&lt;/p&gt;

&lt;p&gt;So we disabled new user notifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_filter( 'wp_send_new_user_notification_to_user', '__return_false' );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That solved welcome emails during migration.&lt;/p&gt;

&lt;p&gt;But real-world testing exposed a gap.&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some users were created.&lt;/li&gt;
&lt;li&gt;Some were updated.&lt;/li&gt;
&lt;li&gt;Some had email changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even with new user notifications disabled, WordPress still triggered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;send_email_change_email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because from core perspective — email change is a separate lifecycle event.&lt;/p&gt;

&lt;p&gt;Lesson:&lt;/p&gt;

&lt;p&gt;Disabling one filter does not mean you control the lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Critical Decision Point&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent email change notifications:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add_filter( 'send_email_change_email', '__return_false' );&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By default → true.&lt;/p&gt;

&lt;p&gt;We explicitly return false.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;p&gt;This does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modify user data&lt;/li&gt;
&lt;li&gt;Override internal functions&lt;/li&gt;
&lt;li&gt;Disable WordPress email globally&lt;/li&gt;
&lt;li&gt;Break core logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It changes a boolean decision flag.&lt;/p&gt;

&lt;p&gt;That’s a behavioral override.&lt;/p&gt;

&lt;p&gt;And that’s an architectural choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Is Architecturally Significant&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a difference between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modifying data&lt;/li&gt;
&lt;li&gt;Modifying control flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Boolean filters like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send_email_change_email&lt;/li&gt;
&lt;li&gt;send_password_change_email&lt;/li&gt;
&lt;li&gt;user_has_cap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are not data transformers.&lt;/p&gt;

&lt;p&gt;They are behavioral switches.&lt;/p&gt;

&lt;p&gt;They sit at decision points inside core.&lt;/p&gt;

&lt;p&gt;Changing them alters system flow — not data integrity.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoped Implementation (Best Practice)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This should never be applied blindly in production.&lt;/p&gt;

&lt;p&gt;Recommended approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if ( defined( 'CRM_MIGRATION_PROCESS' ) &amp;amp;&amp;amp; CRM_MIGRATION_PROCESS ) {
    add_filter( 'send_email_change_email', '__return_false' );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply only in CLI context&lt;/li&gt;
&lt;li&gt;Scope to migration service layer&lt;/li&gt;
&lt;li&gt;Enable only during sync&lt;/li&gt;
&lt;li&gt;Remove after migration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Control the scope.&lt;/p&gt;

&lt;p&gt;Never globally suppress lifecycle behavior without context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Practical Classification of WordPress Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding filter types helps avoid architectural mistakes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Data Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modify values.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the_content&lt;/li&gt;
&lt;li&gt;pre_user_email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Boolean Control Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Control system decisions.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send_email_change_email&lt;/li&gt;
&lt;li&gt;send_password_change_email&lt;/li&gt;
&lt;li&gt;user_has_cap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are control switches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Pre-Persistence Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run before saving data.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;pre_insert_user_data&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Capability &amp;amp; Security Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Control permissions.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;map_meta_cap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our migration case, we were dealing with Boolean Control Filters.&lt;/p&gt;

&lt;p&gt;These require architectural awareness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Was Required in B2B Context&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this migration:&lt;/li&gt;
&lt;li&gt;Email changes were system-driven.&lt;/li&gt;
&lt;li&gt;CRM was authoritative.&lt;/li&gt;
&lt;li&gt;Users did not initiate updates.&lt;/li&gt;
&lt;li&gt;No verification flow was required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From UX perspective — notifications would create noise.&lt;/p&gt;

&lt;p&gt;From infrastructure perspective — risk.&lt;/p&gt;

&lt;p&gt;From architecture perspective — mandatory control.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Engineering Lessons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Study full lifecycle, not just creation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inspect internal trigger points in wp_update_user().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Map all related filters before mass operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use scoped boolean filters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document every override.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WordPress core works correctly.&lt;/p&gt;

&lt;p&gt;But it works correctly for interactive user flows.&lt;/p&gt;

&lt;p&gt;CRM-driven synchronization is not interactive.&lt;/p&gt;

&lt;p&gt;If you do not control trigger points —&lt;br&gt;
core will execute its default behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thought&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_filter( 'send_email_change_email', '__return_false' );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not about “turning something off.”&lt;/p&gt;

&lt;p&gt;It is about taking control over system behavior.&lt;/p&gt;

&lt;p&gt;In complex B2B systems, filters are not customization tools.&lt;/p&gt;

&lt;p&gt;They are infrastructure control mechanisms.&lt;/p&gt;

&lt;p&gt;And every time you override default WordPress behavior,&lt;br&gt;
you are making an architectural decision — not just writing code.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://4wp.dev" rel="noopener noreferrer"&gt;https://4wp.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>4wpdev</category>
      <category>wordpress</category>
      <category>webdev</category>
    </item>
    <item>
      <title>4wp Responsive Plugin</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Tue, 03 Feb 2026 16:46:58 +0000</pubDate>
      <link>https://forem.com/adovgun/4wp-responsive-plugin-2pnp</link>
      <guid>https://forem.com/adovgun/4wp-responsive-plugin-2pnp</guid>
      <description>&lt;h1&gt;
  
  
  4WP Responsive
&lt;/h1&gt;

&lt;p&gt;Responsive controls for core Gutenberg blocks with per-breakpoint spacing, visibility, font-size, and alignment support. Designed to be theme.json-first and editor-friendly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;– Plugin page: &lt;a href="https://4wp.dev/plugin/4wp-responsive/" rel="noopener noreferrer"&gt;https://4wp.dev/plugin/4wp-responsive/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;– GitRepository: &lt;a href="https://github.com/4wpdev/4wp-responsive" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-responsive&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does today
&lt;/h2&gt;

&lt;p&gt;– Responsive spacing per breakpoint (Padding/Margin: top/right/bottom/left).&lt;/p&gt;

&lt;p&gt;– Responsive visibility per breakpoint (Hide / Show only).&lt;/p&gt;

&lt;p&gt;– Responsive font-size per breakpoint for blocks that support typography.&lt;/p&gt;

&lt;p&gt;– Responsive text alignment per breakpoint (left/center/right/justify).&lt;/p&gt;

&lt;p&gt;– Works with core blocks (e.g. Heading, Paragraph, Group, List) and any block that supports the same features.&lt;/p&gt;

&lt;p&gt;– Uses utility CSS classes + CSS variables (no frontend JS).&lt;/p&gt;

&lt;p&gt;– Editor preview stays in sync with the selected device mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;– Theme.json-first: reads spacing and font-size presets from the active theme.&lt;/p&gt;

&lt;p&gt;– Works with standard blocks (no custom block requirement).&lt;/p&gt;

&lt;p&gt;– Minimal markup changes: classes + CSS variables only.&lt;/p&gt;

&lt;p&gt;– Safe fallback: content stays intact if the plugin is deactivated.&lt;/p&gt;

&lt;p&gt;– Single generated CSS file, cached with a hash.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;– &lt;strong&gt;Presets&lt;/strong&gt; (from &lt;code&gt;theme.json&lt;/code&gt;) are applied via utility classes like:&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;has-forwp-padding-top-mobile-40&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;has-forwp-font-size-desktop-large&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;has-forwp-text-align-mobile-center&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;– &lt;strong&gt;Custom values&lt;/strong&gt; (e.g. 150 / 150px / 2rem) are applied via:&lt;/p&gt;

&lt;p&gt;– class &lt;code&gt;has-forwp-*-custom&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;– CSS variable on the block, e.g. &lt;code&gt;–forwp-padding-top-mobile: 150px;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;– this keeps output clean while allowing arbitrary values&lt;/p&gt;

&lt;h2&gt;
  
  
  Editor UI
&lt;/h2&gt;

&lt;p&gt;You will find &lt;strong&gt;Responsive Spacing&lt;/strong&gt; in the block inspector sidebar:&lt;/p&gt;

&lt;p&gt;– Tabs: Desktop / Tablet / Mobile&lt;/p&gt;

&lt;p&gt;– Sections: Padding, Margin, Font Size, Alignment, Visibility&lt;/p&gt;

&lt;p&gt;– Current screen size is shown per tab&lt;/p&gt;

&lt;p&gt;– Hidden blocks are dimmed in the editor instead of fully removed&lt;/p&gt;

&lt;h2&gt;
  
  
  Settings
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Settings → 4WP Responsive&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Breakpoints
&lt;/h3&gt;

&lt;p&gt;Displayed in a table with the active source:&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;theme.json&lt;/code&gt; (&lt;code&gt;settings.custom.breakpoints&lt;/code&gt;), if present&lt;/p&gt;

&lt;p&gt;– Plugin settings, only when &lt;code&gt;theme.json&lt;/code&gt; has no breakpoints&lt;/p&gt;

&lt;p&gt;– Default values if neither is available&lt;/p&gt;

&lt;p&gt;If the theme defines breakpoints, custom fields are disabled to avoid conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS storage path
&lt;/h3&gt;

&lt;p&gt;Generated CSS is stored in &lt;code&gt;wp-content/uploads/4wp-responsive/&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;You can override the storage path with an absolute path if your architecture requires it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;– WordPress 6.0+&lt;/p&gt;

&lt;p&gt;– PHP 7.4+&lt;/p&gt;

&lt;p&gt;– A theme with &lt;code&gt;theme.json&lt;/code&gt; is recommended (for presets).&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;– The plugin respects theme.json presets for spacing and font sizes.&lt;/p&gt;

&lt;p&gt;– Custom values are supported, but only through CSS variables (no inline padding/margin).&lt;/p&gt;

</description>
      <category>4wp</category>
      <category>wordpressplugin</category>
      <category>wordpressdevelopment</category>
      <category>4wpdev</category>
    </item>
    <item>
      <title>4WP-FAQ is not just another FAQ block — it is a smart wrapper around core Accordion.</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Mon, 02 Feb 2026 21:16:44 +0000</pubDate>
      <link>https://forem.com/adovgun/4wp-faq-is-not-just-another-faq-block-it-is-a-smart-wrapper-around-core-accordion-157p</link>
      <guid>https://forem.com/adovgun/4wp-faq-is-not-just-another-faq-block-it-is-a-smart-wrapper-around-core-accordion-157p</guid>
      <description>&lt;p&gt;&lt;strong&gt;4WP-FAQ&lt;/strong&gt; is not another FAQ plugin and not a new block.&lt;br&gt;
It’s a smart wrapper over the WordPress core Accordion, adding structure and meaning to existing content.&lt;/p&gt;

&lt;p&gt;The plugin does not change design, does not break layouts, and does not modify the base block structure. It works entirely on top of native Accordion blocks, adding aggregation logic and Schema.org support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What 4WP-FAQ does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automatically converts Accordion-based questions and answers into valid FAQPage Schema (JSON-LD)&lt;/p&gt;

&lt;p&gt;Aggregates all FAQ blocks across the site and understands where and in what context each question is used&lt;/p&gt;

&lt;p&gt;Works only with real content — no duplication, no invented questions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;4WP-FAQ creates a single source of truth for real questions and answers:&lt;/p&gt;

&lt;p&gt;Clear visibility into which questions are actually used&lt;/p&gt;

&lt;p&gt;Transparent mapping of questions to pages and contexts&lt;/p&gt;

&lt;p&gt;Easy validation of content reuse and relevance&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Philosophy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Content is the source of truth.&lt;br&gt;
The plugin doesn’t generate knowledge — it records facts, aggregates them, and exposes data for analysis, reuse, and integrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built for scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reuse common questions via autocomplete&lt;/p&gt;

&lt;p&gt;Real usage and interaction statistics&lt;/p&gt;

&lt;p&gt;Click and expansion tracking with entry-point context&lt;/p&gt;

&lt;p&gt;A knowledge base built on actual user questions, not copies or assumptions&lt;/p&gt;

&lt;p&gt;🔗 Plugin page &amp;amp; documentation:&lt;br&gt;
&lt;a href="https://4wp.dev/plugin/4wp-faq/" rel="noopener noreferrer"&gt;https://4wp.dev/plugin/4wp-faq/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 GitHub repository:&lt;br&gt;
&lt;a href="https://github.com/4wpdev/4wp-faq" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-faq&lt;/a&gt;&lt;/p&gt;

</description>
      <category>4wpdev</category>
      <category>wordpressplugins</category>
      <category>woordpressdevelopment</category>
    </item>
    <item>
      <title>How to Use MCP with WordPress: Step-by-Step</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Sat, 24 Jan 2026 22:28:00 +0000</pubDate>
      <link>https://forem.com/adovgun/how-to-use-mcp-with-wordpress-step-by-step-1p3i</link>
      <guid>https://forem.com/adovgun/how-to-use-mcp-with-wordpress-step-by-step-1p3i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide shows how to connect an MCP client to WordPress via the MCP Adapter and create content using MCP tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WordPress 6.9+&lt;/li&gt;
&lt;li&gt;MCP Adapter installed and activated&lt;/li&gt;
&lt;li&gt;MCP client (Cursor, Claude Desktop, VS Code, etc.)&lt;/li&gt;
&lt;li&gt;Application Password for the WordPress admin user (HTTP transport)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Abilities Provider (Required)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP Adapter exposes only abilities that are explicitly registered and marked meta.mcp.public=true. That means you need a small abilities provider plugin that registers admin‑only tools such as create-post and update-post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/4wpdev/4wp-mcp-abilities" rel="noopener noreferrer"&gt;GitHub → 4wp-mcp-abilities&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: This is not a production plugin. Treat it as reference code only. You can adapt it inside a theme or a temporary internal plugin, but you must review security, permissions, and data exposure before using it in any real environment.&lt;/p&gt;

&lt;p&gt;The repository is intentionally minimal and acts as a reference implementation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code is poetry.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What exactly must be enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abilities plugin active (admin‑only).&lt;/li&gt;
&lt;li&gt;Abilities registered on wp_abilities_api_init.&lt;/li&gt;
&lt;li&gt;Each ability includes meta.mcp.public = true.&lt;/li&gt;
&lt;li&gt;Admin capability check (recommended: manage_options).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;- Abilities code example (minimal) *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Register on wp_abilities_api_init
wp_register_ability('your-plugin/create-post', [
  'label' =&amp;gt; 'Create Post',
  'description' =&amp;gt; 'Create a WordPress post',
  'input_schema' =&amp;gt; [
    'type' =&amp;gt; 'object',
    'properties' =&amp;gt; [
      'title' =&amp;gt; ['type' =&amp;gt; 'string'],
      'content' =&amp;gt; ['type' =&amp;gt; 'string'],
      'status' =&amp;gt; ['type' =&amp;gt; 'string', 'default' =&amp;gt; 'draft']
    ],
    'required' =&amp;gt; ['title','content']
  ],
  'execute_callback' =&amp;gt; function($input){
    return wp_insert_post([
      'post_title' =&amp;gt; $input['title'],
      'post_content' =&amp;gt; $input['content'],
      'post_status' =&amp;gt; $input['status'] ?? 'draft'
    ]);
  },
  'permission_callback' =&amp;gt; function(){
    return current_user_can('manage_options');
  },
  'meta' =&amp;gt; [
    'mcp' =&amp;gt; [
      'public' =&amp;gt; true,
      'type' =&amp;gt; 'tool'
    ]
  ]
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: Install and activate MCP Adapter&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command (WP-CLI):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd "/path/to/wordpress"&lt;br&gt;
wp plugin install mcp-adapter --activate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can also activate via WP Admin → Plugins → Installed Plugins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install and activate the Abilities Provider plugin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the plugin, then activate it in WP Admin. This is required for content actions to appear as MCP tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configure MCP client (HTTP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the MCP WordPress remote proxy to connect over HTTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "mcpServers": {
    "wordpress-local": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "http://your-site.local/wp-json/mcp/mcp-adapter-default-server",
        "WP_API_USERNAME": "admin",
        "WP_API_PASSWORD": "YOUR_APP_PASSWORD"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Verify MCP server in your editor&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open View → Command Palette → MCP: Open MCP Settings&lt;/li&gt;
&lt;li&gt;Confirm the server is listed and has no errors&lt;/li&gt;
&lt;li&gt;Reload the editor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 5: List tools and execute an ability&lt;br&gt;
&lt;strong&gt;Command (MCP tools/list)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
**Command (Execute ability)**:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"mcp-adapter-execute-ability","arguments":{"ability_name":"your-plugin/create-post","parameters":{"title":"Example","content":"Hello from MCP","status":"draft"}}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Commands&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tools/list — list MCP tools&lt;/li&gt;
&lt;li&gt;tools/call — execute a tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default endpoint: /wp-json/mcp/mcp-adapter-default-server&lt;/li&gt;
&lt;li&gt;Transport: HTTP or STDIO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Logic&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MCP connects to WordPress&lt;/li&gt;
&lt;li&gt;MCP discovers tools (abilities)&lt;/li&gt;
&lt;li&gt;MCP executes tools to read/write content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Expected Result&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP client can list tools&lt;/li&gt;
&lt;li&gt;MCP can create or update posts through abilities
&lt;strong&gt;FAQ&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;**Q: What should I watch out for?&lt;br&gt;
**Sometimes the agent output lands as one big Classic block. Convert it to blocks once, and the content renders correctly.&lt;/p&gt;

&lt;p&gt;**Q: Can an agent write in blocks?&lt;br&gt;
**Yes. Send Gutenberg block markup (&amp;lt;!-- wp:... --&amp;gt;) in the content so WordPress opens it as blocks instead of Classic.&lt;/p&gt;

&lt;p&gt;**Q: Do I need to write custom code?&lt;br&gt;
**Yes. The MCP Adapter only exposes abilities that are explicitly marked meta.mcp.public=true.&lt;/p&gt;

&lt;p&gt;**Q: Why does WP-CLI fail on Local?&lt;br&gt;
**Local uses a site-specific MySQL socket. If WP-CLI cannot connect, pass the socket via WP_CLI_DB_HOST.&lt;/p&gt;

&lt;p&gt;**Q: Is STDIO safe for production?&lt;br&gt;
**STDIO is intended for local development. Use HTTP with Application Passwords for production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install MCP Adapter, activate an abilities provider plugin, configure your MCP client, and use MCP tools to create or update content. Keep abilities admin‑only and expose only what you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wordpress.com/blog/2025/10/07/mcp/" rel="noopener noreferrer"&gt;WordPress.com: See Your Site Through AI (MCP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/WordPress/mcp-adapter" rel="noopener noreferrer"&gt;WordPress MCP Adapter (official repository)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/4wpdev/4wp-mcp-abilities" rel="noopener noreferrer"&gt;4wp-mcp-abilities (public reference repo)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Automattic" rel="noopener noreferrer"&gt;Automattic on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Thanks to the Automattic team for making MCP Adapter possible.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>tutorial</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Step 2: Essential Theme Files – Core WordPress Theme Structure</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Wed, 27 Aug 2025 09:01:19 +0000</pubDate>
      <link>https://forem.com/adovgun/step-2-essential-theme-files-core-wordpress-theme-structure-36ig</link>
      <guid>https://forem.com/adovgun/step-2-essential-theme-files-core-wordpress-theme-structure-36ig</guid>
      <description>&lt;h2&gt;
  
  
  Step 2: Essential Theme Files
&lt;/h2&gt;

&lt;p&gt;Create the core files required for a WordPress Full Site Editor theme using the 4WP Starter Theme* as our foundation for Personal Branding and Corporate sites.&lt;/p&gt;

&lt;p&gt;Project Foundation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base Theme: 4WP Starter Theme* - FSE starter theme built for developers&lt;/li&gt;
&lt;li&gt;Theme Name: 4WP Starter Theme* (customize for your project)&lt;/li&gt;
&lt;li&gt;Use Cases: Personal Branding Site and Corporate websites&lt;/li&gt;
&lt;li&gt;License: MIT License (developer-friendly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essential Files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;style.css - Theme header and metadata (REQUIRED)&lt;/li&gt;
&lt;li&gt;theme.json - FSE configuration and design tokens (REQUIRED)&lt;/li&gt;
&lt;li&gt;templates/index.html - Main FSE template (REQUIRED for theme functionality)&lt;/li&gt;
&lt;li&gt;functions.php - Theme functionality and hooks (recommended for professional themes)&lt;/li&gt;
&lt;li&gt;screenshot.png - Theme preview image (1200x900px, WordPress standard)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Integration:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://github.com/4wpdev/4wp-starter-theme" rel="noopener noreferrer"&gt;4WP Starter Theme*&lt;/a&gt; repository (🚧 under development - use your own theme name for production) provides:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Version control: Git-based development workflow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collaboration: Issues, pull requests, and community contributions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: README.md with setup instructions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Licensing: Clear MIT license for commercial and personal use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates: Regular improvements and WordPress compatibility updates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Step:
&lt;/h2&gt;

&lt;p&gt;Configure Composer for dependency management and modern PHP development practices with the 4WP Starter Theme* foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Completed Step:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/adovgun/step-1-basic-theme-structure-fse-theme-development-3bpb"&gt;Basic FSE theme structure and WordPress development fundamentals established with proper directory organization and security practices.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;===&lt;br&gt;
Resources &amp;amp; References&lt;br&gt;
Full Course on GitHub: &lt;a href="https://github.com/4wpdev/4wp-course-fse-theme-development" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-course-fse-theme-development&lt;/a&gt;&lt;br&gt;
Theme Code on GitHub: &lt;a href="https://github.com/4wpdev/4wp-starter-theme" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-starter-theme&lt;/a&gt;&lt;br&gt;
Course for WordPress developers: &lt;a href="https://4wp.dev/course/fse-theme-development/" rel="noopener noreferrer"&gt;https://4wp.dev/course/fse-theme-development/&lt;/a&gt;&lt;br&gt;
Author Fullstack WordPress developer: &lt;a href="https://anatoliy.dovgun.com/" rel="noopener noreferrer"&gt;https://anatoliy.dovgun.com/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Step 1: Basic Theme Structure – FSE Theme Development</title>
      <dc:creator>Anatoliy Dovgun</dc:creator>
      <pubDate>Tue, 26 Aug 2025 10:40:15 +0000</pubDate>
      <link>https://forem.com/adovgun/step-1-basic-theme-structure-fse-theme-development-3bpb</link>
      <guid>https://forem.com/adovgun/step-1-basic-theme-structure-fse-theme-development-3bpb</guid>
      <description>&lt;h2&gt;
  
  
  Step 1: Basic Theme Structure
&lt;/h2&gt;

&lt;p&gt;Create the fundamental folder structure for a Full Site Editor (FSE) theme following WordPress best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Snippet:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd wp-content/themes/starry&lt;br&gt;
mkdir -p {assets/{css,js,images},inc,parts,patterns,styles,templates}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What This Creates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assets/ – Static files (CSS, JS, images)&lt;/li&gt;
&lt;li&gt;inc/ – PHP includes and functions&lt;/li&gt;
&lt;li&gt;parts/ – Template parts (header, footer, etc.)&lt;/li&gt;
&lt;li&gt;patterns/ – Block patterns&lt;/li&gt;
&lt;li&gt;styles/ – Theme style variations&lt;/li&gt;
&lt;li&gt;templates/ – HTML template files&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Step:
&lt;/h2&gt;

&lt;p&gt;After creating the structure, we’ll add the essential theme files (style.css, theme.json, functions.php).&lt;/p&gt;

&lt;p&gt;===&lt;br&gt;
Resources &amp;amp; References&lt;br&gt;
Full Course on GitHub: &lt;a href="https://github.com/4wpdev/4wp-course-fse-theme-development" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-course-fse-theme-development&lt;/a&gt;&lt;br&gt;
Theme Code on GitHub: &lt;a href="https://github.com/4wpdev/4wp-starter-theme" rel="noopener noreferrer"&gt;https://github.com/4wpdev/4wp-starter-theme&lt;/a&gt;&lt;br&gt;
Course for WordPress developers: &lt;a href="https://4wp.dev/course/fse-theme-development/" rel="noopener noreferrer"&gt;https://4wp.dev/course/fse-theme-development/&lt;/a&gt;&lt;br&gt;
Author Fullstack WordPress developer: &lt;a href="https://anatoliy.dovgun.com/" rel="noopener noreferrer"&gt;https://anatoliy.dovgun.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fse</category>
      <category>wordpress</category>
      <category>4wpdev</category>
      <category>gutenberg</category>
    </item>
  </channel>
</rss>
