<?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>DEV Community: Matt Hummel</title>
    <description>The latest articles on DEV Community by Matt Hummel (@matthummeldev).</description>
    <link>https://dev.to/matthummeldev</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2686545%2Fad0735c5-f154-48b7-83d7-5fe213cf56e4.jpeg</url>
      <title>DEV Community: Matt Hummel</title>
      <link>https://dev.to/matthummeldev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matthummeldev"/>
    <language>en</language>
    <item>
      <title>WordPress 7.2: Release Date, Features, and What to Test</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Fri, 23 Oct 2026 00:41:18 +0000</pubDate>
      <link>https://dev.to/matthummeldev/wordpress-72-release-date-features-and-what-to-test-405j</link>
      <guid>https://dev.to/matthummeldev/wordpress-72-release-date-features-and-what-to-test-405j</guid>
      <description>&lt;p&gt;WordPress 7.2 is scheduled to ship on &lt;strong&gt;December 8, 2026&lt;/strong&gt;. Beta 1 landed October 20, and the first release candidate follows on November 17.&lt;/p&gt;

&lt;p&gt;The headline items are a new default theme called Ipsum, a suggestion mode for Notes, a Secrets API for storing credentials, and form styling in Global Styles. Nothing is locked until RC 1, though. The core team only ships roadmap items that are "reasonably ready."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F368rwwlemon6ib207f97.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F368rwwlemon6ib207f97.webp" alt="WordPress 7.2 release timeline from Beta 1 on October 20 through RC 3 on December 1 to the December 8 release" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Release schedule
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Milestone&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Beta 1&lt;/td&gt;
&lt;td&gt;October 20&lt;/td&gt;
&lt;td&gt;Feature freeze, testing starts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Betas 2–4&lt;/td&gt;
&lt;td&gt;October 27, November 3, November 10&lt;/td&gt;
&lt;td&gt;Bug fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RC 1&lt;/td&gt;
&lt;td&gt;November 17&lt;/td&gt;
&lt;td&gt;Field Guide out, hard string freeze&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RC 2–3&lt;/td&gt;
&lt;td&gt;November 24, December 1&lt;/td&gt;
&lt;td&gt;Final fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dry run&lt;/td&gt;
&lt;td&gt;December 7&lt;/td&gt;
&lt;td&gt;24-hour code freeze&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;December 8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;WordPress 7.2 ships&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dates come from the &lt;a href="https://make.wordpress.org/core/7-2/" rel="noopener noreferrer"&gt;official 7.2 release page&lt;/a&gt;. The earlier &lt;a href="https://make.wordpress.org/core/2026/08/12/wordpress-7-2-call-for-volunteers/" rel="noopener noreferrer"&gt;call for volunteers&lt;/a&gt; gave a December 8 to 10 window, so a day of slip wouldn't be a surprise. Matt Mullenweg is release lead, David Baumwald handles release coordination, and George Mamadashvili and Peter Wilson are tech leads.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in WordPress 7.2
&lt;/h2&gt;

&lt;p&gt;The full list is in the &lt;a href="https://make.wordpress.org/core/2026/09/18/roadmap-to-7-2/" rel="noopener noreferrer"&gt;Roadmap to 7.2&lt;/a&gt;. These are the changes most site owners and developers will notice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ipsum, the new default theme
&lt;/h3&gt;

&lt;p&gt;Ipsum is a minimal, blank-canvas blog theme, and the first default theme in years without a year in its name. Expect a plainer starting point than Twenty Twenty-Five.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notes: suggestion mode and reactions
&lt;/h3&gt;

&lt;p&gt;Notes are block-level comments on a draft. Suggestion mode would let editors propose changes the author accepts or rejects, like tracked changes in a word processor. Emoji reactions and a toolbar shortcut for adding a note are planned too. Suggestion mode is still a large change in review, so the smaller Notes updates could ship without it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secrets API and application password alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application passwords:&lt;/strong&gt; you'll get an email when a new one is added to your account. That's a useful tripwire for account takeovers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets API:&lt;/strong&gt; a standard place in core to store credentials like API keys, instead of every plugin rolling its own (often plain options). WP-CLI support comes first; a settings screen is planned for 7.3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sudo mode&lt;/strong&gt; (re-entering your password before risky admin actions) is on the list but has no public proposal yet, so it may slip to 7.3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Form styling in Global Styles
&lt;/h3&gt;

&lt;p&gt;Global Styles gets UI for styling buttons, text inputs, selects, and labels, including hover and focus states. Block settings may also start showing the value a block inherits from Global Styles, with a way to reset an override. That design is still open.&lt;/p&gt;

&lt;h3&gt;
  
  
  New and updated blocks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Description List:&lt;/strong&gt; a block for &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;dt&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;dd&amp;gt;&lt;/code&gt; markup. Good for glossaries and spec sheets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table of Contents:&lt;/strong&gt; moves to server-side rendering and is set to become stable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Icon block:&lt;/strong&gt; search icons by keyword, not just by label.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactivity API:&lt;/strong&gt; a new &lt;code&gt;data-wp-html&lt;/code&gt; directive for rendering trusted markup, plus router fixes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Admin, accessibility, and performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clearer error messages with a copy button.&lt;/li&gt;
&lt;li&gt;Admin notices that screen readers announce properly and that can be dismissed with the keyboard.&lt;/li&gt;
&lt;li&gt;Automated axe-core accessibility checks in core's test suite.&lt;/li&gt;
&lt;li&gt;An "On This Day" dashboard widget, back for another try after being pulled from 7.1.&lt;/li&gt;
&lt;li&gt;Admin script and style concatenation replaced with prefetching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI work, mostly in the AI plugin
&lt;/h3&gt;

&lt;p&gt;Most AI work this cycle lives in the official AI plugin, not core. The plan adds read-only abilities for media, taxonomies, and comments, and puts the MCP Adapter in the Plugin Directory. MCP (Model Context Protocol) is the standard that lets AI tools talk to your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's not coming in 7.2
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time collaboration:&lt;/strong&gt; left out and being reworked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React 19:&lt;/strong&gt; far along, but unlikely to fully land.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets settings screen:&lt;/strong&gt; planned for 7.3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible Site Editor:&lt;/strong&gt; groundwork continues through 7.3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to test WordPress 7.2 before release
&lt;/h2&gt;

&lt;p&gt;Use a staging copy, never a live site.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make a staging copy and take a fresh backup.&lt;/li&gt;
&lt;li&gt;Install the &lt;a href="https://wordpress.org/plugins/wordpress-beta-tester/" rel="noopener noreferrer"&gt;WordPress Beta Tester&lt;/a&gt; plugin. Go to Tools → Beta Testing, pick the bleeding edge channel and the beta/RC stream, then update from Dashboard → Updates.&lt;/li&gt;
&lt;li&gt;Or use WP-CLI on staging: &lt;code&gt;wp core update --version=7.2-beta1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click through forms, custom blocks, and any admin screens your plugins add.&lt;/li&gt;
&lt;li&gt;Check front-end buttons and inputs, since the new form styling touches them.&lt;/li&gt;
&lt;li&gt;Report bugs on &lt;a href="https://core.trac.wordpress.org/" rel="noopener noreferrer"&gt;Core Trac&lt;/a&gt; or in the Gutenberg GitHub repo.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Should you update on release day?
&lt;/h2&gt;

&lt;p&gt;Take a full backup first either way, as the &lt;a href="https://wordpress.org/documentation/article/updating-wordpress/" rel="noopener noreferrer"&gt;official Updating WordPress guide&lt;/a&gt; recommends.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your site&lt;/th&gt;
&lt;th&gt;When to update&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Personal blog, few plugins&lt;/td&gt;
&lt;td&gt;Release week&lt;/td&gt;
&lt;td&gt;Low risk, and a backup covers you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business site you manage&lt;/td&gt;
&lt;td&gt;After testing on staging&lt;/td&gt;
&lt;td&gt;Forms and checkout are where updates break things&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client sites&lt;/td&gt;
&lt;td&gt;After the first point release&lt;/td&gt;
&lt;td&gt;Plugins have time to ship fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any site, security release&lt;/td&gt;
&lt;td&gt;Right away&lt;/td&gt;
&lt;td&gt;Security fixes close known holes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;AI assisted with drafting this post. I reviewed and edited it before publishing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://matthummel.com/wordpress-7-2/" rel="noopener noreferrer"&gt;matthummel.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
      <category>php</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why I Built a Claude Code Playbook for WordPress</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Thu, 15 Oct 2026 02:29:39 +0000</pubDate>
      <link>https://dev.to/matthummeldev/why-i-built-a-claude-code-playbook-for-wordpress-121l</link>
      <guid>https://dev.to/matthummeldev/why-i-built-a-claude-code-playbook-for-wordpress-121l</guid>
      <description>&lt;p&gt;I keep my Claude Code rules for WordPress in one public GitHub repo, and every machine I use pulls it at the start of the next session. I built it because my rules kept drifting between projects and costing tokens I didn't need to spend.&lt;/p&gt;

&lt;p&gt;This post covers why I made the &lt;a href="https://github.com/matthummel-pa/ai-dev-standards-playbook" rel="noopener noreferrer"&gt;AI Dev Standards &amp;amp; Playbook&lt;/a&gt;, what's in it, and how it changed the way I work with Claude Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy4tjap0cnxdxyck99ddj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy4tjap0cnxdxyck99ddj.webp" alt="Claude Code playbook graphic: one playbook, every project, with rules, skills and /pb:ship chips" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One repo holds my coding standards, SEO rules, writing voice, reference docs, slash commands, a reviewer agent and a deploy kit.&lt;/li&gt;
&lt;li&gt;Only one rule is always on, and it's under 1 KB. Everything else loads by file path or when a skill is used.&lt;/li&gt;
&lt;li&gt;A SessionStart hook pulls &lt;code&gt;main&lt;/code&gt; and reinstalls on every new Claude Code session, so one merge updates every machine.&lt;/li&gt;
&lt;li&gt;The repo is public and generic. Client facts stay in each project's own &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/matthummel-pa/ai-dev-standards-playbook" rel="noopener noreferrer"&gt;github.com/matthummel-pa/ai-dev-standards-playbook&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://matthummel-pa.github.io/ai-dev-standards-playbook/" rel="noopener noreferrer"&gt;matthummel-pa.github.io/ai-dev-standards-playbook&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why did I build a Claude Code playbook?
&lt;/h2&gt;

&lt;p&gt;Two problems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;My rules lived inside one theme repo, so they didn't follow me to the next client.&lt;/li&gt;
&lt;li&gt;They were all always on, so every session paid for every line whether it needed them or not.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When I pulled the rules out of my &lt;a href="https://matthummel.com/ai-workflow-for-wordpress-development/" rel="noopener noreferrer"&gt;matthummel.com theme&lt;/a&gt;, I had ten always-on rule files. Together they were about 60 KB, loaded into every session. Most of it was WordPress and Sage detail that only matters when I'm editing a PHP or Blade file. Claude Code loads rules at session start, so that 60 KB rode along even when I was writing a blog post.&lt;/p&gt;

&lt;p&gt;The fix was to split by trigger. The core rule is now 0.9 KB. The rest only load when Claude touches a matching file or picks a skill. Same standards, a fraction of the context.&lt;/p&gt;

&lt;p&gt;What tipped me over was typing the same prompts again and again. Every new session started with me pasting the same security rules, the same accessibility checks and the same "answer first" note. Each of those prompts counted against my credits.&lt;/p&gt;

&lt;p&gt;I wanted the rules to already be there, and I wanted the always-on part as small as possible so each session cost less.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the playbook load into Claude Code?
&lt;/h2&gt;

&lt;p&gt;Claude Code reads rules, skills and commands from &lt;code&gt;~/.claude&lt;/code&gt;, and a SessionStart hook can run a script before each session. The playbook uses both.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;install.sh&lt;/code&gt; copies the repo into &lt;code&gt;~/.claude&lt;/code&gt; once and adds the hook. From then on, every new session runs &lt;code&gt;sync.sh&lt;/code&gt;, which does a &lt;code&gt;git pull --ff-only&lt;/code&gt; and recopies the files. If nothing changed, it prints nothing.&lt;/p&gt;

