<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>beginner guide Archives - Developry Plugins</title>
	<atom:link href="https://developryplugins.com/tag/beginner-guide/feed/" rel="self" type="application/rss+xml" />
	<link>https://developryplugins.com/tag/beginner-guide/</link>
	<description></description>
	<lastBuildDate>Mon, 24 Nov 2025 11:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://developryplugins.com/wp-content/uploads/2025/11/cropped-favicon-32x32.png</url>
	<title>beginner guide Archives - Developry Plugins</title>
	<link>https://developryplugins.com/tag/beginner-guide/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WordPress Plugin Development from Scratch: Complete Beginner&#8217;s Guide</title>
		<link>https://developryplugins.com/wordpress-plugin-development-from-scratch-complete-beginners-guide/</link>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[WordPress Plugin Development Guide]]></category>
		<category><![CDATA[beginner guide]]></category>
		<category><![CDATA[php development]]></category>
		<category><![CDATA[plugin development]]></category>
		<category><![CDATA[plugin tutorial]]></category>
		<category><![CDATA[wordpress plugins]]></category>
		<guid isPermaLink="false">https://developryplugins.com/?p=171</guid>

					<description><![CDATA[<p>WordPress plugin development opens endless possibilities for extending WordPress functionality. This beginner-friendly guide teaches you to build your first plugin from scratch, even if you’ve never written PHP code before....</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-development-from-scratch-complete-beginners-guide/">WordPress Plugin Development from Scratch: Complete Beginner&#8217;s Guide</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><!-- @format --></p>
<p>WordPress plugin development opens endless possibilities for extending WordPress functionality. This beginner-friendly guide teaches you to build your first plugin from scratch, even if you’ve never written PHP code before. You’ll learn fundamental concepts, best practices, and create a functioning plugin by the end.</p>
<h2 id="what-are-wordpress-plugins">What Are WordPress Plugins?</h2>
<p>Plugins are PHP files that extend WordPress core functionality without modifying core files. They add features, modify behavior, and integrate services. WordPress’s extensive plugin API provides hooks and functions that let you tap into WordPress at precise moments during execution.</p>
<p>Understanding this principle is crucial: never modify WordPress core. Always build plugins (or themes) to add functionality. This keeps your changes upgrade-safe and maintainable.</p>
<h2 id="prerequisites-and-setup">Prerequisites and Setup</h2>
<p>Before starting, ensure you have:</p>
<ul>
<li><strong>Basic PHP knowledge</strong> &#8211; Understand variables, functions, arrays</li>
<li><strong>HTML/CSS basics</strong> &#8211; Know how to structure and style content</li>
<li><strong>Local development environment</strong> &#8211; LocalWP, MAMP, or Docker</li>
<li><strong>Code editor</strong> &#8211; VS Code, PhpStorm, or Sublime Text</li>
</ul>
<p>Install LocalWP for the easiest local WordPress setup. It handles server configuration, making development straightforward for beginners.</p>
<h2 id="your-first-plugin-file">Your First Plugin File</h2>
<p>Create a new folder in <code>wp-content/plugins/</code> named <code>my-first-plugin</code>. Inside, create <code>my-first-plugin.php</code>:</p>
<div class="sourceCode" id="cb1">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="kw">&lt;?php</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="co">/**</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a><span class="co"> * Plugin Name: My First Plugin</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a><span class="co"> * Plugin URI: https://example.com/my-first-plugin</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a><span class="co"> * Description: A simple plugin to learn WordPress development</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a><span class="co"> * Version: 1.0.0</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a><span class="co"> * Author: Your Name</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a><span class="co"> * Author URI: https://example.com</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a><span class="co"> * License: GPL v2 or later</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a><span class="co"> * License URI: https://www.gnu.org/licenses/gpl-2.0.html</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a><span class="co"> * Text Domain: my-first-plugin</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a><span class="co"> * Domain Path: /languages</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a><span class="co"> */</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a><span class="co">// If this file is called directly, abort.</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! <span class="fu">defined</span><span class="ot">(</span> <span class="st">&#39;WPINC&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>    <span class="kw">die</span><span class="ot">;</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>The header comment tells WordPress about your plugin. Required fields are Plugin Name and Description. The security check prevents direct file access.</p>
<p>Navigate to Plugins in your WordPress admin. You’ll see “My First Plugin” listed. Click Activate.</p>
<h2 id="understanding-wordpress-hooks">Understanding WordPress Hooks</h2>
<p>Hooks are WordPress’s event system. They allow your plugin to execute code at specific moments.</p>
<p><strong>Actions</strong> let you run code at specific points:</p>
<div class="sourceCode" id="cb2">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="kw">function</span> dprt_welcome_message<span class="ot">()</span> {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>    <span class="kw">echo</span> <span class="st">&#39;&lt;div class=&quot;notice notice-info&quot;&gt;&lt;p&gt;Welcome to our site!&lt;/p&gt;&lt;/div&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>}</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;admin_notices&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_welcome_message&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>This displays a message in the WordPress admin when the <code>admin_notices</code> action fires.</p>
<p><strong>Filters</strong> let you modify data:</p>
<div class="sourceCode" id="cb3">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="kw">function</span> dprt_modify_excerpt_length<span class="ot">(</span> <span class="kw">$length</span> <span class="ot">)</span> {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a>    <span class="kw">return</span> <span class="dv">30</span><span class="ot">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a>}</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>add_filter<span class="ot">(</span> <span class="st">&#39;excerpt_length&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_modify_excerpt_length&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>This changes excerpt length to 30 words by filtering the default value.</p>
<h2 id="common-hooks-for-beginners">Common Hooks for Beginners</h2>
<p>Start with these essential hooks:</p>
<p><strong><code>init</code></strong> &#8211; Fires after WordPress finishes loading. Use it for registering post types, taxonomies, and initialization:</p>
<div class="sourceCode" id="cb4">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="kw">function</span> dprt_init_plugin<span class="ot">()</span> {</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a>    <span class="co">// Register custom post types, taxonomies, etc.</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a>}</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;init&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_init_plugin&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p><strong><code>wp_enqueue_scripts</code></strong> &#8211; Load CSS and JavaScript for frontend:</p>
<div class="sourceCode" id="cb5">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a><span class="kw">function</span> dprt_enqueue_assets<span class="ot">()</span> {</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a>    wp_enqueue_style<span class="ot">(</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a>        <span class="st">&#39;dprt-styles&#39;</span><span class="ot">,</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a>        plugin_dir_url<span class="ot">(</span> <span class="kw">__FILE__</span> <span class="ot">)</span> . <span class="st">&#39;assets/css/style.css&#39;</span><span class="ot">,</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a>        <span class="kw">array</span><span class="ot">(),</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a>        <span class="st">&#39;1.0.0&#39;</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a>    <span class="ot">);</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a>    wp_enqueue_script<span class="ot">(</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a>        <span class="st">&#39;dprt-scripts&#39;</span><span class="ot">,</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true"></a>        plugin_dir_url<span class="ot">(</span> <span class="kw">__FILE__</span> <span class="ot">)</span> . <span class="st">&#39;assets/js/script.js&#39;</span><span class="ot">,</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true"></a>        <span class="kw">array</span><span class="ot">(</span> <span class="st">&#39;jquery&#39;</span> <span class="ot">),</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a>        <span class="st">&#39;1.0.0&#39;</span><span class="ot">,</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a>        <span class="kw">true</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a>    <span class="ot">);</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a>}</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;wp_enqueue_scripts&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_enqueue_assets&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p><strong><code>admin_menu</code></strong> &#8211; Add admin menu pages:</p>
<div class="sourceCode" id="cb6">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="kw">function</span> dprt_add_menu_page<span class="ot">()</span> {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a>    add_menu_page<span class="ot">(</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>        <span class="st">&#39;My Plugin Settings&#39;</span><span class="ot">,</span>  <span class="co">// Page title</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>        <span class="st">&#39;My Plugin&#39;</span><span class="ot">,</span>           <span class="co">// Menu title</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a>        <span class="st">&#39;manage_options&#39;</span><span class="ot">,</span>      <span class="co">// Capability required</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a>        <span class="st">&#39;my-plugin&#39;</span><span class="ot">,</span>           <span class="co">// Menu slug</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>        <span class="st">&#39;dprt_settings_page&#39;</span><span class="ot">,</span>  <span class="co">// Function to display page</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a>        <span class="st">&#39;dashicons-admin-generic&#39;</span><span class="ot">,</span> <span class="co">// Icon</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a>        <span class="dv">20</span>                     <span class="co">// Position</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a>    <span class="ot">);</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a>}</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;admin_menu&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_add_menu_page&#39;</span> <span class="ot">);</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a><span class="kw">function</span> dprt_settings_page<span class="ot">()</span> {</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a>    <span class="kw">echo</span> <span class="st">&#39;&lt;div class=&quot;wrap&quot;&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a>    <span class="kw">echo</span> <span class="st">&#39;&lt;h1&gt;My Plugin Settings&lt;/h1&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a>    <span class="kw">echo</span> <span class="st">&#39;&lt;p&gt;Settings page content goes here.&lt;/p&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a>    <span class="kw">echo</span> <span class="st">&#39;&lt;/div&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="plugin-activation-and-deactivation">Plugin Activation and Deactivation</h2>
<p>Run code when plugins activate or deactivate:</p>
<div class="sourceCode" id="cb7">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="kw">function</span> dprt_activate_plugin<span class="ot">()</span> {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a>    <span class="co">// Set default options</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a>    add_option<span class="ot">(</span> <span class="st">&#39;dprt_welcome_message&#39;</span><span class="ot">,</span> <span class="st">&#39;Welcome to our site!&#39;</span> <span class="ot">);</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a>    <span class="co">// Create custom database tables if needed</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a>    <span class="co">// Flush rewrite rules if registering custom post types</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a>    flush_rewrite_rules<span class="ot">();</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a>}</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a>register_activation_hook<span class="ot">(</span> <span class="kw">__FILE__</span><span class="ot">,</span> <span class="st">&#39;dprt_activate_plugin&#39;</span> <span class="ot">);</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a><span class="kw">function</span> dprt_deactivate_plugin<span class="ot">()</span> {</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>    <span class="co">// Clean up temporary data</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true"></a>    <span class="co">// Flush rewrite rules</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true"></a>    flush_rewrite_rules<span class="ot">();</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true"></a></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true"></a>    <span class="co">// Don&#39;t delete user data on deactivation</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true"></a>    <span class="co">// Save that for uninstall</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true"></a>}</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true"></a>register_deactivation_hook<span class="ot">(</span> <span class="kw">__FILE__</span><span class="ot">,</span> <span class="st">&#39;dprt_deactivate_plugin&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Never delete user data on deactivation. Users might temporarily deactivate to troubleshoot. Save deletion for uninstall.</p>
<h2 id="the-options-api">The Options API</h2>
<p>Store plugin settings using the Options API:</p>
<div class="sourceCode" id="cb8">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co">// Save option</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a>update_option<span class="ot">(</span> <span class="st">&#39;dprt_setting_name&#39;</span><span class="ot">,</span> <span class="st">&#39;value&#39;</span> <span class="ot">);</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a><span class="co">// Get option</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a><span class="kw">$setting</span> = get_option<span class="ot">(</span> <span class="st">&#39;dprt_setting_name&#39;</span><span class="ot">,</span> <span class="st">&#39;default value&#39;</span> <span class="ot">);</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a><span class="co">// Delete option</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a>delete_option<span class="ot">(</span> <span class="st">&#39;dprt_setting_name&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Options are stored in the wp_options table. Use them for plugin configuration, user preferences, and cached data.</p>
<h2 id="plugin-security-basics">Plugin Security Basics</h2>
<p>Security is paramount. Follow these practices from day one:</p>
<p><strong>Sanitize input</strong> &#8211; Clean data users provide:</p>
<div class="sourceCode" id="cb9">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="kw">$user_input</span> = sanitize_text_field<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;input_field&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="kw">$email</span> = sanitize_email<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;email_field&#39;</span><span class="ot">]</span> <span class="ot">);</span></span></code></pre>
</div>
<p><strong>Escape output</strong> &#8211; Prevent XSS attacks:</p>
<div class="sourceCode" id="cb10">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;p&gt;&#39;</span> . esc_html<span class="ot">(</span> <span class="kw">$user_data</span> <span class="ot">)</span> . <span class="st">&#39;&lt;/p&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a><span class="kw">echo</span> <span class="st">&#39;&lt;a href=&quot;&#39;</span> . esc_url<span class="ot">(</span> <span class="kw">$link</span> <span class="ot">)</span> . <span class="st">&#39;&quot;&gt;Link&lt;/a&gt;&#39;</span><span class="ot">;</span></span></code></pre>
</div>
<p><strong>Use nonces</strong> &#8211; Verify form submissions:</p>
<div class="sourceCode" id="cb11">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="co">// Create nonce</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a>wp_nonce_field<span class="ot">(</span> <span class="st">&#39;dprt_save_settings&#39;</span><span class="ot">,</span> <span class="st">&#39;dprt_settings_nonce&#39;</span> <span class="ot">);</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a><span class="co">// Verify nonce</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! wp_verify_nonce<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;dprt_settings_nonce&#39;</span><span class="ot">],</span> <span class="st">&#39;dprt_save_settings&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a>    wp_die<span class="ot">(</span> <span class="st">&#39;Security check failed&#39;</span> <span class="ot">);</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a>}</span></code></pre>
</div>
<p><strong>Check capabilities</strong> &#8211; Ensure users have permission:</p>
<div class="sourceCode" id="cb12">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! current_user_can<span class="ot">(</span> <span class="st">&#39;manage_options&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a>    wp_die<span class="ot">(</span> <span class="st">&#39;Unauthorized access&#39;</span> <span class="ot">);</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="organizing-plugin-files">Organizing Plugin Files</h2>
<p>As plugins grow, organize code across multiple files:</p>
<pre><code>my-first-plugin/
├── my-first-plugin.php    (Main file)
├── includes/
│   ├── class-admin.php
│   ├── class-frontend.php
│   └── functions.php
├── assets/
│   ├── css/
│   │   └── style.css
│   └── js/
│       └── script.js
└── languages/</code></pre>
<p>Include files in your main plugin file:</p>
<div class="sourceCode" id="cb14">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true"></a><span class="kw">require_once</span> plugin_dir_path<span class="ot">(</span> <span class="kw">__FILE__</span> <span class="ot">)</span> . <span class="st">&#39;includes/functions.php&#39;</span><span class="ot">;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true"></a><span class="kw">require_once</span> plugin_dir_path<span class="ot">(</span> <span class="kw">__FILE__</span> <span class="ot">)</span> . <span class="st">&#39;includes/class-admin.php&#39;</span><span class="ot">;</span></span></code></pre>
</div>
<h2 id="debugging-your-plugin">Debugging Your Plugin</h2>
<p>Enable WordPress debugging in wp-config.php:</p>
<div class="sourceCode" id="cb15">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true"></a><span class="fu">define</span><span class="ot">(</span> <span class="st">&#39;WP_DEBUG&#39;</span><span class="ot">,</span> <span class="kw">true</span> <span class="ot">);</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true"></a><span class="fu">define</span><span class="ot">(</span> <span class="st">&#39;WP_DEBUG_LOG&#39;</span><span class="ot">,</span> <span class="kw">true</span> <span class="ot">);</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true"></a><span class="fu">define</span><span class="ot">(</span> <span class="st">&#39;WP_DEBUG_DISPLAY&#39;</span><span class="ot">,</span> <span class="kw">false</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Log debug messages:</p>
<div class="sourceCode" id="cb16">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true"></a><span class="fu">error_log</span><span class="ot">(</span> <span class="st">&#39;Debug message: &#39;</span> . <span class="fu">print_r</span><span class="ot">(</span> <span class="kw">$variable</span><span class="ot">,</span> <span class="kw">true</span> <span class="ot">)</span> <span class="ot">);</span></span></code></pre>
</div>
<p>Check <code>/wp-content/debug.log</code> for logged errors.</p>
<h2 id="building-a-complete-example-plugin">Building a Complete Example Plugin</h2>
<p>Let’s build a simple quote display plugin:</p>
<div class="sourceCode" id="cb17">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true"></a><span class="kw">&lt;?php</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true"></a><span class="co">/**</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true"></a><span class="co"> * Plugin Name: Simple Quote Display</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true"></a><span class="co"> * Description: Display random quotes on your site</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true"></a><span class="co"> * Version: 1.0.0</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true"></a><span class="co"> */</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true"></a></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true"></a><span class="kw">if</span> <span class="ot">(</span> ! <span class="fu">defined</span><span class="ot">(</span> <span class="st">&#39;WPINC&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true"></a>    <span class="kw">die</span><span class="ot">;</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true"></a>}</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true"></a></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true"></a><span class="co">// Add admin menu</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true"></a><span class="kw">function</span> sqd_add_menu<span class="ot">()</span> {</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true"></a>    add_menu_page<span class="ot">(</span></span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true"></a>        <span class="st">&#39;Quotes&#39;</span><span class="ot">,</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true"></a>        <span class="st">&#39;Quotes&#39;</span><span class="ot">,</span></span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true"></a>        <span class="st">&#39;manage_options&#39;</span><span class="ot">,</span></span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true"></a>        <span class="st">&#39;sqd-quotes&#39;</span><span class="ot">,</span></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true"></a>        <span class="st">&#39;sqd_quotes_page&#39;</span><span class="ot">,</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true"></a>        <span class="st">&#39;dashicons-format-quote&#39;</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true"></a>    <span class="ot">);</span></span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true"></a>}</span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true"></a>add_action<span class="ot">(</span> <span class="st">&#39;admin_menu&#39;</span><span class="ot">,</span> <span class="st">&#39;sqd_add_menu&#39;</span> <span class="ot">);</span></span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true"></a></span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true"></a><span class="co">// Admin page</span></span>
<span id="cb17-26"><a href="#cb17-26" aria-hidden="true"></a><span class="kw">function</span> sqd_quotes_page<span class="ot">()</span> {</span>
<span id="cb17-27"><a href="#cb17-27" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> <span class="kw">isset</span><span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;sqd_add_quote&#39;</span><span class="ot">]</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb17-28"><a href="#cb17-28" aria-hidden="true"></a>        <span class="kw">if</span> <span class="ot">(</span> ! wp_verify_nonce<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;sqd_nonce&#39;</span><span class="ot">],</span> <span class="st">&#39;sqd_add_quote&#39;</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb17-29"><a href="#cb17-29" aria-hidden="true"></a>            wp_die<span class="ot">(</span> <span class="st">&#39;Security check failed&#39;</span> <span class="ot">);</span></span>
<span id="cb17-30"><a href="#cb17-30" aria-hidden="true"></a>        }</span>
<span id="cb17-31"><a href="#cb17-31" aria-hidden="true"></a></span>
<span id="cb17-32"><a href="#cb17-32" aria-hidden="true"></a>        <span class="kw">$quote</span> = sanitize_textarea_field<span class="ot">(</span> <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;quote&#39;</span><span class="ot">]</span> <span class="ot">);</span></span>
<span id="cb17-33"><a href="#cb17-33" aria-hidden="true"></a>        <span class="kw">$quotes</span> = get_option<span class="ot">(</span> <span class="st">&#39;sqd_quotes&#39;</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">()</span> <span class="ot">);</span></span>
<span id="cb17-34"><a href="#cb17-34" aria-hidden="true"></a>        <span class="kw">$quotes</span><span class="ot">[]</span> = <span class="kw">$quote</span><span class="ot">;</span></span>
<span id="cb17-35"><a href="#cb17-35" aria-hidden="true"></a>        update_option<span class="ot">(</span> <span class="st">&#39;sqd_quotes&#39;</span><span class="ot">,</span> <span class="kw">$quotes</span> <span class="ot">);</span></span>
<span id="cb17-36"><a href="#cb17-36" aria-hidden="true"></a>    }</span>
<span id="cb17-37"><a href="#cb17-37" aria-hidden="true"></a></span>
<span id="cb17-38"><a href="#cb17-38" aria-hidden="true"></a>    <span class="kw">$quotes</span> = get_option<span class="ot">(</span> <span class="st">&#39;sqd_quotes&#39;</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">()</span> <span class="ot">);</span></span>
<span id="cb17-39"><a href="#cb17-39" aria-hidden="true"></a>    <span class="kw">?&gt;</span></span>
<span id="cb17-40"><a href="#cb17-40" aria-hidden="true"></a>    &lt;div <span class="kw">class</span>=<span class="st">&quot;wrap&quot;</span>&gt;</span>
<span id="cb17-41"><a href="#cb17-41" aria-hidden="true"></a>        &lt;h1&gt;Manage Quotes&lt;/h1&gt;</span>
<span id="cb17-42"><a href="#cb17-42" aria-hidden="true"></a>        &lt;form method=<span class="st">&quot;post&quot;</span>&gt;</span>
<span id="cb17-43"><a href="#cb17-43" aria-hidden="true"></a>            &lt;<span class="ot">?</span>php wp_nonce_field<span class="ot">(</span> <span class="st">&#39;sqd_add_quote&#39;</span><span class="ot">,</span> <span class="st">&#39;sqd_nonce&#39;</span> <span class="ot">);</span> <span class="kw">?&gt;</span></span>
<span id="cb17-44"><a href="#cb17-44" aria-hidden="true"></a>            &lt;textarea name=<span class="st">&quot;quote&quot;</span> rows=<span class="st">&quot;3&quot;</span> cols=<span class="st">&quot;50&quot;</span>&gt;&lt;/textarea&gt;</span>
<span id="cb17-45"><a href="#cb17-45" aria-hidden="true"></a>            &lt;input type=<span class="st">&quot;submit&quot;</span> name=<span class="st">&quot;sqd_add_quote&quot;</span> value=<span class="st">&quot;Add Quote&quot;</span> <span class="kw">class</span>=<span class="st">&quot;button button-primary&quot;</span>&gt;</span>
<span id="cb17-46"><a href="#cb17-46" aria-hidden="true"></a>        &lt;/form&gt;</span>
<span id="cb17-47"><a href="#cb17-47" aria-hidden="true"></a>        &lt;h2&gt;Existing Quotes&lt;/h2&gt;</span>
<span id="cb17-48"><a href="#cb17-48" aria-hidden="true"></a>        &lt;ul&gt;</span>
<span id="cb17-49"><a href="#cb17-49" aria-hidden="true"></a>            &lt;<span class="ot">?</span>php <span class="kw">foreach</span> <span class="ot">(</span> <span class="kw">$quotes</span> <span class="kw">as</span> <span class="kw">$quote</span> <span class="ot">)</span> <span class="ot">:</span> <span class="kw">?&gt;</span></span>
<span id="cb17-50"><a href="#cb17-50" aria-hidden="true"></a>                &lt;li&gt;&lt;<span class="ot">?</span>php <span class="kw">echo</span> esc_html<span class="ot">(</span> <span class="kw">$quote</span> <span class="ot">);</span> <span class="kw">?&gt;</span>&lt;/li&gt;</span>
<span id="cb17-51"><a href="#cb17-51" aria-hidden="true"></a>            &lt;<span class="ot">?</span>php <span class="kw">endfor</span>each<span class="ot">;</span> <span class="kw">?&gt;</span></span>
<span id="cb17-52"><a href="#cb17-52" aria-hidden="true"></a>        &lt;/ul&gt;</span>
<span id="cb17-53"><a href="#cb17-53" aria-hidden="true"></a>    &lt;/div&gt;</span>
<span id="cb17-54"><a href="#cb17-54" aria-hidden="true"></a>    &lt;<span class="ot">?</span>php</span>
<span id="cb17-55"><a href="#cb17-55" aria-hidden="true"></a>}</span>
<span id="cb17-56"><a href="#cb17-56" aria-hidden="true"></a></span>
<span id="cb17-57"><a href="#cb17-57" aria-hidden="true"></a><span class="co">// Shortcode to display random quote</span></span>
<span id="cb17-58"><a href="#cb17-58" aria-hidden="true"></a><span class="kw">function</span> sqd_display_quote<span class="ot">()</span> {</span>
<span id="cb17-59"><a href="#cb17-59" aria-hidden="true"></a>    <span class="kw">$quotes</span> = get_option<span class="ot">(</span> <span class="st">&#39;sqd_quotes&#39;</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">()</span> <span class="ot">);</span></span>
<span id="cb17-60"><a href="#cb17-60" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ot">(</span> <span class="kw">empty</span><span class="ot">(</span> <span class="kw">$quotes</span> <span class="ot">)</span> <span class="ot">)</span> {</span>
<span id="cb17-61"><a href="#cb17-61" aria-hidden="true"></a>        <span class="kw">return</span> <span class="st">&#39;&#39;</span><span class="ot">;</span></span>
<span id="cb17-62"><a href="#cb17-62" aria-hidden="true"></a>    }</span>
<span id="cb17-63"><a href="#cb17-63" aria-hidden="true"></a>    <span class="kw">$random_quote</span> = <span class="kw">$quotes</span><span class="ot">[</span> <span class="fu">array_rand</span><span class="ot">(</span> <span class="kw">$quotes</span> <span class="ot">)</span> <span class="ot">];</span></span>
<span id="cb17-64"><a href="#cb17-64" aria-hidden="true"></a>    <span class="kw">return</span> <span class="st">&#39;&lt;blockquote class=&quot;sqd-quote&quot;&gt;&#39;</span> . esc_html<span class="ot">(</span> <span class="kw">$random_quote</span> <span class="ot">)</span> . <span class="st">&#39;&lt;/blockquote&gt;&#39;</span><span class="ot">;</span></span>
<span id="cb17-65"><a href="#cb17-65" aria-hidden="true"></a>}</span>
<span id="cb17-66"><a href="#cb17-66" aria-hidden="true"></a>add_shortcode<span class="ot">(</span> <span class="st">&#39;random_quote&#39;</span><span class="ot">,</span> <span class="st">&#39;sqd_display_quote&#39;</span> <span class="ot">);</span></span></code></pre>
</div>
<p>This complete plugin adds quotes via admin, stores them, and displays them with <code>[random_quote]</code> shortcode.</p>
<h2 id="common-beginner-mistakes">Common Beginner Mistakes</h2>
<p>Avoid these pitfalls:</p>
<ul>
<li><strong>Not using prefixes</strong> &#8211; Prefix all functions to avoid conflicts</li>
<li><strong>Forgetting security</strong> &#8211; Always sanitize, escape, and verify</li>
<li><strong>Ignoring WordPress functions</strong> &#8211; Use WordPress APIs instead of raw PHP/SQL</li>
<li><strong>Not testing</strong> &#8211; Test across WordPress versions and with other plugins</li>
<li><strong>Poor error handling</strong> &#8211; Anticipate failures and handle gracefully</li>
</ul>
<h2 id="next-steps">Next Steps</h2>
<p>After mastering basics:</p>
<ol type="1">
<li>Study the Plugin Handbook thoroughly</li>
<li>Explore the Settings API for complex settings pages</li>
<li>Learn custom post types and taxonomies</li>
<li>Understand the REST API for modern integrations</li>
<li>Study established plugins’ code on GitHub</li>
</ol>
<h2 id="conclusion">Conclusion</h2>
<p>WordPress plugin development is accessible to beginners willing to learn. Start with simple plugins, follow security best practices, use WordPress APIs, and gradually build complexity. Your first plugin might be basic, but it establishes the foundation for building sophisticated WordPress extensions.</p>
<h2 id="external-links">External Links</h2>
<ol type="1">
<li><a href="https://developer.wordpress.org/plugins/">WordPress Plugin Handbook</a></li>
<li><a href="https://developer.wordpress.org/plugins/plugin-basics/">Plugin Basics</a></li>
<li><a href="https://localwp.com/">Local by Flywheel</a></li>
<li><a href="https://developer.wordpress.org/coding-standards/">WordPress Coding Standards</a></li>
<li><a href="https://developer.wordpress.org/">WordPress Developer Resources</a></li>
</ol>
<h2 id="call-to-action">Call to Action</h2>
<p>Supercharge your development! <a href="https://acfcopilotplugin.com/">ACF Copilot Pro</a> generates ACF field groups with AI, exports to PHP, and accelerates custom field workflows—try it free!</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-development-from-scratch-complete-beginners-guide/">WordPress Plugin Development from Scratch: Complete Beginner&#8217;s Guide</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