&lt;p&gt;I use copies, not symlinks, on purpose. Symlinks need Developer Mode on Windows, and Claude Code loads &lt;code&gt;~/.claude/rules/&lt;/code&gt; without an approval prompt when the files are plain copies.&lt;/p&gt;

&lt;p&gt;One catch: rules load at session start, so a merge shows up in the session &lt;em&gt;after&lt;/em&gt; the one that pulled it. When I want it right away, I run &lt;code&gt;sync.sh&lt;/code&gt; by hand and restart.&lt;/p&gt;

&lt;p&gt;Here's how the layers fit together:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Loads&lt;/th&gt;
&lt;th&gt;Use it for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rules/core.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every session&lt;/td&gt;
&lt;td&gt;5 to 10 lines that are true everywhere&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path rules (&lt;code&gt;paths:&lt;/code&gt; in frontmatter)&lt;/td&gt;
&lt;td&gt;When Claude reads or edits a matching file&lt;/td&gt;
&lt;td&gt;Coding standards per file type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skills (&lt;code&gt;SKILL.md&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Description always; body only when used&lt;/td&gt;
&lt;td&gt;Long playbooks: writing, SEO, architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commands (&lt;code&gt;/pb:…&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Only when I type them&lt;/td&gt;
&lt;td&gt;Repeatable workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project &lt;code&gt;CLAUDE.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Every session in that repo&lt;/td&gt;
&lt;td&gt;Project facts, commands, hard no's&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What's in the repo?
&lt;/h2&gt;

&lt;p&gt;Eight folders. Here's what each one does and when it loads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rules
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;core.md&lt;/code&gt; is the only always-on file. It covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answer first&lt;/li&gt;
&lt;li&gt;Work on a branch&lt;/li&gt;
&lt;li&gt;Read before editing&lt;/li&gt;
&lt;li&gt;Sanitize and escape&lt;/li&gt;
&lt;li&gt;WCAG 2.1 AA&lt;/li&gt;
&lt;li&gt;Never invent metrics&lt;/li&gt;
&lt;li&gt;Verify versioned APIs against official docs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The other rules load by path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WordPress rules:&lt;/strong&gt; &lt;code&gt;*.php&lt;/code&gt;, &lt;code&gt;theme.json&lt;/code&gt; and &lt;code&gt;block.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sage rules:&lt;/strong&gt; &lt;code&gt;app/&lt;/code&gt;, &lt;code&gt;resources/&lt;/code&gt; and &lt;code&gt;vite.config.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO rules:&lt;/strong&gt; Blade templates and SEO code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Skills
&lt;/h3&gt;

&lt;p&gt;A skill is a folder with a &lt;code&gt;SKILL.md&lt;/code&gt; that Claude loads on demand. I have six so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;doc-references&lt;/strong&gt;: the official docs for my stack (WordPress Developer Resources, Roots, Tailwind, MDN, the WHATWG HTML spec, W3C and the ARIA APG, web.dev, caniuse, TypeScript, React, Next.js, Node, NestJS) and a rule to check them before writing code against an API I haven't verified that session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;content-writer&lt;/strong&gt;: my editorial voice and readability rules for posts and site copy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;growth-design&lt;/strong&gt;: landing page, conversion copy and design review guidance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;portfolio-seo&lt;/strong&gt;: on-page limits for portfolio and service pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;geo-blog-post&lt;/strong&gt;: blog structure for Google AI Overviews and LLM search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sage-architecture&lt;/strong&gt;: ACF Pro fields registered in PHP, a Customizer dark-mode default, the Tailwind v4 and &lt;code&gt;theme.json&lt;/code&gt; token bridge, and CI/CD for built themes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Commands, agent and hook
&lt;/h3&gt;

&lt;p&gt;I have five slash commands, namespaced so they never shadow a project's own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/pb:new-project&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/pb:plan&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/pb:fix&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/pb:review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/pb:ship&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;wp-reviewer&lt;/code&gt; agent reads a diff against the WordPress Developer Handbook before I open a pull request.&lt;/p&gt;

&lt;p&gt;A PostToolUse hook runs PHPCS on every PHP file Claude edits and sends the errors straight back, so Claude fixes them before moving on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project template
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/pb:new-project&lt;/code&gt; drops a kit into a theme repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;CLAUDE.md&lt;/code&gt; under 2 KB&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;.claude/settings.json&lt;/code&gt; with safe permissions and a &lt;code&gt;WebFetch&lt;/code&gt; allowlist for every doc site in &lt;code&gt;doc-references&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A GitHub Actions workflow that builds the theme, swaps it over SSH, runs a health check and rolls back on failure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do I use the rules and skills?
&lt;/h2&gt;

&lt;p&gt;I don't call them. Claude Code picks them up from what I'm doing and what I type.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rules watch the files.&lt;/strong&gt; Each rule has a &lt;code&gt;paths:&lt;/code&gt; list in its frontmatter. Open a &lt;code&gt;.php&lt;/code&gt; file and the WordPress rules are in context. Open a Blade template and the Sage and SEO rules are there. I never mention them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills watch the prompt.&lt;/strong&gt; Claude always sees each skill's one-line description and loads the full &lt;code&gt;SKILL.md&lt;/code&gt; only when my request matches it. If I say "draft a blog post about X," &lt;code&gt;geo-blog-post&lt;/code&gt; and &lt;code&gt;content-writer&lt;/code&gt; load. If I say "add an ACF field for the hero," &lt;code&gt;sage-architecture&lt;/code&gt; loads. If I ask what &lt;code&gt;wp_insert_post()&lt;/code&gt; returns, &lt;code&gt;doc-references&lt;/code&gt; loads and Claude fetches the handbook page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commands wait for me.&lt;/strong&gt; &lt;code&gt;/pb:fix add a skip link to the header&lt;/code&gt; runs the fix-and-ship workflow. &lt;code&gt;/pb:review&lt;/code&gt; runs the reviewer agent on the branch. Nothing happens until I type the slash.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why the descriptions matter more than the bodies. A skill with a vague description never loads, and one with a sharp description loads at the right moment. When a skill isn't firing, I fix the description, not the prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it help me develop with Claude Code?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Consistency.&lt;/strong&gt; Every client site gets the same security checks, the same accessibility bar and the same review before a PR. I don't paste rules into a new &lt;code&gt;CLAUDE.md&lt;/code&gt; each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer stale answers.&lt;/strong&gt; The &lt;code&gt;doc-references&lt;/code&gt; skill tells Claude to fetch the official page before writing against a hook, a Tailwind v4 feature or a Next.js API. The project settings pre-approve those domains, so the fetch never stops for a permission prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cheaper sessions.&lt;/strong&gt; The always-on context went from about 60 KB to under 1 KB, and I stopped re-sending the same rules by hand at the start of each session. Smaller prompts, fewer credits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One place to fix things.&lt;/strong&gt; When Claude gets something wrong twice, I change the rule once, open a PR, and the fix lands everywhere the next day. The repo's CI checks frontmatter, the core rule's size budget and a blocklist for private details, so I can't merge a client host name by mistake.&lt;/p&gt;

&lt;h2&gt;
  
  
  What stays out of the repo?
&lt;/h2&gt;

&lt;p&gt;Anything that names a client. Hosts, paths, plugin lists, logins and product catalogs live in each project's &lt;code&gt;CLAUDE.md&lt;/code&gt; and &lt;code&gt;.claude/rules/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The playbook is public, so &lt;code&gt;validate.py&lt;/code&gt; scans every file for patterns like application passwords, GitHub tokens and private keys. It fails the build if one shows up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you build your own?
&lt;/h2&gt;

&lt;p&gt;If you use Claude Code on more than one repo, yes. Start smaller than I did:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put five lines in a core rule.&lt;/li&gt;
&lt;li&gt;Move one long checklist into a skill.&lt;/li&gt;
&lt;li&gt;Add the sync hook.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll know within a week whether it's worth growing. Anthropic's guide on &lt;a href="https://claude.com/resources/articles/steering-claude-code-skills-hooks-rules-subagents-and-more" rel="noopener noreferrer"&gt;when to use CLAUDE.md, skills, hooks and subagents&lt;/a&gt; is a good overview of how the pieces fit together.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://matthummel.com/claude-code-playbook-wordpress/" rel="noopener noreferrer"&gt;matthummel.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>wordpress</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Website Basics for New Developers and Business Owners</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Tue, 13 Oct 2026 03:54:27 +0000</pubDate>
      <link>https://dev.to/matthummeldev/website-basics-for-new-developers-and-business-owners-26fe</link>
      <guid>https://dev.to/matthummeldev/website-basics-for-new-developers-and-business-owners-26fe</guid>
      <description>&lt;p&gt;The website basics are the same whether you build sites or own one: where a site lives and how it changes without breaking. Anyone learning to build sites has to pick these up early. An owner who knows even a little of this gets more out of every developer they hire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Website basics at a glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A website is files and a database on a server. People reach it through a domain name.&lt;/li&gt;
&lt;li&gt;Before any framework, a new developer needs HTML, CSS, JavaScript, and Git.&lt;/li&gt;
&lt;li&gt;Owners should have every account in their own name and know when the last backup ran.&lt;/li&gt;
&lt;li&gt;Test changes on a staging site, a private copy of the live one, before visitors see them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does a website work?
&lt;/h2&gt;

&lt;p&gt;A website is a set of files and a database on a rented computer, reached through a name you rent. Your browser asks for the name. DNS turns that name into the server's address, and the server sends back the page. On a WordPress site, the server builds each page with PHP before it sends it.&lt;/p&gt;

&lt;p&gt;DNS stands for Domain Name System. PHP is the programming language WordPress is written in.&lt;/p&gt;

&lt;p&gt;Every site has the same pieces, and each piece has its own account.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;Where the account lives&lt;/th&gt;
&lt;th&gt;Who should own it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;td&gt;Your address, like example.com&lt;/td&gt;
&lt;td&gt;A registrar, the company that sells domain names&lt;/td&gt;
&lt;td&gt;The business owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS&lt;/td&gt;
&lt;td&gt;The settings that point your domain at your host and your email&lt;/td&gt;
&lt;td&gt;Your registrar, your host, or a service like Cloudflare&lt;/td&gt;
&lt;td&gt;The business owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;The server that stores your site's files and database&lt;/td&gt;
&lt;td&gt;A hosting company&lt;/td&gt;
&lt;td&gt;The business owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress&lt;/td&gt;
&lt;td&gt;The software that runs your site&lt;/td&gt;
&lt;td&gt;Installed on your hosting&lt;/td&gt;
&lt;td&gt;The owner, with an Administrator account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paid themes and plugins&lt;/td&gt;
&lt;td&gt;Add-ons with a yearly license&lt;/td&gt;
&lt;td&gt;Each vendor's site&lt;/td&gt;
&lt;td&gt;The owner, or the developer with the license written down&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;DNS is the piece people forget. It's also the one that takes email down when it changes by mistake.&lt;/p&gt;

&lt;p&gt;This table is the core of it. It's worth being able to explain from memory, whichever side of the project you're on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should beginner web developers learn first?
&lt;/h2&gt;

&lt;p&gt;Learn what every site shares before you learn a framework. That means HTML, CSS, JavaScript, Git, how a page travels from server to browser, and how to read an error. After that come the habits clients end up paying for, like security, accessibility, and speed.&lt;/p&gt;

&lt;p&gt;I taught myself, and I wrote about it in &lt;a href="https://matthummel.com/self-taught-wordpress-developer/" rel="noopener noreferrer"&gt;how I became a self-taught WordPress developer&lt;/a&gt;. This is the order I'd follow now.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML and CSS.&lt;/strong&gt; Use the right tag for the job, and learn the box model, flexbox, and grid. Build one full page with no framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript.&lt;/strong&gt; Learn events, the DOM, and &lt;code&gt;fetch&lt;/code&gt; before React or any other library. The DOM is the browser's live copy of your page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How a request works.&lt;/strong&gt; Open your browser's developer tools and watch the Network tab. Know what a 404 and a 500 mean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git.&lt;/strong&gt; Get used to small commits and working on a branch, then put your first project on GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors and docs.&lt;/strong&gt; Read the error message before you search for it. In WordPress, turn on &lt;code&gt;WP_DEBUG_LOG&lt;/code&gt; on your local site and read &lt;code&gt;wp-content/debug.log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security.&lt;/strong&gt; Never trust input. In WordPress that means you sanitize what comes in, escape what goes out, and check a nonce and the user's capability before you save anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility.&lt;/strong&gt; One &lt;code&gt;h1&lt;/code&gt;, headings in order, alt text on images, and a page that works with the keyboard alone. The quickest test is to put the mouse away and tab through the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed.&lt;/strong&gt; Oversized images are the usual first thing to fix. Test on a real phone, and run your pages through &lt;a href="https://pagespeed.web.dev" rel="noopener noreferrer"&gt;PageSpeed Insights&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Talking to clients.&lt;/strong&gt; Put the scope in writing, and be honest about what you don't know yet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A nonce is a short-lived token that proves a request came from your own form.&lt;/p&gt;

&lt;p&gt;The one thing I wish I'd learned sooner is to stop studying and start building. I spent way too much time on online courses and tutorials. Once you've learned something, go use it on a real project, or you'll get stuck in a tutorial cycle that never ends.&lt;/p&gt;

&lt;p&gt;I'd also learn a few things at a time. You don't need to know everything at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should a business owner understand about their website?
&lt;/h2&gt;

&lt;p&gt;If you build sites, this is the section to send your clients.&lt;/p&gt;

&lt;p&gt;You can run a website well without writing code. For an owner, it comes down to knowing what you own and who runs the updates and backups. It also helps to know what your developer needs from you, and how to tell when something's broken.&lt;/p&gt;

&lt;h3&gt;
  
  
  Own every account
&lt;/h3&gt;

&lt;p&gt;Your domain, hosting, and WordPress login should be in your name, tied to an email you check. If they sit in a past developer's name, or a relative's, you can get locked out of your own site.&lt;/p&gt;

&lt;p&gt;Check it in 10 minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Look up your domain at &lt;a href="https://lookup.icann.org" rel="noopener noreferrer"&gt;lookup.icann.org&lt;/a&gt;. The result names your registrar.&lt;/li&gt;
&lt;li&gt;Log in to the registrar. Confirm the contact email is yours and turn on auto-renew.&lt;/li&gt;
&lt;li&gt;Log in to your hosting account. Confirm the billing is in your name.&lt;/li&gt;
&lt;li&gt;Log in to WordPress and open &lt;strong&gt;Users&lt;/strong&gt;. Confirm your role is Administrator.&lt;/li&gt;
&lt;li&gt;Save every login in a password manager.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've been on the wrong side of this one. I kept a client's domain in my own account. When it came time to transfer it and hand ownership back, it turned into a mess. In the end the client lost the domain altogether. It cost them time, and it cost me a good client relationship.&lt;/p&gt;

&lt;p&gt;If you build sites, don't keep a client's domain or hosting in your own account. Have them own it and add you as a user, never a shared password. When the job ends, they remove that user and nothing else changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates and backups are routine
&lt;/h3&gt;

&lt;p&gt;WordPress, your theme, and your plugins all get updates, and many of them fix security holes. Someone has to run them, so agree on who that is.&lt;/p&gt;

&lt;p&gt;A backup is a full copy of your files and database, kept somewhere other than your server. Ask two questions: when was the last backup, and has anyone ever restored one?&lt;/p&gt;

&lt;h3&gt;
  
  
  Your developer needs things from you
&lt;/h3&gt;

&lt;p&gt;Projects often stall in the first week because the developer is waiting on something. Bring this list to the first meeting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logins, or your own user account, for the domain, hosting, and WordPress.&lt;/li&gt;
&lt;li&gt;The main thing you want a visitor to do: call, book, buy, or fill out a form.&lt;/li&gt;
&lt;li&gt;Your logo files, photos, and the words for each page. If you need the words written, say so early, because it changes the quote.&lt;/li&gt;
&lt;li&gt;Two or three sites you like, with a note on what you like about each.&lt;/li&gt;
&lt;li&gt;A deadline and a budget range.&lt;/li&gt;
&lt;li&gt;One person who makes the final call. Feedback from five people with no tiebreaker stalls a project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time, what's missing is the content: photos, logos, and the words for the pages. Always get that collected in one place before the project starts.&lt;/p&gt;

&lt;p&gt;If you're on the other side of that meeting, this list makes a good intake form to send ahead of the first call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check that your site still works
&lt;/h3&gt;

&lt;p&gt;Once a month, send yourself a message through your own contact form. Then open the site on your phone and run the home page through &lt;a href="https://pagespeed.web.dev" rel="noopener noreferrer"&gt;PageSpeed Insights&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A broken contact form can sit for weeks before anyone notices.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a staging site, and why does it matter?
&lt;/h2&gt;

&lt;p&gt;A staging site is a private copy of your website where changes get tested before visitors see them. Updates, new plugins, and design changes go there first. If something breaks, it breaks on the copy. Ask any developer you hire where they test changes. If they say "on the live site," I'd keep looking.&lt;/p&gt;

&lt;p&gt;This part applies whether you build the site or own it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why it matters this fall
&lt;/h3&gt;

&lt;p&gt;WordPress 7.2 is the next major release. Beta 1 is scheduled for October 20 to 22, 2026, and the final release for December 8 to 10, according to the &lt;a href="https://developer.wordpress.org/news/2026/09/whats-new-for-developers-september-2026/" rel="noopener noreferrer"&gt;WordPress Developer Blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Security releases don't follow that calendar. &lt;a href="https://wordpress.org/documentation/wordpress-version/version-7-0-2/" rel="noopener noreferrer"&gt;WordPress 7.0.2&lt;/a&gt; shipped in July 2026 with a note to update right away. I covered a later one in &lt;a href="https://matthummel.com/wordpress-7-1-3-security-release/" rel="noopener noreferrer"&gt;what's new in WordPress 7.1.3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a staging site, you can apply an update like that the same day and know your contact form still works.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to get one
&lt;/h3&gt;

&lt;p&gt;Many hosts include staging in their plans. Ask your host, or check your hosting dashboard for a button labeled Staging. If your host doesn't offer it, your developer can set one up on a subdomain like staging.example.com.&lt;/p&gt;

&lt;h3&gt;
  
  
  What a safe update looks like
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Back up the live site.&lt;/li&gt;
&lt;li&gt;Copy the live site to staging.&lt;/li&gt;
&lt;li&gt;Run the updates on staging.&lt;/li&gt;
&lt;li&gt;Check the pages that make you money: home, contact form, booking, checkout.&lt;/li&gt;
&lt;li&gt;Run the same updates on the live site.&lt;/li&gt;
&lt;li&gt;Check those pages again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I learned how much step 1 matters when I managed a college's website. The backups got messed up, and users lost content edits they had already made. That's why the backup comes first on this list, and why it's worth restoring one now and then to prove it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  For developers: tell WordPress it's on staging
&lt;/h3&gt;

&lt;p&gt;Set the environment type in &lt;code&gt;wp-config.php&lt;/code&gt; on the staging copy only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// wp-config.php on the staging copy only.&lt;/span&gt;
&lt;span class="c1"&gt;// Place this above the "That's all, stop editing!" line.&lt;/span&gt;
&lt;span class="c1"&gt;// Allowed values: local, development, staging, production.&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'WP_ENVIRONMENT_TYPE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'staging'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check it in your theme or plugin before you load anything that belongs on the live site only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Print the analytics tag on the live site only.
 *
 * @return void
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;mh_print_analytics_tag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Returns 'production' when WP_ENVIRONMENT_TYPE is unset or invalid.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'production'&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nf"&gt;wp_get_environment_type&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Your analytics snippet goes here.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_head'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'mh_print_analytics_tag'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first block labels the copy as staging. The second one skips your analytics tag anywhere the label isn't &lt;code&gt;production&lt;/code&gt;, so test visits stay out of your reports.&lt;/p&gt;

&lt;p&gt;One catch: a site with no label counts as &lt;code&gt;production&lt;/code&gt;. Set &lt;code&gt;local&lt;/code&gt; on your own machine too, or your test visits will show up in your reports.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.wordpress.org/reference/functions/wp_get_environment_type/" rel="noopener noreferrer"&gt;&lt;code&gt;wp_get_environment_type()&lt;/code&gt;&lt;/a&gt; has been in WordPress since 5.5.0. Also check &lt;strong&gt;Settings &amp;gt; Reading&lt;/strong&gt; on staging and tick "Discourage search engines from indexing this site." That box is only a request, so put staging behind a password or basic auth too.&lt;/p&gt;

&lt;p&gt;I tested both snippets on WordPress 7.1.3 and PHP 8.3 in October 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should a beginner learn React or WordPress first?
&lt;/h3&gt;

&lt;p&gt;Learn HTML, CSS, and plain JavaScript first. Both React and WordPress sit on top of them. After that, pick the one that matches the work you want. For small business sites, I'd start with WordPress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can my web developer own my domain or hosting for me?
&lt;/h3&gt;

&lt;p&gt;They can manage both, but the accounts should stay in your name. Give your developer their own user, and if you part ways you remove that one user and keep everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need a staging site for a small website?
&lt;/h3&gt;

&lt;p&gt;Yes, if the site brings in bookings, sales, or leads. If the contact form breaks after an update, you may not find out for days. A five-page site with no forms can get by with a good backup.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if I can't find my logins?
&lt;/h3&gt;

&lt;p&gt;Start at &lt;a href="https://lookup.icann.org" rel="noopener noreferrer"&gt;lookup.icann.org&lt;/a&gt; to find your registrar. Then use the password reset on each account. If the reset email goes to an address you can't reach, contact the company's support and be ready to prove who you are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I turn on automatic updates in WordPress?
&lt;/h3&gt;

&lt;p&gt;Keep them on for minor releases. WordPress turns those on by default, and they carry security fixes. For major releases like 7.2, and for plugins your site depends on, I'd test on staging first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your next step
&lt;/h2&gt;

&lt;p&gt;If you're learning, pick one item from the developer list that you can't explain yet and build something small with it this week.&lt;/p&gt;

&lt;p&gt;For owners, the 10-minute ownership check is the place to start.&lt;/p&gt;

&lt;p&gt;Which of these did you learn the hard way? Tell me in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://matthummel.com/website-basics-for-new-developers-and-business-owners/" rel="noopener noreferrer"&gt;matthummel.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>wordpress</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>WordPress MCP Adapter: Connect Claude Code and Cursor to Your Site</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Sat, 10 Oct 2026 03:44:36 +0000</pubDate>
      <link>https://dev.to/matthummeldev/wordpress-mcp-adapter-connect-claude-code-and-cursor-to-your-site-3kee</link>
      <guid>https://dev.to/matthummeldev/wordpress-mcp-adapter-connect-claude-code-and-cursor-to-your-site-3kee</guid>
      <description>&lt;p&gt;The &lt;strong&gt;WordPress MCP Adapter&lt;/strong&gt; lets AI tools like Claude Code and Cursor find and run actions on your WordPress site. It takes the abilities you register with the Abilities API and shares them over the Model Context Protocol (MCP).&lt;/p&gt;

&lt;p&gt;Here’s the full setup: install the adapter, expose one ability, find the default endpoint, log in with an Application Password, and run a few safety checks.&lt;/p&gt;

&lt;p&gt;Already wired an AI tool to a WordPress site? Skip to the end and tell me how it went. I’d like to compare notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  At a glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Needs:&lt;/strong&gt; WordPress 6.9 or newer and PHP 7.4 or newer. WordPress 6.9 includes the Abilities API in core.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugin:&lt;/strong&gt; the official MCP Adapter from the WordPress GitHub organization. The latest release when I wrote this guide was 0.6.1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opt in:&lt;/strong&gt; an ability shows up on the default MCP server when its meta has &lt;code&gt;mcp.public&lt;/code&gt; set to true. A broader &lt;code&gt;public&lt;/code&gt; flag in meta works too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default endpoint:&lt;/strong&gt; &lt;code&gt;/wp-json/mcp/mcp-adapter-default-server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Login:&lt;/strong&gt; a WordPress user and an Application Password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try it on a local site first.&lt;/strong&gt; An AI tool gets the same rights as the user you connect it with.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What MCP is, in plain terms
&lt;/h2&gt;

&lt;p&gt;MCP is an open standard that gives AI apps a shared way to connect to outside tools and data. An MCP server lists the tools it offers. An MCP client, like Claude Code or Cursor, reads that list and can call those tools when you ask it to.&lt;/p&gt;

&lt;p&gt;WordPress already has its own way to describe actions, called the Abilities API. I covered it in my first Abilities API integration post. Each ability has a name, an input schema, an output schema, a permission check, and a callback. The MCP Adapter takes those abilities and puts them in a form an MCP client can read.&lt;/p&gt;

&lt;p&gt;Here’s how one request moves through the stack:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You ask Claude Code or Cursor a question.&lt;/li&gt;
&lt;li&gt;The client calls the adapter’s server on your site.&lt;/li&gt;
&lt;li&gt;The adapter looks up the matching ability.&lt;/li&gt;
&lt;li&gt;WordPress runs that ability’s permission check for the connected user, before any code executes.&lt;/li&gt;
&lt;li&gt;The result travels back to the client as structured data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;WordPress MCP Adapter diagram: a WordPress site in the center, connected to a terminal and a code editor, with lock, key, and shield icons for login and permissions&lt;/p&gt;

&lt;p&gt;!WordPress MCP Adapter diagram: a WordPress site in the center, connected to a terminal and a code editor, with lock, key, and shield icons for login and permissions&lt;/p&gt;

&lt;p&gt;WordPress MCP Adapter diagram: a WordPress site in the center, connected to a terminal and a code editor, with lock, key, and shield icons for login and permissions&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The WordPress MCP Adapter sits between your site and AI tools like Claude Code and Cursor.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install the WordPress MCP Adapter
&lt;/h2&gt;

&lt;p&gt;The adapter isn’t in core yet, so you add it yourself. You can install it as a plugin, or bundle it inside your own plugin as a Composer package. For a first test, I’d go with the plugin because it’s simpler.&lt;/p&gt;

&lt;p&gt;The Composer route makes sense once you ship a plugin that depends on the adapter. Running &lt;code&gt;composer require wordpress/mcp-adapter&lt;/code&gt; installs it alongside your own code, so the adapter travels with your plugin.&lt;/p&gt;

&lt;p&gt;To install the plugin:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the latest release from the WordPress/mcp-adapter repository.&lt;/li&gt;
&lt;li&gt;On a local or staging site, upload it as a plugin.&lt;/li&gt;
&lt;li&gt;Activate it, and check that your site runs WordPress 6.9 or newer.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads up:&lt;/strong&gt; the adapter is still under version 1.0, so names and commands may change from one release to the next. Before you copy anything below, read the README for the version you installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Mark an ability as public for MCP
&lt;/h2&gt;

&lt;p&gt;Registering an ability won’t share it with AI tools by itself. You have to opt in by adding &lt;code&gt;'mcp' =&amp;gt; array( 'public' =&amp;gt; true )&lt;/code&gt; inside the ability’s &lt;code&gt;meta&lt;/code&gt; array.&lt;/p&gt;

&lt;p&gt;That flag shares the ability over MCP and nothing else. The adapter README also describes a broader &lt;code&gt;public&lt;/code&gt; flag in &lt;code&gt;meta&lt;/code&gt;, which the default server honors too.&lt;/p&gt;

&lt;p&gt;Here’s a small example that only reads data. It returns the site name and tagline, and it only runs for users who can edit posts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_abilities_api_categories_init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;wp_register_ability_category&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'my-site'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'label'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'My Site'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Abilities for this site.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_abilities_api_init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;wp_register_ability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'my-site/get-site-info'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'label'&lt;/span&gt;               &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Get site info'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Returns the site name and tagline.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'category'&lt;/span&gt;            &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'my-site'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'output_schema'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'type'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'properties'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s1"&gt;'name'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s1"&gt;'tagline'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'execute_callback'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s1"&gt;'name'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_bloginfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s1"&gt;'tagline'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_bloginfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'permission_callback'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;current_user_can&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'edit_posts'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'meta'&lt;/span&gt;                &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'annotations'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'readonly'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s1"&gt;'mcp'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'public'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;readonly&lt;/code&gt; annotation tells clients this ability doesn’t change anything. The permission callback runs on every call, even when the request comes from an AI tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Know the default server endpoint
&lt;/h2&gt;

&lt;p&gt;Once the plugin is on, the adapter sets up a default MCP server. You’ll find it at this path on your site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-site.local/wp-json/mcp/mcp-adapter-default-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This server doesn’t list each public ability as its own tool. It offers three general tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One finds the public abilities.&lt;/li&gt;
&lt;li&gt;One gets details about a single ability.&lt;/li&gt;
&lt;li&gt;One runs an ability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The README calls them &lt;code&gt;mcp-adapter/discover-abilities&lt;/code&gt;, &lt;code&gt;mcp-adapter/get-ability-info&lt;/code&gt;, and &lt;code&gt;mcp-adapter/execute-ability&lt;/code&gt;. So the client finds your ability first, then calls it.&lt;/p&gt;

&lt;p&gt;If you’d rather list each ability as its own tool, you can register a custom server. It’s a good thing to try once the default server is working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create an Application Password
&lt;/h2&gt;

&lt;p&gt;Application Passwords come built into WordPress. They let an outside app log in through the REST API without your main password, and you can revoke each one on its own.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the profile page for the user the AI tool will use.&lt;/li&gt;
&lt;li&gt;Scroll down to Application Passwords. Type a name like “Cursor local” and click Add.&lt;/li&gt;
&lt;li&gt;Copy the password right away. WordPress only shows it once.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; make a separate user for this and give it the lowest role that still passes your permission checks. Don’t connect an AI tool as an admin unless you have a good reason.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 5: Connect Cursor and Claude Code
&lt;/h2&gt;

&lt;p&gt;For an HTTP connection, the adapter docs suggest a small proxy package called &lt;code&gt;@automattic/mcp-wordpress-remote&lt;/code&gt;. It runs through &lt;code&gt;npx&lt;/code&gt; on your computer and takes care of the login for you.&lt;/p&gt;

&lt;p&gt;The two connection types suit different setups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STDIO&lt;/strong&gt; runs the server through WP-CLI on the same machine as the site. It needs no password and works well for local development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP&lt;/strong&gt; goes through the REST API with an Application Password. Use it for staging sites and anything you can’t reach from a terminal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cursor
&lt;/h3&gt;

&lt;p&gt;Add this to &lt;code&gt;.cursor/mcp.json&lt;/code&gt; in your project, then restart Cursor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"wordpress-local"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@automattic/mcp-wordpress-remote@latest"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WP_API_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://your-site.local/wp-json/mcp/mcp-adapter-default-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WP_API_USERNAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp-user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WP_API_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xxxx xxxx xxxx xxxx xxxx xxxx"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Claude Code
&lt;/h3&gt;

&lt;p&gt;If WP-CLI works on your local site, you can skip HTTP and use STDIO. This command runs the server through WP-CLI as the user you pick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add wordpress-local &lt;span class="nt"&gt;--&lt;/span&gt; wp &lt;span class="nt"&gt;--path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/site mcp-adapter serve &lt;span class="nt"&gt;--server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mcp-adapter-default-server &lt;span class="nt"&gt;--user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mcp-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also give Claude Code the same &lt;code&gt;npx&lt;/code&gt; setup that Cursor uses.&lt;/p&gt;

&lt;p&gt;Once you’re connected, ask the tool to list the abilities on your site. You should see &lt;code&gt;my-site/get-site-info&lt;/code&gt; in the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety checks before you go further
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with read-only abilities.&lt;/strong&gt; Share abilities that only fetch data before you add any that create, edit, or delete.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep permission callbacks strict.&lt;/strong&gt; Never return true for everyone. The callback is what really keeps people out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep passwords out of git.&lt;/strong&gt; If &lt;code&gt;.cursor/mcp.json&lt;/code&gt; holds a password, add it to &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look before you approve.&lt;/strong&gt; Both tools ask before they run a tool call. Read the input before you say yes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test a failed permission check.&lt;/strong&gt; Get one read-only ability working, then see what happens when the check says no. That test teaches you more about safety than a success does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revoke the password when you’re done.&lt;/strong&gt; Delete the Application Password once you stop testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay local until you trust it.&lt;/strong&gt; Don’t point an AI tool at a client’s live site on day one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the WordPress MCP Adapter part of WordPress core?
&lt;/h3&gt;

&lt;p&gt;No.&amp;nbsp;WordPress 6.9 includes the Abilities API in core, but the MCP Adapter is a separate plugin you install from GitHub. It’s still under version 1.0, so expect changes between releases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need WP-CLI to connect Claude Code?
&lt;/h3&gt;

&lt;p&gt;No.&amp;nbsp;WP-CLI gives you a STDIO connection on a local site. Without it, you can use the HTTP endpoint with the &lt;code&gt;npx&lt;/code&gt; proxy and an Application Password, the same way Cursor connects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI tool change my site through MCP?
&lt;/h3&gt;

&lt;p&gt;Only through abilities you’ve marked as public, and only when the connected user passes each ability’s permission callback. Start with read-only abilities and a user with a low role.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why doesn’t my ability show up in Cursor or Claude Code?
&lt;/h3&gt;

&lt;p&gt;Check three things first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability’s &lt;code&gt;meta&lt;/code&gt; needs the &lt;code&gt;mcp&lt;/code&gt; public flag.&lt;/li&gt;
&lt;li&gt;The adapter plugin has to be active.&lt;/li&gt;
&lt;li&gt;The site has to run WordPress 6.9 or newer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then ask the tool to list the abilities again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn
&lt;/h2&gt;

&lt;p&gt;I’m still early with this setup, and I’d like to hear how yours went.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have you connected Claude Code or Cursor to a WordPress site yet? Did you go with STDIO or HTTP?&lt;/li&gt;
&lt;li&gt;Which ability would you expose first on a real site?&lt;/li&gt;
&lt;li&gt;Did a permission check ever block something you expected to work?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tell me in the comments, including the parts that broke. I read every reply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep reading
&lt;/h2&gt;

&lt;p&gt;I explain how I split work between these tools in my AI workflow for WordPress development. I also wrote about where AI speeds up my WordPress work, and where it doesn’t.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on matthummel.com.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>ai</category>
      <category>php</category>
      <category>mcp</category>
    </item>
    <item>
      <title>How I published my first WordPress.org plugin with Cursor, Git, and AI</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Thu, 24 Sep 2026 01:23:01 +0000</pubDate>
      <link>https://dev.to/matthummeldev/how-i-published-my-first-wordpressorg-plugin-with-cursor-git-and-ai-118j</link>
      <guid>https://dev.to/matthummeldev/how-i-published-my-first-wordpressorg-plugin-with-cursor-git-and-ai-118j</guid>
      <description>&lt;p&gt;Today I published my first plugin on &lt;a href="https://wordpress.org/plugins/tocguide/" rel="noopener noreferrer"&gt;WordPress.org&lt;/a&gt;: &lt;strong&gt;TOCguide&lt;/strong&gt;. It is a Gutenberg Table of Contents block with an optional Reading Guide. No accounts, no tracking, no outside APIs. The listing is live at version 1.6.3.&lt;/p&gt;

&lt;p&gt;This is a slightly shorter Dev.to version of a longer write-up on my site. The full notes are here: &lt;a href="https://matthummel.com/first-wordpress-org-plugin-tocguide-ai/" rel="noopener noreferrer"&gt;How I published my first WordPress.org plugin with Cursor, Git, and AI&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI mattered for finishing this
&lt;/h2&gt;

&lt;p&gt;I am a dad of twins. I also have a full-time job and a freelance WordPress side gig. Evenings and weekends are short. Shipping a Plugin Directory product the old way — every PHPCS pass, every readme tweak, every packaging step — would have sat on a list for years.&lt;/p&gt;

&lt;p&gt;I used AI tools on purpose: &lt;strong&gt;Cursor&lt;/strong&gt; (including cloud agents on the repo), &lt;strong&gt;Grok Bot&lt;/strong&gt; for site and content work around matthummel.com, and normal &lt;strong&gt;Git + GitHub Actions&lt;/strong&gt; so the machine checks stayed honest. I am not saying AI replaces judgment. I am saying it compressed weeks of typing and rework into hours I actually had.&lt;/p&gt;

&lt;p&gt;People are right to be careful with AI. Used poorly, it invents APIs, ships insecure PHP, and fights the WordPress.org guidelines. Used with rules, reviews, and CI, it can raise daily output without lowering the bar. Feedback and pushback are welcome in the comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What TOCguide is
&lt;/h2&gt;

&lt;p&gt;TOCguide is a single-purpose block plugin. Display name &lt;strong&gt;TOCguide&lt;/strong&gt;. Slug, folder, text domain, shortcode, and CSS prefix are all &lt;code&gt;tocguide&lt;/code&gt;. That one identity mattered for WordPress.org guideline 17 and for long-term support.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard TOC: heading levels, nested lists, five Block Styles, sticky/collapse, scroll-spy, smooth scroll offset, auto-insert, &lt;code&gt;[tocguide]&lt;/code&gt; shortcode, accessible &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Optional Reading Guide: section previews, density bars, read-time badges, reading progress, author notes, localStorage reactions and citations — all from post content and meta, not remote services&lt;/li&gt;
&lt;li&gt;Builder fallbacks for Elementor, Bricks, and HTML-based themes&lt;/li&gt;
&lt;li&gt;License: GPLv2 or later. Privacy: no phone-home
Docs: &lt;a href="https://matthummel-pa.github.io/tocguide/" rel="noopener noreferrer"&gt;matthummel-pa.github.io/tocguide&lt;/a&gt;
Source: &lt;a href="https://github.com/matthummel-pa/tocguide" rel="noopener noreferrer"&gt;github.com/matthummel-pa/tocguide&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup in brief
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cursor rules and cloud agents.&lt;/strong&gt; Under &lt;code&gt;.cursor/rules/&lt;/code&gt; I keep always-on rules for block coding, brand typography, and the WordPress.org Plugin Directory FAQ plus the 18 guidelines. A &lt;code&gt;CLAUDE.md&lt;/code&gt; file states the product intent in plain language. Cloud agents handled large slices as pull requests. I still read every PR. The agent drafts. I decide what merges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git and GitHub Actions.&lt;/strong&gt; CI on push and pull request runs lint, build, PHP lint, and PHPCS. Tags like &lt;code&gt;v1.6.2&lt;/code&gt; fire a Release workflow that builds the plugin zip with &lt;code&gt;@wordpress/scripts&lt;/code&gt; &lt;code&gt;plugin-zip&lt;/code&gt; and attaches it to a GitHub Release. That zip is what goes through SVN to the directory after review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block architecture.&lt;/strong&gt; TOCguide is a dynamic block: &lt;code&gt;block.json&lt;/code&gt; (apiVersion 3), &lt;code&gt;save.js&lt;/code&gt; returns null, and &lt;code&gt;src/render.php&lt;/code&gt; prints the nav. Heading maps live in &lt;code&gt;TOCguide_Headings&lt;/code&gt; so render stays thin.&lt;br&gt;
&lt;strong&gt;Where Grok Bot fits.&lt;/strong&gt; Cursor owns the plugin code. Grok Bot owns a different lane for me: site drafts, Rank Math, media, and turning repo facts into readable posts. Same person reviewing both. Different tools for code vs. site content.&lt;/p&gt;

&lt;h2&gt;
  
  
  An honest take on AI
&lt;/h2&gt;

&lt;p&gt;What helped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Written rules in the repo so agents follow Gutenberg and WordPress.org constraints&lt;/li&gt;
&lt;li&gt;CI as a second reviewer that never gets tired of PHPCS or lint&lt;/li&gt;
&lt;li&gt;Cloud agents for packaging and repetitive compliance edits while I was with the kids or on client work
What still needs a human:&lt;/li&gt;
&lt;li&gt;Product taste (what belongs in free vs later)&lt;/li&gt;
&lt;li&gt;Security and escaping reviews&lt;/li&gt;
&lt;li&gt;Reading the official guidelines yourself before you argue with a reviewer&lt;/li&gt;
&lt;li&gt;Saying no when a suggestion would phone home, load a CDN script, or lock features behind a paywall on .org
I am not claiming AI is magic. I am claiming that for a busy parent shipping a first directory plugin, the time cost used to be the blocker — and tooling that respects WordPress standards can change that. If your experience differs, I want to hear it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://wordpress.org/plugins/tocguide/" rel="noopener noreferrer"&gt;TOCguide on WordPress.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/matthummel-pa/tocguide/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://matthummel-pa.github.io/tocguide/" rel="noopener noreferrer"&gt;Docs site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://matthummel.com/first-wordpress-org-plugin-tocguide-ai/" rel="noopener noreferrer"&gt;Full article on matthummel.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build plugins with AI, or you refuse to, leave a comment. What worked, what broke review, what you would never trust an agent with.&lt;/p&gt;

&lt;p&gt;— Matt Hummel&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>ai</category>
      <category>git</category>
      <category>web</category>
    </item>
    <item>
      <title>WordPress Abilities API integration — A Practical First Integration</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Fri, 04 Sep 2026 16:32:53 +0000</pubDate>
      <link>https://dev.to/matthummeldev/wordpress-abilities-api-integration-a-practical-first-integration-27a2</link>
      <guid>https://dev.to/matthummeldev/wordpress-abilities-api-integration-a-practical-first-integration-27a2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This post walks through a practical WordPress Abilities API integration for developers and product teams. It shows how to declare discoverable, executable abilities (name, schema, callback) so external tools, automation, and AI agents can find and run site functionality. The goal here is to give you a safe, minimal first integration and a straightforward path for promoting and engaging with it once it’s live.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Abilities API is and why it matters
&lt;/h2&gt;

&lt;p&gt;The Abilities API was added to WordPress to make site capabilities both machine-readable and executable. It arrived in WordPress 6.9 and provides a standard registry for actions your site can perform. (&lt;a href="https://developer.wordpress.org/apis/abilities-api/getting-started/?utm_source=openai" rel="noopener noreferrer"&gt;developer.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Why it matters: abilities make your site discoverable to integrations, enforce consistent parameter schemas, optionally expose functionality via REST, and give automation and AI tools a predictable way to execute tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick overview: register an ability
&lt;/h2&gt;

&lt;p&gt;At the heart of a WordPress Abilities API integration is &lt;code&gt;wp_register_ability()&lt;/code&gt;. Use it to declare an ability's name, description, JSON schema for parameters, and the callback that performs the work. This is how you make tasks like "create-draft", "sync-product", or "triage-comment" visible to other systems. (&lt;a href="https://developer.wordpress.org/reference/functions/wp_register_ability/?utm_source=openai" rel="noopener noreferrer"&gt;developer.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimal example
&lt;/h3&gt;

&lt;p&gt;Register abilities during the Abilities API init so they’re available for discovery and execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_abilities_api_init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;wp_register_ability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'my-plugin.create_draft'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'title'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Create draft post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Create a draft post with title and content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'meta'&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'show_in_rest'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'args'&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'title'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'callback'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;wp_insert_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'post_title'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'post_content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'post_status'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'draft'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting &lt;code&gt;show_in_rest&lt;/code&gt; gives you automatic REST endpoints and makes the ability discoverable through the Abilities REST routes. (&lt;a href="https://developer.wordpress.org/apis/abilities-api/rest-api-endpoints/?utm_source=openai" rel="noopener noreferrer"&gt;developer.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery, REST endpoints, and authentication
&lt;/h2&gt;

&lt;p&gt;When you expose abilities over the REST surface, external systems can discover what your site can do and what parameters each ability expects. The Abilities REST endpoints follow the same authentication and permission model as the WordPress REST API, so apply least-privilege access when granting remote systems permission to call abilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to hook and how to structure code
&lt;/h2&gt;

&lt;p&gt;Register abilities on the Abilities API init hooks (for example, &lt;code&gt;wp_abilities_api_init&lt;/code&gt; and any category registration hooks) so they’re available for discovery and for adapters that surface them to agents. Hooking in at the right point ensures predictable availability and compatibility with other systems. (&lt;a href="https://make.wordpress.org/core/2025/11/10/abilities-api-in-wordpress-6-9/?utm_source=openai" rel="noopener noreferrer"&gt;make.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating with AI agents (MCP adapter)
&lt;/h2&gt;

&lt;p&gt;If you want to connect Abilities to AI agents and automation frameworks, look at the WordPress MCP adapter. It maps Abilities into tools and resources that agent frameworks can consume, which helps you build safe, scoped integrations between AI tooling and site functionality. (&lt;a href="https://developer.wordpress.org/news/2026/02/from-abilities-to-ai-agents-introducing-the-wordpress-mcp-adapter/?utm_source=openai" rel="noopener noreferrer"&gt;developer.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety, permissions, and best practices
&lt;/h2&gt;

&lt;p&gt;Keep abilities narrow and purpose-built. Prefer small, least-privilege actions rather than a single admin-level ability that does everything. Log executions with context (ability name, calling actor, parameters) so you can audit activity and respond to misuse. Treat any ability that performs writes as sensitive and require explicit opt-in before exposing it to external agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps and resources
&lt;/h2&gt;

&lt;p&gt;1) Build a minimal plugin that registers one read-only and one write ability. 2) Publish the project on GitHub with clear examples and tests. 3) Share the tutorial on DEV.to and a short business summary on LinkedIn; engage with comments and track clicks and leads. Use the Abilities API docs and examples as your primary references while developing. (&lt;a href="https://developer.wordpress.org/apis/abilities-api/getting-started/?utm_source=openai" rel="noopener noreferrer"&gt;developer.wordpress.org&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Follow this practical approach and you’ll end up with a discoverable, auditable, and promotable WordPress Abilities API integration that serves both developers and business stakeholders.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://matthummel.com/?p=5088" rel="noopener noreferrer"&gt;matthummel.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>abilitiesapi</category>
      <category>ai</category>
      <category>developer</category>
    </item>
    <item>
      <title>Why I'm Moving Away from Power Platform and Back to Modern WordPress</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Wed, 02 Sep 2026 05:05:11 +0000</pubDate>
      <link>https://dev.to/matthummeldev/why-im-moving-away-from-power-platform-and-back-to-modern-wordpress-15i2</link>
      <guid>https://dev.to/matthummeldev/why-im-moving-away-from-power-platform-and-back-to-modern-wordpress-15i2</guid>
      <description>&lt;p&gt;After nearly five years of enterprise Power Platform work, I'm pivoting my content and personal projects back to modern custom WordPress development.&lt;/p&gt;

&lt;p&gt;For the last nearly five years, a big part of my day-to-day work revolved &lt;br&gt;
around the Microsoft Power Platform. Over the past few months, I began &lt;br&gt;
writing about it here—sharing practical fixes for canvas app delegation, &lt;br&gt;
complex formulas, SharePoint integrations, and automated flows.&lt;/p&gt;

&lt;p&gt;However, the more I documented those enterprise processes, the more I &lt;br&gt;
realized my core passion wasn't in low-code platforms. While internal business &lt;br&gt;
tools solve real corporate problems, my true technical curiosity has always &lt;br&gt;
belonged to full-stack web development. &lt;/p&gt;

&lt;p&gt;Because of that, I'm making a deliberate shift: moving away from Power &lt;br&gt;
Platform content and returning to my roots in &lt;strong&gt;modern WordPress engineering, &lt;br&gt;
open-web architectures, and custom personal builds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is why I'm making the change—and what I'll be sharing next.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Five Years in Managed Ecosystems vs. Open-Web Control
&lt;/h2&gt;

&lt;p&gt;Spending nearly five years inside the Microsoft ecosystem taught me a lot &lt;br&gt;
about rapid enterprise app delivery. But working exclusively within a vendor's &lt;br&gt;
walled garden introduces hard limits on custom execution, data flow, and &lt;br&gt;
long-term platform control.&lt;/p&gt;

&lt;p&gt;Returning my focus to custom web development (especially modern setups using &lt;br&gt;
Roots/Sage, Blade templates, Vite, and automated CI/CD pipelines) brings back &lt;br&gt;
the exact aspects of engineering I enjoy most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total architectural control&lt;/strong&gt; over data flow, markup, and application logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct performance tuning&lt;/strong&gt; at the code level without vendor-imposed rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;True open-source independence&lt;/strong&gt; without licensing shifts or platform lock-in.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Modern WordPress Is a Superior Developer Experience
&lt;/h2&gt;

&lt;p&gt;There is a common myth that WordPress development is stuck in the past. In &lt;br&gt;
reality, modern custom theme and plugin development uses a toolchain that &lt;br&gt;
matches top-tier web application engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clean templating&lt;/strong&gt; using Blade and modern PHP features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant asset compilation&lt;/strong&gt; powered by Vite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlined developer workflows&lt;/strong&gt; (using tools like Cursor and scoped MCP 
integrations) that handle repetitive boilerplate, freeing up time for 
architecture, accessibility, and speed optimizations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stepping back into custom WordPress builds reminded me how powerful, clean, &lt;br&gt;
and rewarding web engineering can be when done with modern tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Building for the Web (Not Just Enterprise Specs)
&lt;/h2&gt;

&lt;p&gt;Internal enterprise tools naturally focus on admin forms, internal workflows, &lt;br&gt;
and corporate data entry. They serve a functional purpose, but they rarely &lt;br&gt;
allow for creative experimentation with modern web APIs, public-facing user &lt;br&gt;
experiences, or open-source software.&lt;/p&gt;

&lt;p&gt;I want to spend my energy building and shipping personal web projects, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight, speed-first custom WordPress plugins.&lt;/li&gt;
&lt;li&gt;Modern theme starter stacks.&lt;/li&gt;
&lt;li&gt;Full-stack experiments combining external APIs, modern UI, and AI workflows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Changes Here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No new Power Platform posts.&lt;/strong&gt; The tutorials I published over the last 
few months will remain online for anyone who needs them, but my focus is 
moving on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep-dive WordPress content.&lt;/strong&gt; Expect practical guides on custom PHP 
architectures, Sage/Blade workflows, performance strategies, and modern 
developer tooling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build logs.&lt;/strong&gt; I’ll be sharing the raw, honest engineering process behind 
the personal projects and tools I ship.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took five years in the low-code world to realize how much I missed custom &lt;br&gt;
web development, and I’m excited to be back in my element.&lt;/p&gt;

&lt;p&gt;Are you building for the open web or refining your own dev stack right now? &lt;br&gt;
Let's connect in the comments below.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>webdev</category>
      <category>powerplatform</category>
      <category>career</category>
    </item>
    <item>
      <title>5 Ways my new AI WordPress Workflow Actually Speeds up Development (and what it doesn't)</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Wed, 02 Sep 2026 04:25:12 +0000</pubDate>
      <link>https://dev.to/matthummeldev/5-ways-my-new-ai-wordpress-workflow-actually-speeds-up-development-and-what-it-doesn8217t-md6</link>
      <guid>https://dev.to/matthummeldev/5-ways-my-new-ai-wordpress-workflow-actually-speeds-up-development-and-what-it-doesn8217t-md6</guid>
      <description>&lt;p&gt;My AI WordPress workflow helps me finish the parts of a custom WordPress build I already know how to check. &lt;strong&gt;It does not replace the check.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use &lt;strong&gt;Cursor&lt;/strong&gt; inside a Sage (Roots) theme repository, &lt;strong&gt;ChatGPT&lt;/strong&gt; and &lt;strong&gt;Claude&lt;/strong&gt; for context/copy passes, &lt;strong&gt;n8n&lt;/strong&gt; for form handling, &lt;strong&gt;GitHub Actions&lt;/strong&gt; to build the theme zip, and &lt;strong&gt;Vite&lt;/strong&gt; for asset compilation. Scaffolding, boilerplate, and first-pass Blade loops come back significantly quicker than they used to. Architecture, testing, and the final &lt;em&gt;yes&lt;/em&gt; still sit with me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on context:&lt;/strong&gt; This post is a tool-by-tool breakdown of strengths, costs, and human steps—not a repeat of my previous workflow essay (&lt;em&gt;"AI for WordPress Development: My Cursor, ChatGPT, n8n &amp;amp; MCP Workflow"&lt;/em&gt;). That post covers the loop; this one maps where each tool shines and where it costs.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What “Fast” Actually Means in Custom Dev
&lt;/h2&gt;

&lt;p&gt;"Fast" is easy to sell. In practice, it means something much narrower: &lt;strong&gt;less time spent on work that does not require a human rewrite.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I won't claim a 10x multiplier or a shorter calendar on every project, nor that a model "wrote the site." The core benefit is clear: repeatable technical work shrinks, while accountability remains firmly human.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Repeatable Work Lessens
&lt;/h3&gt;

&lt;p&gt;Renaming an ACF page field, wiring a new Vite entry point, drafting a standard Blade loop, or filling out a GitHub Actions workflow—these are predictable patterns. AI models excel here because I can immediately verify the output against a pattern I already know. &lt;/p&gt;

&lt;p&gt;That accounts for most of the actual speed gain. It is real, but it is also easy to overstate.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Judgment Remains with the Developer
&lt;/h3&gt;

&lt;p&gt;Deciding which plugin stays, whether a client editor can safely modify a layout field, catching contrast accessibility failures, or evaluating if a webhook belongs in the stack—that is judgment. Models guess based on statistical likelihood. I still own the call.&lt;/p&gt;

&lt;p&gt;If I cannot explain every line at handoff, it does not ship. It's the same quality bar as a traditional build, just with less friction on the boilerplate.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AI WordPress Tool Matrix
&lt;/h2&gt;

&lt;p&gt;This isn't a tier list or a ranking. Each tool occupies a specific role in the build, incurs a specific trade-off, and demands a non-negotiable human review step.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Role / Best For&lt;/th&gt;
&lt;th&gt;Weak At / Trade-Off&lt;/th&gt;
&lt;th&gt;Non-Negotiable Human Step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;In-repo scaffolding, Blade templates, PHP helpers, refactoring.&lt;/td&gt;
&lt;td&gt;Hallucinating WP core APIs or outdated package syntaxes.&lt;/td&gt;
&lt;td&gt;Reading diffs line-by-line; testing logic in a real WP environment.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ChatGPT / Claude&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Second-pass copy editing, off-repo structural brainstorming, regex.&lt;/td&gt;
&lt;td&gt;Lacks direct codebase context; over-uses generic "agency voice."&lt;/td&gt;
&lt;td&gt;Validating accuracy, editing tone, stripping unnecessary fluff.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;n8n&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;External form handoff automation and webhook integration.&lt;/td&gt;
&lt;td&gt;Silent failures if third-party endpoints rate-limit or change schemas.&lt;/td&gt;
&lt;td&gt;Setting up fallback mail handlers (&lt;code&gt;wp_mail&lt;/code&gt;) and monitoring logs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Asset bundling, hot module replacement (HMR), asset compilation.&lt;/td&gt;
&lt;td&gt;Requires strict entry point declarations in custom theme setups.&lt;/td&gt;
&lt;td&gt;Auditing bundle sizes and verifying compiled output in browser.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Automated CI/CD, running Composer, building production zip releases.&lt;/td&gt;
&lt;td&gt;Hidden pipeline costs or broken builds due to strict PHP/node mismatches.&lt;/td&gt;
&lt;td&gt;Maintaining deployment secrets and controlling production triggers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Giving agents scoped doors to external tools (database, terminal, APIs).&lt;/td&gt;
&lt;td&gt;Risk of exposing elevated write access or leaking sensitive credentials.&lt;/td&gt;
&lt;td&gt;Keeping scopes hyper-narrow; manually approving write operations.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How I Choose Tools per Task
&lt;/h2&gt;

&lt;p&gt;I start from the job, not the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In-repo file edits (Sage/Roots theme):&lt;/strong&gt; I open &lt;strong&gt;Cursor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drafting content or working outside the codebase:&lt;/strong&gt; I use &lt;strong&gt;ChatGPT&lt;/strong&gt; or &lt;strong&gt;Claude&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handling form submissions and external payload routes:&lt;/strong&gt; That is &lt;strong&gt;n8n&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset compilation &amp;amp; production releases:&lt;/strong&gt; That belongs to &lt;strong&gt;Vite&lt;/strong&gt; and &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connecting agents to real-time tools:&lt;/strong&gt; &lt;strong&gt;MCP&lt;/strong&gt; opens only when an agent needs a narrow doorway to an external utility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A development shop doesn't need all of these active at once. You pick the right tool for the current step, followed immediately by human review.&lt;/p&gt;




&lt;h2&gt;
  
  
  How a Change Moves from Brief to Release
&lt;/h2&gt;

&lt;p&gt;From a client brief to project handoff, the pipeline is short and predictable. AI models sit exclusively in the middle step—never at the boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ Brief ] ──► [ Cursor / AI Draft ] ──► [ Human Review &amp;amp; Diffs ] ──► [ Vite &amp;amp; CI/CD ] ──► [ Production Handoff ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Brief:&lt;/strong&gt; A shop note, agency ticket, or custom brief. I write the technical constraints. A model did not take the job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor:&lt;/strong&gt; Local scaffolding inside the Sage repository—Blade components, PHP helpers, Tailwind/CSS. ChatGPT/Claude assist with off-repo structural ideas. MCP is enabled only when an agent requires a specific, scoped tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review:&lt;/strong&gt; I inspect the Git diff. I execute the code on a real local page. Hallucinated APIs, unnecessary plugins, and fluff copy get eliminated here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vite &amp;amp; CI:&lt;/strong&gt; Running &lt;code&gt;npm run build&lt;/code&gt; locally, followed by GitHub Actions on push to &lt;code&gt;main&lt;/code&gt;. The pipeline runs Composer, compiles assets, packages the production release zip, and tags &lt;code&gt;theme-latest&lt;/code&gt;. PHP 8.3 serves as the runtime; WP-CLI remains the administrative interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handoff:&lt;/strong&gt; Configuring &lt;code&gt;wp-admin&lt;/code&gt; fields for client editing, providing clean technical notes, and transferring the Git repository. If I cannot explain a piece of code, it does not get handed off.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where n8n Sits:&lt;/strong&gt; &lt;code&gt;n8n&lt;/code&gt; is isolated from the theme's core code path. When a user submits a contact form, WordPress &lt;code&gt;POST&lt;/code&gt;s JSON to an &lt;code&gt;n8n&lt;/code&gt; webhook. If that webhook fails, a native &lt;code&gt;wp_mail&lt;/code&gt; fallback triggers. Automation handles the payload &lt;em&gt;after&lt;/em&gt; submission—it does not author the theme.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What I Still Do by Hand
&lt;/h2&gt;

&lt;p&gt;The list of manual tasks remains longer than the automated pipeline by design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture &amp;amp; Strategy:&lt;/strong&gt; Deciding overall system structure—and what &lt;em&gt;not&lt;/em&gt; to build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security &amp;amp; Access:&lt;/strong&gt; Managing permissions, nonces, and governing what MCP servers can access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diff Auditing:&lt;/strong&gt; Reviewing every single line in a pull request rather than trusting the commit summary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Field &amp;amp; Cross-Device Testing:&lt;/strong&gt; Validating themes on live page builds across desktop and mobile viewports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy Tone:&lt;/strong&gt; Ensuring the copy speaks clearly to clients and agencies without sounding like LLM jargon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility (a11y):&lt;/strong&gt; Verifying color contrast pairs, ARIA labels, semantic HTML hierarchy, and keyboard focus states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Deployment Approval:&lt;/strong&gt; Giving the final green light for production releases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Standard VS Code is still part of my setup for times when I want to edit files without AI assistance. Keeping the review muscle sharp is critical.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Does AI write the PHP I ship?
&lt;/h4&gt;

&lt;p&gt;It drafts it; I review and ship it. Tools like Cursor, Claude, and ChatGPT help produce boilerplate PHP and initial template logic. However, I read, test, and take ownership of every line that hits production—including Vite pipelines, PHP 8.3 code, and GitHub Actions scripts.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why is there no "overall winner" in this comparison?
&lt;/h4&gt;

&lt;p&gt;Because they perform completely different functions. Cursor acts as the local code editor, ChatGPT/Claude handle off-repo reasoning, n8n routes form payloads, and GitHub Actions automates deployment zips. Ranking them against each other would be comparing apples to build servers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Will an AI workflow like this replace a developer?
&lt;/h4&gt;

&lt;p&gt;No. The cost of generating repeatable code dropped, but the cost of technical judgment did not change. Hiring an experienced developer means paying for code architecture, security verification, thorough testing, and long-term maintainability—not the speed of the prompt log.&lt;/p&gt;

&lt;h4&gt;
  
  
  What about data privacy and vendor lock-in?
&lt;/h4&gt;

&lt;p&gt;Chat interfaces and MCP tools process whatever you pass to them. I mitigate risk by keeping write scopes minimal and removing secrets/keys from prompts. While Cursor, n8n, and GitHub represent distinct third-party dependencies, all code and review processes live inside standard Git repositories that can be migrated at any time.&lt;/p&gt;

&lt;h4&gt;
  
  
  How does this differ from a full workflow guide?
&lt;/h4&gt;

&lt;p&gt;A workflow guide demonstrates how the ecosystem fits together during an active WordPress build. This post provides an explicit tool-by-tool comparison detailing strengths, trade-offs, and where human intervention remains mandatory.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://matthummel.com/web-development/5-ways-ai-wordpress-workflow/" rel="noopener noreferrer"&gt;matthummel.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>chatgpt</category>
      <category>claude</category>
    </item>
    <item>
      <title>AI Website Redesign: 5 Lessons From a Solo Developer</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Mon, 22 Jun 2026 15:51:15 +0000</pubDate>
      <link>https://dev.to/matthummeldev/ai-website-redesign-5-lessons-from-a-solo-developer-nhj</link>
      <guid>https://dev.to/matthummeldev/ai-website-redesign-5-lessons-from-a-solo-developer-nhj</guid>
      <description>&lt;p&gt;I'll be honest with you: my website sat half-finished for a long time. Not because I didn't care about it, but because I'm a full-time Power Platform developer by day and a full-time dad the rest of the time. Between work and a house full of twins (and a cat who thinks he's in charge), "redesign my portfolio" kept sliding to the bottom of the list.&lt;/p&gt;

&lt;p&gt;So I did something I'd been curious about for a while. I used AI to help me redesign on my portfolio as a one-person team. This post is the honest version of how that went — why I reached for AI, what it actually did, where it tripped up, and the lessons you can borrow for your own AI website redesign.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I used AI (when I'm just one person)
&lt;/h2&gt;

&lt;p&gt;The short answer is time. The longer answer is that a solo dev wears every hat — designer, developer, writer, QA, and SEO person — usually after the kids are asleep.&lt;/p&gt;

&lt;p&gt;Here's what pushed me to try it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time is my scarcest resource.&lt;/strong&gt; A full-time job plus parenting doesn't leave long stretches for fiddling with CSS at midnight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I'm a team of one.&lt;/strong&gt; There's no designer to hand off to and no senior dev to review my work. AI became my second pair of eyes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context-switching is brutal.&lt;/strong&gt; My day job is Power Platform, not front-end. AI helped me get back up to speed fast instead of relearning everything each time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I wanted momentum.&lt;/strong&gt; Small, finished wins beat a perfect plan I never start.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Turns out I'm not alone. In the &lt;a href="https://survey.stackoverflow.co/2025/ai/" rel="noopener noreferrer"&gt;2025 Stack Overflow Developer Survey&lt;/a&gt;, 84% of developers said they use or plan to use AI tools — up from 76% the year before. AI has quietly become a normal part of how we build.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI actually did in the redesign
&lt;/h2&gt;

&lt;p&gt;This wasn't "press a button, get a website." It was more like pair programming with a tireless junior who never gets bored of the fiddly stuff. A few real examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fixed my responsive layouts.&lt;/strong&gt; My columns refused to stack on mobile. AI found that the grids were styled inline and targeted them the right way, so the parent columns stacked without breaking the child grids.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built a full-width gradient hero.&lt;/strong&gt; The brand gradient kept hiding my content. The fix was putting the gradient on the outer row and making the inner column transparent — something I'd have spent an evening guessing at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solved a page-speed problem.&lt;/strong&gt; My site got flagged for slow loading (Largest Contentful Paint). It turned out the slow element was my heading text waiting on a web font, not an image. One font-loading setting fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handled the boring-but-important SEO.&lt;/strong&gt; Meta titles, descriptions, slugs, and indexing — the stuff I always rush — got done properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want the technical background on that speed metric, Google's own &lt;a href="https://web.dev/articles/lcp" rel="noopener noreferrer"&gt;Largest Contentful Paint guide&lt;/a&gt; is the clearest explanation out there (aim for 2.5 seconds or less).&lt;/p&gt;

&lt;h2&gt;
  
  
  5 lessons from my AI website redesign
&lt;/h2&gt;

&lt;p&gt;If you take nothing else from this post, take these.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Diagnose before you fix.&lt;/strong&gt; My biggest time-saver was making AI &lt;em&gt;prove&lt;/em&gt; the cause before changing anything. The "slow page" was a font issue, not an image — guessing would have wasted hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify on the live page, not the editor.&lt;/strong&gt; What the editor shows and what visitors actually see are two different things. Always check the real, published page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat AI as a collaborator, not autopilot.&lt;/strong&gt; I still made the calls. Fittingly, that same Stack Overflow survey found 46% of developers don't fully trust AI output — so review everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make small, reversible changes.&lt;/strong&gt; One labeled CSS block or one setting at a time. If something breaks, you know exactly what to undo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write down what worked.&lt;/strong&gt; I kept a running playbook of fixes so future-me (or future-you) doesn't solve the same problem twice.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Trust, but verify: I read over everything
&lt;/h2&gt;

&lt;p&gt;This is the part I won't skip, and you shouldn't either. AI is fast, but it's confidently wrong often enough that I treat every result as a draft, not a final answer.&lt;/p&gt;

&lt;p&gt;Here's how I check accuracy before anything goes live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I read every line of code and copy.&lt;/strong&gt; If I don't understand why a change works, I ask until I do. No black boxes on my own site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I test the real result.&lt;/strong&gt; I load the live page and click around at different screen sizes instead of trusting a description of what "should" happen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I fact-check claims and sources.&lt;/strong&gt; Stats, links, and "best practices" get verified against primary sources before I publish them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I sanity-check the SEO.&lt;/strong&gt; Titles, descriptions, and slugs all get a human read for tone and accuracy, not just a green score.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple: AI does the heavy lifting, but I'm accountable for what ships. Reviewing the output is where "using AI" turns into "using AI &lt;em&gt;well&lt;/em&gt;."&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompting is a skill worth practicing
&lt;/h2&gt;

&lt;p&gt;The difference between a frustrating AI session and a productive one usually comes down to the prompt. Vague questions get vague answers. The more context and direction I give, the better the results.&lt;/p&gt;

&lt;p&gt;A few habits that leveled up my prompting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Be specific about the goal.&lt;/strong&gt; "Make the columns stack on mobile and tablet, but don't change the inner grids" beats "fix the layout."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give context.&lt;/strong&gt; I mention the stack (WordPress, Kadence, SiteGround) so the answer fits my actual setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask for the cause, not just a fix.&lt;/strong&gt; Telling AI to diagnose first leads to real solutions instead of guesses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate.&lt;/strong&gt; I refine in small steps — "now make it responsive," "add padding to the buttons" — instead of demanding everything at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set the standard.&lt;/strong&gt; I tell it to keep things scannable, on-brand, and reversible so I don't have to redo the output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good prompting isn't magic words. It's clear thinking written down — and like any skill, it gets sharper the more you do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting: when AI got it wrong
&lt;/h2&gt;

&lt;p&gt;It wasn't all smooth. The recurring snags were easy to fix once I knew them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"My change didn't apply!"&lt;/strong&gt; Nine times out of ten it was caching. Purge your cache before deciding a change failed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrong element targeted.&lt;/strong&gt; AI occasionally styled the wrong box. A quick look at the live page caught it every time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logged-in view fooled me.&lt;/strong&gt; Admins bypass caching and optimizations, so test as a logged-out visitor for the real result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes to avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Letting AI publish or change settings without you reviewing first.&lt;/li&gt;
&lt;li&gt;Bundling ten changes together, then not knowing which one broke the site.&lt;/li&gt;
&lt;li&gt;Trusting the editor preview instead of the live page.&lt;/li&gt;
&lt;li&gt;Skipping a backup or revision before a big edit.&lt;/li&gt;
&lt;li&gt;Optimizing the thing you &lt;em&gt;assume&lt;/em&gt; is slow instead of the thing you &lt;em&gt;measured&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your AI website redesign checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Write one sentence describing what "done" looks like.&lt;/li&gt;
&lt;li&gt;[ ] Ask AI to diagnose and confirm the root cause first.&lt;/li&gt;
&lt;li&gt;[ ] Make one small, reversible change at a time.&lt;/li&gt;
&lt;li&gt;[ ] Purge the cache after each change.&lt;/li&gt;
&lt;li&gt;[ ] Verify on the live page at mobile, tablet, and desktop widths.&lt;/li&gt;
&lt;li&gt;[ ] Set your SEO (title, description, slug) before publishing.&lt;/li&gt;
&lt;li&gt;[ ] Save what worked to a personal playbook.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;AI didn't replace me — it gave a busy solo dev a way to actually finish things. As a full-time developer and full-time dad, that's the difference between a site that's "always almost done" and one that's live, fast, and something I'm proud of.&lt;/p&gt;

&lt;p&gt;If you've been putting off your own redesign because there just aren't enough hours, this is your nudge: start small, let AI handle the heavy lifting, and keep your hands on the wheel.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>wordpress</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Power Apps Project Planning: 7 Simple Steps to Build Better Apps</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Fri, 22 May 2026 04:03:08 +0000</pubDate>
      <link>https://dev.to/matthummeldev/power-apps-project-planning-7-simple-steps-to-build-better-apps-4ccm</link>
      <guid>https://dev.to/matthummeldev/power-apps-project-planning-7-simple-steps-to-build-better-apps-4ccm</guid>
      <description>&lt;p&gt;Learn Power Apps project planning before building your app. Use this beginner-friendly checklist to plan users, data, workflows, security, ALM, and success metrics.&lt;/p&gt;

&lt;p&gt;Starting a new Power Apps project can be exciting.&lt;/p&gt;

&lt;p&gt;You have an idea, you open Power Apps Studio, add a screen, connect a list, and start building. That is one of the best parts of Power Apps. You can go from an idea to something working pretty quickly.&lt;/p&gt;

&lt;p&gt;But I have also learned that jumping in too fast can create problems later.&lt;/p&gt;

&lt;p&gt;Sometimes the app starts simple, then suddenly you need approvals, different user roles, email notifications, admin screens, reports, and a better way to manage the data.&lt;/p&gt;

&lt;p&gt;That is when a little planning helps.&lt;/p&gt;

&lt;p&gt;You do not need a huge requirements document. Even a simple one-page plan can make the project easier to build, test, and support.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start With the Problem
&lt;/h2&gt;

&lt;p&gt;Before creating screens, write down the actual problem.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;I need to build a request app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Try something clearer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Employees need a simple way to submit equipment requests, managers need to approve them, and admins need one place to track the status.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That one sentence gives the app more direction.&lt;/p&gt;

&lt;p&gt;It tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who is using the app&lt;/li&gt;
&lt;li&gt;What they are submitting&lt;/li&gt;
&lt;li&gt;Who approves it&lt;/li&gt;
&lt;li&gt;What needs to be tracked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Power App does not need to solve every problem. It just needs to solve one process clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Know Who Will Use the App
&lt;/h2&gt;

&lt;p&gt;Next, list the people who will use the app.&lt;/p&gt;

&lt;p&gt;Do not just say “users.” Break them into roles.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;What they need to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Employee&lt;/td&gt;
&lt;td&gt;Submit a request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manager&lt;/td&gt;
&lt;td&gt;Approve or reject a request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin&lt;/td&gt;
&lt;td&gt;Review and update records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leadership&lt;/td&gt;
&lt;td&gt;View status or reports&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once you know the roles, it becomes easier to decide what each person should see.&lt;/p&gt;

&lt;p&gt;The employee probably does not need the admin screen.&lt;br&gt;&lt;br&gt;
The manager probably only needs items waiting for approval.&lt;br&gt;&lt;br&gt;
The admin may need access to everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Look at the Current Process
&lt;/h2&gt;

&lt;p&gt;Before building the new app, write down how the process works today.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Employee fills out a spreadsheet.&lt;/li&gt;
&lt;li&gt;Employee emails it to a manager.&lt;/li&gt;
&lt;li&gt;Manager replies with approval.&lt;/li&gt;
&lt;li&gt;Admin copies the information somewhere else.&lt;/li&gt;
&lt;li&gt;Someone manually sends status updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the current process is written down, the problems become easier to see.&lt;/p&gt;

&lt;p&gt;Maybe approvals are getting buried in email.&lt;br&gt;&lt;br&gt;
Maybe people are copying the same data into multiple places.&lt;br&gt;&lt;br&gt;
Maybe nobody knows the current status.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sketch the Future Process
&lt;/h2&gt;

&lt;p&gt;Now write down what the new process should look like.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Employee submits the request in Power Apps.&lt;/li&gt;
&lt;li&gt;The request is saved to SharePoint or Dataverse.&lt;/li&gt;
&lt;li&gt;Power Automate sends the approval to the manager.&lt;/li&gt;
&lt;li&gt;Manager approves or rejects it.&lt;/li&gt;
&lt;li&gt;The request status updates automatically.&lt;/li&gt;
&lt;li&gt;Employee gets a notification.&lt;/li&gt;
&lt;li&gt;Admins can track everything in one place.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This gives you a simple roadmap before you build.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Plan the Data Before the Screens
&lt;/h2&gt;

&lt;p&gt;This is one of the biggest lessons I have learned with Power Apps.&lt;/p&gt;

&lt;p&gt;If the data is not planned well, the app gets harder to build.&lt;/p&gt;

&lt;p&gt;Before adding too many screens, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What information needs to be saved?&lt;/li&gt;
&lt;li&gt;Will I use SharePoint or Dataverse?&lt;/li&gt;
&lt;li&gt;What lists or tables do I need?&lt;/li&gt;
&lt;li&gt;What should be a dropdown?&lt;/li&gt;
&lt;li&gt;What should be a lookup?&lt;/li&gt;
&lt;li&gt;Do I need attachments?&lt;/li&gt;
&lt;li&gt;Do I need approval history?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a request app, you might need:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;List or table&lt;/th&gt;
&lt;th&gt;What it stores&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Requests&lt;/td&gt;
&lt;td&gt;Main request information&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Departments&lt;/td&gt;
&lt;td&gt;Department names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request Types&lt;/td&gt;
&lt;td&gt;Dropdown options&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Approval History&lt;/td&gt;
&lt;td&gt;Approval actions and dates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For simple apps, SharePoint Lists may work fine.&lt;/p&gt;

&lt;p&gt;For more structured apps with relationships, security roles, and more business logic, Dataverse may be a better option.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Write Down the Flows You Need
&lt;/h2&gt;

&lt;p&gt;Most Power Apps projects eventually need Power Automate.&lt;/p&gt;

&lt;p&gt;Even a basic app might need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An approval email&lt;/li&gt;
&lt;li&gt;A Teams message&lt;/li&gt;
&lt;li&gt;A status update&lt;/li&gt;
&lt;li&gt;A reminder&lt;/li&gt;
&lt;li&gt;A confirmation email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I like to list the flows before building them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flow&lt;/th&gt;
&lt;th&gt;What starts it&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;New request notification&lt;/td&gt;
&lt;td&gt;A new request is submitted&lt;/td&gt;
&lt;td&gt;Emails the manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Approval update&lt;/td&gt;
&lt;td&gt;Manager responds&lt;/td&gt;
&lt;td&gt;Updates the request status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reminder flow&lt;/td&gt;
&lt;td&gt;Runs daily&lt;/td&gt;
&lt;td&gt;Reminds managers about pending requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Completion notice&lt;/td&gt;
&lt;td&gt;Request is approved&lt;/td&gt;
&lt;td&gt;Tells the employee&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For each flow, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What starts the flow?&lt;/li&gt;
&lt;li&gt;What record does it update?&lt;/li&gt;
&lt;li&gt;Who gets the email or message?&lt;/li&gt;
&lt;li&gt;What should happen if something goes wrong?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Think About Permissions, Testing, and Launch
&lt;/h2&gt;

&lt;p&gt;This part is not as fun as building screens, but it matters.&lt;/p&gt;

&lt;p&gt;Before the app goes live, think through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can users see only their own records?&lt;/li&gt;
&lt;li&gt;Can managers see their team’s records?&lt;/li&gt;
&lt;li&gt;Can admins see everything?&lt;/li&gt;
&lt;li&gt;Who can edit records?&lt;/li&gt;
&lt;li&gt;Who can delete records?&lt;/li&gt;
&lt;li&gt;Who will support the app after launch?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, have someone else test the app before calling it done.&lt;/p&gt;

&lt;p&gt;You know where everything is because you built it. A new user may not.&lt;/p&gt;

&lt;p&gt;Ask testers to try simple tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submit a request&lt;/li&gt;
&lt;li&gt;Find the request&lt;/li&gt;
&lt;li&gt;Approve or reject something&lt;/li&gt;
&lt;li&gt;Check the status&lt;/li&gt;
&lt;li&gt;Confirm they received a notification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If they get confused, that is useful feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Resources
&lt;/h2&gt;

&lt;p&gt;Here are a few resources that can help with Power Apps project planning:&lt;/p&gt;

&lt;p&gt;Microsoft Power Apps planning module:&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/training/modules/plan-app-project/" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/training/modules/plan-app-project/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Power Apps documentation:&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/power-apps/" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/power-apps/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Power Apps Plan Designer:&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/power-apps/maker/plan-designer/plan-designer" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/power-apps/maker/plan-designer/plan-designer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Power Platform ALM documentation:&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/power-platform/alm/" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/power-platform/alm/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Power Platform Center of Excellence guidance:&lt;br&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/power-platform/guidance/adoption/coe" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/power-platform/guidance/adoption/coe&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Power Apps is great because you can build quickly.&lt;/p&gt;

&lt;p&gt;But I have learned that a little planning makes the build much smoother.&lt;/p&gt;

&lt;p&gt;You do not need to be a Power Platform expert. You do not need a perfect diagram. You do not need a giant requirements document.&lt;/p&gt;

&lt;p&gt;You just need to slow down long enough to answer a few basic questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What problem am I solving?&lt;/li&gt;
&lt;li&gt;Who is using the app?&lt;/li&gt;
&lt;li&gt;What data do I need?&lt;/li&gt;
&lt;li&gt;What should be automated?&lt;/li&gt;
&lt;li&gt;Who can see or edit records?&lt;/li&gt;
&lt;li&gt;How will I test it?&lt;/li&gt;
&lt;li&gt;Who will support it later?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start simple. Build the first useful version. Get feedback. Then improve it over time.&lt;/p&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
      <category>powerautomate</category>
      <category>sharepoint</category>
    </item>
    <item>
      <title>How to Debug a Blank Power Apps Gallery</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Thu, 21 May 2026 01:11:21 +0000</pubDate>
      <link>https://dev.to/matthummeldev/how-to-debug-a-blank-power-apps-gallery-5a6p</link>
      <guid>https://dev.to/matthummeldev/how-to-debug-a-blank-power-apps-gallery-5a6p</guid>
      <description>&lt;p&gt;A blank gallery in Power Apps does not always mean your app is broken. Most gallery issues come from one of these areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Items&lt;/code&gt; property&lt;/li&gt;
&lt;li&gt;A filter returning no records&lt;/li&gt;
&lt;li&gt;A dropdown with no selected value&lt;/li&gt;
&lt;li&gt;A search box filtering everything out&lt;/li&gt;
&lt;li&gt;An empty collection&lt;/li&gt;
&lt;li&gt;Delegation limits&lt;/li&gt;
&lt;li&gt;Data source or permission issues&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Start by Simplifying the Gallery
&lt;/h2&gt;

&lt;p&gt;The first step is to strip the &lt;code&gt;Items&lt;/code&gt; property down to just the data source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'Project Requests'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If records show up, your connection is fine. The problem lives inside your filter logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Isolate the Filter
&lt;/h2&gt;

&lt;p&gt;Add your filter back and watch what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filter(
    'Project Requests',
    Status.Value = "Approved"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the gallery goes blank again, you know the issue is inside the filter itself — not the data source.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handle Dropdown Filters with an "All" Option
&lt;/h2&gt;

&lt;p&gt;Dropdowns with no selected value can silently filter out everything. Use an &lt;code&gt;"All"&lt;/code&gt; fallback to prevent this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filter(
    'Project Requests',
    ddStatus.Selected.Value = "All" || Status.Value = ddStatus.Selected.Value
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, when &lt;code&gt;"All"&lt;/code&gt; is selected, every record passes through.&lt;/p&gt;




&lt;h2&gt;
  
  
  Debug Collections with a Count Label
&lt;/h2&gt;

&lt;p&gt;If your gallery is backed by a collection, add a temporary label to check whether it actually loaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CountRows(colProjectRequests)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that returns &lt;code&gt;0&lt;/code&gt;, the collection was never populated — check where &lt;code&gt;Collect()&lt;/code&gt; or &lt;code&gt;ClearCollect()&lt;/code&gt; is called and whether it runs on app start.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Debugging Principle
&lt;/h2&gt;

&lt;p&gt;Do not try to debug everything at once.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with the raw data source&lt;/li&gt;
&lt;li&gt;Confirm records appear&lt;/li&gt;
&lt;li&gt;Add each filter or condition back &lt;strong&gt;one step at a time&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Isolating variables is how you find the real problem fast.&lt;/p&gt;

</description>
      <category>powerapps</category>
      <category>microsoft</category>
      <category>lowcode</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Power Apps Filter vs LookUp vs Collections (Quick Guide for Beginners)</title>
      <dc:creator>Matt Hummel</dc:creator>
      <pubDate>Sat, 04 Apr 2026 15:18:14 +0000</pubDate>
      <link>https://dev.to/matthummeldev/power-apps-filter-vs-lookup-vs-collections-quick-guide-for-beginners-3afe</link>
      <guid>https://dev.to/matthummeldev/power-apps-filter-vs-lookup-vs-collections-quick-guide-for-beginners-3afe</guid>
      <description>&lt;p&gt;If you're learning Power Apps, these three come up fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filter&lt;/li&gt;
&lt;li&gt;LookUp&lt;/li&gt;
&lt;li&gt;Collections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re simple on their own — but easy to mix up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep This Straight
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Filter → multiple records (table)&lt;/li&gt;
&lt;li&gt;LookUp → one record&lt;/li&gt;
&lt;li&gt;Collections → stored data in memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most issues come from ignoring that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Things Go Wrong
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Common mistakes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using LookUp when multiple results exist&lt;/li&gt;
&lt;li&gt;Using Filter when you only need one record&lt;/li&gt;
&lt;li&gt;Storing everything in a collection “just in case”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app might still work at first… then break later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Filter (for lists)&lt;/li&gt;
&lt;li&gt;Filter(Requests, Status = "Approved")&lt;/li&gt;
&lt;li&gt;LookUp (for one record)&lt;/li&gt;
&lt;li&gt;LookUp(Users, Email = User().Email)&lt;/li&gt;
&lt;li&gt;Common mistake&lt;/li&gt;
&lt;li&gt;Filter(Users, Email = User().Email)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you’ve got a table, not a record — which complicates everything later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Filter + LookUp&lt;br&gt;
LookUp(&lt;br&gt;
    Filter(Orders, Status = "Pending"),&lt;br&gt;
    OrderID = varOrderID&lt;br&gt;
)&lt;br&gt;
Collections&lt;br&gt;
ClearCollect(colOrders, Orders)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use when reusing data — not for everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example That Breaks
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;LookUp(Approvals, Status = "Pending")&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Works… until multiple records match.
&lt;/h2&gt;

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

&lt;p&gt;&lt;code&gt;Filter(Approvals, Status = "Pending")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Rule&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need a list → Filter&lt;/li&gt;
&lt;li&gt;Need one record → LookUp&lt;/li&gt;
&lt;li&gt;Need to store data → Collections&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Most issues aren’t complicated — just small misunderstandings early on.&lt;/p&gt;

&lt;p&gt;And your app will usually still work… until it doesn’t.&lt;/p&gt;

&lt;p&gt;🔗 Full Post&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://bit.ly/filter-lookup" rel="noopener noreferrer"&gt;https://bit.ly/filter-lookup&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;💬 Question&lt;/p&gt;

&lt;p&gt;What’s something confusing you’ve run into with Filter or LookUp?&lt;/p&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
      <category>lowcode</category>
      <category>microsoft</category>
    </item>
  </channel>
</rss>
