{"id":143486,"date":"2025-11-20T04:28:37","date_gmt":"2025-11-20T02:28:37","guid":{"rendered":"https:\/\/elementor.com\/blog\/?p=143486"},"modified":"2025-11-20T14:42:44","modified_gmt":"2025-11-20T12:42:44","slug":"how-to-create-a-wordpress-shortcode","status":"publish","type":"post","link":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/","title":{"rendered":"How to Create a WordPress Shortcode in 7 Steps (A Developer&#8217;s Guide)"},"content":{"rendered":"\n<p>But what happens when a plugin doesn&#8217;t exist for the specific, custom content you need? The answer is to create your own. This guide provides a comprehensive, 7-step process for professionals, agencies, and curious creators who want to learn how to build their own custom shortcodes. We will cover everything from the basic &#8220;Hello, World!&#8221; to advanced, attribute-driven shortcodes, all while following modern WordPress best practices.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Key Takeaways<\/strong><\/h2>\n\n\n\n<p>Before we dive into the code, here are the essential takeaways you should know about creating shortcodes in WordPress:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What a Shortcode Is:<\/strong> A shortcode is a WordPress-specific macro. It&#8217;s a small piece of text in brackets, like [current_year], that WordPress replaces with dynamic content (like &#8220;2025&#8221;) when the page is loaded.<\/li>\n\n\n\n<li><strong>The Golden Rule: <\/strong><strong>return<\/strong><strong>, Don&#8217;t <\/strong><strong>echo<\/strong><strong>:<\/strong> The number one mistake beginners make is using echo inside a shortcode function. This will print the data at the top of your page, out of order. Your function <strong>must<\/strong> return the final HTML or text as a string.<\/li>\n\n\n\n<li><strong>The Best Place for Your Code:<\/strong> Never add custom code snippets to your theme&#8217;s functions.php file. If you change themes, your shortcodes will break. The professional method is to use a <strong>site-specific plugin<\/strong>, which is a simple plugin you create to hold all your site&#8217;s custom code.<\/li>\n\n\n\n<li><strong>The 7 Core Steps:<\/strong> The process is straightforward:\n<ol class=\"wp-block-list\">\n<li>Decide where your code will live (a site-specific plugin).<\/li>\n\n\n\n<li>Create that plugin file.<\/li>\n\n\n\n<li>Write the PHP function that generates your content.<\/li>\n\n\n\n<li>Register your shortcode tag with add_shortcode().<\/li>\n\n\n\n<li>Test it in the editor.<\/li>\n\n\n\n<li>Add attributes ($atts) to make it flexible.<\/li>\n\n\n\n<li>Handle enclosing content ($content) for wrapper shortcodes.<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li><strong>Shortcodes vs. Modern Builders:<\/strong> For visual layout and design (like buttons, columns, or styled sections), shortcodes are an outdated, clunky method. A modern visual builder like<a href=\"https:\/\/elementor.com\"> Elementor<\/a> provides a faster, more intuitive, &#8220;drag-and-drop&#8221; workflow.<\/li>\n\n\n\n<li><strong>The Modern Use for Shortcodes:<\/strong> Shortcodes are not dead. They are perfect for embedding <em>dynamic content<\/em> or <em>plugin functionality<\/em> (like a form or a product grid) into a page.<\/li>\n\n\n\n<li><strong>Elementor Loves Shortcodes:<\/strong> Modern page builders like<a href=\"https:\/\/elementor.com\"> Elementor<\/a> fully embrace shortcodes. They provide a dedicated &#8220;Shortcode&#8221; widget, allowing you to visually place your custom shortcode (or a plugin&#8217;s shortcode) anywhere in your design.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is a WordPress Shortcode?<\/strong><\/h2>\n\n\n\n<p>At its simplest, a shortcode is a shortcut. It\u2019s a small, human-readable tag enclosed in square brackets that WordPress is trained to recognize. When WordPress renders a page, it scans the content for these bracketed tags. When it finds one, it stops, replaces that tag with the output of a specific PHP function, and then continues.<\/p>\n\n\n\n<p>Think of it as a mail-merge field for your website. You write [user_name] in the editor, but your visitor sees &#8220;Hello, Jane!&#8221; on the frontend. The shortcode is the bridge between that simple tag and the complex code required to find and display the user&#8217;s name.<\/p>\n\n\n\n<p>This system is what powers thousands of plugins. When you install a contact form plugin and it tells you to add [my_contact_form] to your page, you are using its shortcode.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>A Deeper Dive: How Shortcodes Actually Work<\/strong><\/h3>\n\n\n\n<p>The magic behind this system is the <strong>Shortcode API<\/strong>. This is a set of functions built into the WordPress core that developers can use to create their own shortcuts.<\/p>\n\n\n\n<p>The entire process works in two parts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Registration:<\/strong> A developer uses a function called add_shortcode(). This function tells WordPress, &#8220;Hey, if you ever see the tag [my_tag], I want you to run <em>this<\/em> specific PHP function.&#8221;<\/li>\n\n\n\n<li><strong>Execution:<\/strong> When a visitor loads a page, WordPress runs the content through a filter called do_shortcode(). This filter&#8217;s job is to scan the text, find all registered shortcode tags, run their corresponding functions, and replace the tags with whatever string of HTML or text those functions return.<\/li>\n<\/ol>\n\n\n\n<p>This is a brilliant system because it hides complexity. Your content editor remains clean, holding just the simple [my_tag], while all the messy HTML and PHP logic is tucked away in a plugin file where it belongs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>The Two Main Types of Shortcodes<\/strong><\/h3>\n\n\n\n<p>You will encounter two different syntaxes for shortcodes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>1. Self-Closing Shortcodes<\/strong><\/h4>\n\n\n\n<p>This is the most common type. It\u2019s a single tag that stands on its own. It&#8217;s used to insert a self-contained piece of content.<\/p>\n\n\n\n<p><strong>Syntax:<\/strong><\/p>\n\n\n<p>[my_shortcode]<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:12pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">Examples:<\/span><\/p>\n<ul style=\"margin-top:0;margin-bottom:0;padding-inline-start:48px\">\n<li dir=\"ltr\" style=\"list-style-type:disc;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:0pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[current_year]<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> &#8211; Inserts &#8220;2025&#8221;.<\/span><\/p>\n<\/li>\n<li dir=\"ltr\" style=\"list-style-type:disc;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[latest_posts_gallery]<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> &#8211; Inserts a gallery of images.<\/span><\/p>\n<\/li>\n<li dir=\"ltr\" style=\"list-style-type:disc;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:12pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[main_contact_form]<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> &#8211; Inserts a form.<\/span><\/p>\n<\/li>\n<\/ul>\n<h4 dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:2pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">2. Enclosing Shortcodes<\/span><\/h4>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:12pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">This type acts as a wrapper. It has an opening tag and a closing tag, and it modifies the content <\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline\">between<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> them.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:12pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">Syntax:<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> <\/span><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[my_shortcode]This is the content.[\/my_shortcode]<\/p>\n\n\n\n<p><strong>Examples:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[alert_box type=&#8221;warning&#8221;]This is a warning![\/alert_box] &#8211; Wraps the text in a styled warning box.<\/li>\n\n\n\n<li>[collapsible_text title=&#8221;Click to Read More&#8221;]This content is hidden.[\/collapsible_text] &#8211; Hides the content inside a toggle.<\/li>\n\n\n\n<li>[private_content]This is only for members.[\/private_content] &#8211; Hides the content from non-logged-in users.<\/li>\n<\/ul>\n\n\n\n<p>We will learn how to build all of these, starting with the simplest.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Before You Start: Do You Even Need a Custom Shortcode?<\/strong><\/h2>\n\n\n\n<p>As a web creation professional with years of experience, I can tell you that the most common mistake is building something you don&#8217;t need to. Before you write a single line of code, you must ask: <strong>Is a custom shortcode the right tool for this job?<\/strong><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>The &#8220;Plugin Ecosystem&#8221; Solution<\/strong><\/h4>\n\n\n\n<p>First, <strong>90% of the time, a plugin already exists for what you want to do.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Need a contact form? Don&#8217;t build a shortcode. Use a plugin like Contact Form 7 or WPForms.<\/li>\n\n\n\n<li>Need an image gallery? Use a gallery plugin or the built-in WordPress block.<\/li>\n\n\n\n<li>Need to sell products?<a href=\"https:\/\/elementor.com\/features\/woocommerce-builder\"> WooCommerce<\/a> provides a massive library of shortcodes like [products] and [add_to_cart].<\/li>\n<\/ul>\n\n\n\n<p>Always search for an existing, well-supported plugin first. It&#8217;s faster, more secure, and maintained by other developers, saving you time.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>The Modern Alternative: Visual Website Builders<\/strong><\/h4>\n\n\n\n<p>Second, if your goal is to design a <strong>layout<\/strong> or <strong>styled element<\/strong> (like a custom button, a styled pricing table, or a &#8220;call to action&#8221; box), <strong>a shortcode is the wrong tool.<\/strong><\/p>\n\n\n\n<p>This was the &#8220;old way&#8221; of doing things. We used to write clunky shortcodes like this: [button link=&#8221;\/contact&#8221; color=&#8221;blue&#8221; size=&#8221;large&#8221;]Click Here![\/button]<\/p>\n\n\n\n<p>This is terrible for a user. They can&#8217;t see what the button looks like. They have to remember all the attribute names. It&#8217;s slow and frustrating.<\/p>\n\n\n\n<p>This entire workflow has been made obsolete by modern visual website builders. A platform like<a href=\"https:\/\/elementor.com\"> Elementor<\/a> replaces this clunky-text-based system with a fast, intuitive, visual one.<\/p>\n\n\n\n<p>Instead of writing that shortcode, you now:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Drag a &#8220;Button&#8221; widget from the panel onto your page.<\/li>\n\n\n\n<li>Visually change the color with a color picker.<\/li>\n\n\n\n<li>Type the text directly on the button.<\/li>\n\n\n\n<li>See the final result in real-time.<\/li>\n<\/ol>\n\n\n\n<p>This visual workflow is infinitely superior for design and layout. You get pixel-perfect control without writing a single line of code or remembering a single shortcode tag.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>When to Create Your Own Shortcode<\/strong><\/h4>\n\n\n\n<p>So, if plugins handle most features and builders handle most designs, when do you create your own?<\/p>\n\n\n\n<p>You build a custom shortcode when you have a <strong>specific, custom piece of dynamic data<\/strong> that needs to be easily inserted into your content.<\/p>\n\n\n\n<p><strong>Good examples of custom shortcodes:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[current_year] &#8211; To automatically update your copyright footer.<\/li>\n\n\n\n<li>[business_phone] &#8211; To display a phone number. If the number changes, you only update it in one place (the function) and it updates on all 50 pages where it&#8217;s used.<\/li>\n\n\n\n<li>[user_first_name] &#8211; To greet a logged-in user by their name.<\/li>\n\n\n\n<li>[custom_post_query type=&#8221;event&#8221; count=&#8221;3&#8243;] &#8211; To show a list of the 3 most recent &#8220;Event&#8221; custom posts.<\/li>\n<\/ul>\n\n\n\n<p>See the pattern? Shortcodes are for <strong>dynamic content macros<\/strong>, not for visual design.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How to Create a Shortcode in WordPress: The 7-Step Guide<\/strong><\/h2>\n\n\n\n<p>Ready to build? Let&#8217;s go through the entire process, from start to finish, using professional best practices.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1: Decide Where Your Code Will Live (The Right Way)<\/strong><\/h3>\n\n\n\n<p>You have three places to add PHP code to your site. Two are wrong.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Option 1 (The Bad Way): <\/strong><strong>functions.php<\/strong> Almost every beginner tutorial tells you to paste your code into your theme&#8217;s functions.php file. <strong>Do not do this.<\/strong> It&#8217;s a terrible habit. This file is theme-dependent. The <em>moment<\/em> you or your client decides to change themes, your site will break. All your custom shortcodes will vanish, and your pages will fill with ugly, un-rendered [bracket_tags].<\/li>\n\n\n\n<li><strong>Option 2 (The Easy Way): A &#8220;Code Snippets&#8221; Plugin<\/strong> For most users, this is a great option. A plugin like &#8220;Code Snippets&#8221; gives you a simple admin menu to add and manage PHP snippets. It&#8217;s like a functions.php file that isn&#8217;t tied to your theme. It&#8217;s safe, easy, and you can toggle snippets on and off.<\/li>\n\n\n\n<li><strong>Option 3 (The Best Way): A Site-Specific Plugin<\/strong> This is the professional method. You create a tiny, one-file plugin that exists for one reason: to hold your site&#8217;s custom code. It&#8217;s theme-independent, faster than a snippets plugin, and it&#8217;s the standard for professional WordPress development. It sounds hard, but it&#8217;s incredibly easy. We&#8217;ll do this in Step 2.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2: Create Your Site-Specific Plugin<\/strong><\/h3>\n\n\n\n<p>This will take you 60 seconds.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On your computer&#8217;s desktop, create a new folder. Name it my-custom-shortcodes.<\/li>\n\n\n\n<li>Inside that folder, create a new file. Name it my-custom-shortcodes.php.<\/li>\n\n\n\n<li>Open this new file in a plain text editor (like Notepad or VS Code).<\/li>\n<\/ol>\n\n\n\n<p>Copy and paste the following code into it:<br>&lt;?php<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* Plugin Name: &nbsp; &nbsp; &nbsp; My Custom Shortcodes<\/p>\n\n\n\n<p>&nbsp;* Plugin URI:&nbsp; &nbsp; &nbsp; &nbsp; [https:\/\/example.com\/](https:\/\/example.com\/)<\/p>\n\n\n\n<p>&nbsp;* Description: &nbsp; &nbsp; &nbsp; Holds all custom shortcodes and functions for my site.<\/p>\n\n\n\n<p>&nbsp;* Version: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.0.0<\/p>\n\n\n\n<p>&nbsp;* Author:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Your Name<\/p>\n\n\n\n<p>&nbsp;* Author URI:&nbsp; &nbsp; &nbsp; &nbsp; [https:\/\/example.com\/](https:\/\/example.com\/)<\/p>\n\n\n\n<p>&nbsp;* License: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPL v2 or later<\/p>\n\n\n\n<p>&nbsp;* License URI: &nbsp; &nbsp; &nbsp; [https:\/\/www.gnu.org\/licenses\/gpl-2.0.html](https:\/\/www.gnu.org\/licenses\/gpl-2.0.html)<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>\/\/ Exit if accessed directly.<\/p>\n\n\n\n<p>if ( ! defined( &#8216;ABSPATH&#8217; ) ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;exit;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ All of our shortcode functions will go below this line<\/p>\n\n\n\n<p>\/\/ &#8230;<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>This &#8220;header comment&#8221; is what WordPress reads to understand that this file is a plugin.<\/li>\n\n\n\n<li>Save the file.<\/li>\n\n\n\n<li>Go back to your desktop. Right-click the my-custom-shortcodes <em>folder<\/em> and compress it into a .zip file.<\/li>\n\n\n\n<li>In your WordPress dashboard, go to <strong>Plugins &gt; Add New &gt; Upload Plugin<\/strong>.<\/li>\n\n\n\n<li>Upload the .zip file you just created and click &#8220;Activate&#8221;.<\/li>\n<\/ol>\n\n\n\n<p>That&#8217;s it. You now have a custom plugin. Any code you add to that .php file will run on your site. You can edit it from <strong>Plugins &gt; Plugin File Editor<\/strong> (select &#8220;My Custom Shortcodes&#8221; from the dropdown).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 3: Write Your Shortcode&#8217;s PHP Function<\/strong><\/h3>\n\n\n\n<p>Now for the fun part. Let&#8217;s create our first shortcode: [current_year].<\/p>\n\n\n\n<p>We need a PHP function that does one thing: get the current year and return it.<\/p>\n\n\n\n<p>In your plugin file (my-custom-shortcodes.php), add the following code below the header:<\/p>\n\n\n\n<p>\/\/ &#8212; [current_year] Shortcode &#8212;<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* 1. The Shortcode Function<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* This is the function that will run when the [current_year] shortcode is used.<\/p>\n\n\n\n<p>&nbsp;* It returns the current four-digit year as a string.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_current_year_function() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Get the current year in &#8216;YYYY&#8217; format<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$year = date(&#8216;Y&#8217;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ IMPORTANT: You must return the value. Do not echo it.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $year;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>That&#8217;s our logic. It&#8217;s a simple function that gets the year and returns it. Notice the detailed comments. Always comment on your code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 4: Register Your Shortcode with WordPress<\/strong><\/h3>\n\n\n\n<p>Our function exists, but WordPress doesn&#8217;t know about it. We need to &#8220;register&#8221; it and tie it to a shortcode tag. We do this with the add_shortcode() function.<\/p>\n\n\n\n<p>But we can&#8217;t just call this function anywhere. We need to hook it into WordPress&#8217;s initialization process to ensure it loads at the right time. We use add_action( &#8216;init&#8217;, &#8230; ) for this.<\/p>\n\n\n\n<p>Add this code below the function you just wrote:<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* 2. The Shortcode Registration<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* This function registers all of our shortcodes.<\/p>\n\n\n\n<p>&nbsp;* We hook it into the &#8216;init&#8217; action.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_register_shortcodes() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ add_shortcode( &#8216;tag&#8217;, &#8216;function_name&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;current_year&#8217;, &#8216;my_current_year_function&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ You can register more shortcodes here<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ add_shortcode( &#8216;business_phone&#8217;, &#8216;my_phone_function&#8217; );<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ 3. Hook the registration function into WordPress<\/p>\n\n\n\n<p>add_action( &#8216;init&#8217;, &#8216;my_register_shortcodes&#8217; );<\/p>\n\n\n\n<p>Let&#8217;s review the full code for your my-custom-shortcodes.php file so far:<\/p>\n\n\n\n<p>&lt;?php<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* Plugin Name: &nbsp; &nbsp; &nbsp; My Custom Shortcodes<\/p>\n\n\n\n<p>&nbsp;* &#8230; (rest of header) &#8230;<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>\/\/ Exit if accessed directly.<\/p>\n\n\n\n<p>if ( ! defined( &#8216;ABSPATH&#8217; ) ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;exit;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ &#8212; [current_year] Shortcode &#8212;<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* 1. The Shortcode Function<\/p>\n\n\n\n<p>&nbsp;* This function returns the current four-digit year.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_current_year_function() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$year = date(&#8216;Y&#8217;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $year;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* 2. The Shortcode Registration Function<\/p>\n\n\n\n<p>&nbsp;* This function registers all of our shortcodes.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_register_shortcodes() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [current_year]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;current_year&#8217;, &#8216;my_current_year_function&#8217; );<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ 3. Hook into WordPress<\/p>\n\n\n\n<p>add_action( &#8216;init&#8217;, &#8216;my_register_shortcodes&#8217; );<\/p>\n\n\n\n<p>Save your plugin file. The shortcode is now live.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 5: Test Your Shortcode<\/strong><\/h3>\n\n\n\n<p>This is the easiest step.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Go to <strong>Pages &gt; Add New<\/strong>.<\/li>\n\n\n\n<li>In the content editor, type: This website is copyright 2010 &#8211; [current_year]. All rights reserved.<\/li>\n\n\n\n<li>Click &#8220;Preview&#8221;.<\/li>\n<\/ol>\n\n\n\n<p>You will see: &#8220;This website is copyright 2010 &#8211; 2025. All rights reserved.&#8221;<\/p>\n\n\n\n<p>It works! You&#8217;ve successfully created a dynamic, self-updating copyright date.<\/p>\n\n\n\n<p><strong>How to use it in different editors:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Gutenberg (Block Editor):<\/strong> You can type it directly, or you can add the &#8220;Shortcode&#8221; block and paste [current_year] into it.<\/li>\n\n\n\n<li><strong>Classic Editor:<\/strong> Type it directly into the text editor.<\/li>\n\n\n\n<li><a href=\"https:\/\/elementor.com\"><strong>Elementor<\/strong><\/a><strong>:<\/strong> Drag the &#8220;Shortcode&#8221; widget onto your page and paste [current_year] into the settings box. You can also use the &#8220;Text Editor&#8221; widget and type it in there.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 6: Level Up: Adding Attributes (atts)<\/strong><\/h3>\n\n\n\n<p>Our [current_year] shortcode is simple. But what if we want to make it flexible? Let&#8217;s create a new shortcode that greets a user by name.<\/p>\n\n\n\n<p>We want it to work like this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[welcome] -&gt; &#8220;Hello, Valued Visitor! Welcome.&#8221;<\/li>\n\n\n\n<li>[welcome user=&#8221;Itamar&#8221;] -&gt; &#8220;Hello, Itamar! Welcome.&#8221;<\/li>\n<\/ul>\n\n\n\n<p>The user=&#8221;Itamar&#8221; part is an <strong>attribute<\/strong>. WordPress passes all attributes to our function as an array, which is conventionally named $atts.<\/p>\n\n\n\n<p>We use a core function called shortcode_atts() to merge the user&#8217;s provided attributes with a set of defaults. This is a crucial best practice.<\/p>\n\n\n\n<p>Let&#8217;s add this new shortcode to our plugin:<\/p>\n\n\n\n<p>\/\/ &#8212; [welcome] Shortcode &#8212;<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* 1. The [welcome] Shortcode Function<\/p>\n\n\n\n<p>&nbsp;* Greets a user with flexible attributes.<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* @param array $atts User-provided attributes.<\/p>\n\n\n\n<p>&nbsp;* @return string The welcome message HTML.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_welcome_message_function( $atts ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 2. Set default attributes<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ This merges user-provided atts with defaults.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$atts = shortcode_atts( array(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;user&#8217; =&gt; &#8216;Valued Visitor&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;show_icon&#8217; =&gt; &#8216;false&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;), $atts, &#8216;welcome&#8217; ); \/\/ 3rd param is the shortcode tag, good practice.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 3. Sanitize and prepare variables<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ ALWAYS sanitize user input for security.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$user_name = esc_html( $atts[&#8216;user&#8217;] );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$icon = &#8221;; \/\/ Start with an empty string<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;if ( $atts[&#8216;show_icon&#8217;] === &#8216;true&#8217; ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/ You could add an &lt;svg&gt; or &lt;img&gt; tag here<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$icon = &#8216;&lt;span class=&#8221;welcome-icon&#8221;&gt;\ud83d\udc4b&lt;\/span&gt; &#8216;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 4. Build the HTML output<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message = &#8216;&lt;p class=&#8221;welcome-message&#8221;&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= $icon;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= &#8216;Hello, &#8216; . $user_name . &#8216;! Welcome to our site.&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= &#8216;&lt;\/p&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 5. Return the final HTML string<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $message;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ Now, add it to our registration function:<\/p>\n\n\n\n<p>function my_register_shortcodes() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [current_year]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;current_year&#8217;, &#8216;my_current_year_function&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [welcome]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;welcome&#8217;, &#8216;my_welcome_message_function&#8217; );<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ The add_action(&#8216;init&#8217;, &#8230;) is already at the bottom<\/p>\n\n\n\n<p><strong>What we did:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The function now accepts a parameter: $atts.<\/li>\n\n\n\n<li>We used shortcode_atts() to define our defaults: user is &#8216;Valued Visitor&#8217;.<\/li>\n\n\n\n<li>We used esc_html() to <strong>sanitize<\/strong> the input. This is critical for security. It strips out any malicious HTML or scripts a user might try to pass into the attribute.<\/li>\n\n\n\n<li>We built an HTML string ($message) and returned it.<\/li>\n<\/ol>\n\n\n\n<p>Now you can test it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[welcome] -&gt; &lt;p class=&#8221;welcome-message&#8221;&gt;Hello, Valued Visitor! Welcome to our site.&lt;\/p&gt;<\/li>\n\n\n\n<li>[welcome user=&#8221;Itamar&#8221;] -&gt; &lt;p class=&#8221;welcome-message&#8221;&gt;Hello, Itamar! Welcome to our site.&lt;\/p&gt;<\/li>\n\n\n\n<li>[welcome user=&#8221;Jane&#8221; show_icon=&#8221;true&#8221;] -&gt; &lt;p class=&#8221;welcome-message&#8221;&gt;&lt;span class=&#8221;welcome-icon&#8221;&gt;\ud83d\udc4b&lt;\/span&gt; Hello, Jane! Welcome to our site.&lt;\/p&gt;<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 7: Master Class: Handling Enclosing Shortcodes<\/strong><\/h3>\n\n\n\n<p>Finally, let&#8217;s create an enclosing shortcode, like [box_alert]&#8230;[\/box_alert].<\/p>\n\n\n\n<p>This type of function accepts a <em>second<\/em> parameter, conventionally named $content. This variable holds everything that&#8217;s between the opening and closing tags.<\/p>\n\n\n\n<p>Let&#8217;s make a<\/p>\n\n\n<p>[box_alert]<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> shortcode that can be a &#8220;warning&#8221; or &#8220;info&#8221; box. Usage: <\/span><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[box_alert type=&#8221;warning&#8221;]This is a dangerous action.[\/box_alert]<\/p>\n\n\n\n<p>Here&#8217;s the code to add to your plugin:<\/p>\n\n\n\n<p>\/\/ &#8212;<\/p>\n\n\n<p>[box_alert] Shortcode &#8212;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\/**<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;* 1. The [box_alert] Shortcode Function<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;* Wraps content in a styled alert box.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;*<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;* @param array $atts User-provided attributes.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;* @param string $content The content between the opening and closing tags.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;* @return string The alert box HTML.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;*\/<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">function my_box_alert_function( $atts, $content = null ) {<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 2. Set default attributes<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$atts = shortcode_atts( array(<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;type&#8217; =&gt; &#8216;info&#8217;, \/\/ Default type is &#8216;info&#8217;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;), $atts, &#8216;box_alert&#8217; );<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 3. Sanitize attributes<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$safe_type = esc_attr( $atts[&#8216;type&#8217;] ); \/\/ &#8216;info&#8217; or &#8216;warning&#8217;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 4. Process the inner content<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ This is a crucial step!<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ wpautop: Adds &lt;p&gt; tags, just like the normal WordPress editor.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ do_shortcode: Allows other shortcodes to work INSIDE this one.<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$processed_content = do_shortcode( wpautop( $content ) );<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 5. Build the HTML output<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$html = &#8216;&lt;div class=&#8221;alert-box alert-&#8216; . $safe_type . &#8216;&#8221;&gt;&#8217;;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$html .= $processed_content; \/\/ Add the processed content<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;$html .= &#8216;&lt;\/div&gt;&#8217;;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 6. Return the final HTML string<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;return $html;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">}<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\/\/ And add to registration:<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">function my_register_shortcodes() {<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [current_year]<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;current_year&#8217;, &#8216;my_current_year_function&#8217; );<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [welcome]<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;welcome&#8217;, &#8216;my_welcome_message_function&#8217; );<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [box_alert]<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;box_alert&#8217;, &#8216;my_box_alert_function&#8217; );<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">}<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\/\/ The add_action(&#8216;init&#8217;, &#8230;) is already at the bottom<\/span><\/p>\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:12pt\"><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">Key new concepts:<\/span><\/p>\n<ul style=\"margin-top:0;margin-bottom:0;padding-inline-start:48px\">\n<li dir=\"ltr\" style=\"list-style-type:disc;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:12pt;margin-bottom:0pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">$content = null<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">: The function now accepts a second parameter.<\/span><\/p>\n<\/li>\n<li dir=\"ltr\" style=\"list-style-type:disc;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">$processed_content = do_shortcode( wpautop( $content ) );<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">: This line is vital.<\/span><\/p>\n<\/li>\n<ul style=\"margin-top:0;margin-bottom:0;padding-inline-start:48px\">\n<li dir=\"ltr\" style=\"list-style-type:circle;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:0pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">wpautop( $content )<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> takes the plain text from the editor and adds paragraph tags, just like WordPress normally does.<\/span><\/p>\n<\/li>\n<li dir=\"ltr\" style=\"list-style-type:circle;font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">\n<p dir=\"ltr\" style=\"line-height:1.38;margin-top:0pt;margin-bottom:12pt\" role=\"presentation\"><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">do_shortcode( &#8230; )<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> scans the <\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline\">inner<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> content for <\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline\">other<\/span><span style=\"font-size:11pt;font-family:'Noto Sans Hebrew',sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\"> shortcodes. This allows users to &#8220;nest&#8221; shortcodes, like: <\/span><span style=\"font-size:11pt;font-family:'Roboto Mono',monospace;color:#188038;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline\">[box_alert type=&#8221;warning&#8221;][welcome user=&#8221;Admin&#8221;][\/box_alert]<\/p>\n\n\n\n<p>.<\/p>\n\n\n\n<p>To make this look good, you&#8217;d need to add a bit of <a class=\"wpil_keyword_link\" href=\"https:\/\/elementor.com\/blog\/what-is-css\/\" title=\"What Is CSS? How to Use it in Web Design (2025)\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"21110\">CSS<\/a> to your site (e.g., in <strong>Appearance &gt; Customize &gt; Additional CSS<\/strong>):<\/p>\n\n\n\n<p>.alert-box {<\/p>\n\n\n\n<p>&nbsp;&nbsp;padding: 15px;<\/p>\n\n\n\n<p>&nbsp;&nbsp;margin-bottom: 20px;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border: 1px solid transparent;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-radius: 4px;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.alert-info {<\/p>\n\n\n\n<p>&nbsp;&nbsp;color: #31708f;<\/p>\n\n\n\n<p>&nbsp;&nbsp;background-color: #d9edf7;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-color: #bce8f1;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.alert-warning {<\/p>\n\n\n\n<p>&nbsp;&nbsp;color: #8a6d3b;<\/p>\n\n\n\n<p>&nbsp;&nbsp;background-color: #fcf8e3;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-color: #faebcc;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>A Complete, Copy-Paste Site-Specific Plugin Template<\/strong><\/h2>\n\n\n\n<p>Here is the complete, final code for your my-custom-shortcodes.php plugin file. It contains all three of our examples, fully commented and ready to go.<\/p>\n\n\n\n<p>&lt;?php<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* Plugin Name: &nbsp; &nbsp; &nbsp; My Custom Shortcodes<\/p>\n\n\n\n<p>&nbsp;* Plugin URI:&nbsp; &nbsp; &nbsp; &nbsp; [https:\/\/example.com\/](https:\/\/example.com\/)<\/p>\n\n\n\n<p>&nbsp;* Description: &nbsp; &nbsp; &nbsp; Holds all custom shortcodes and functions for my site.<\/p>\n\n\n\n<p>&nbsp;* Version: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1.0.0<\/p>\n\n\n\n<p>&nbsp;* Author:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Your Name<\/p>\n\n\n\n<p>&nbsp;* Author URI:&nbsp; &nbsp; &nbsp; &nbsp; [https:\/\/example.com\/](https:\/\/example.com\/)<\/p>\n\n\n\n<p>&nbsp;* License: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPL v2 or later<\/p>\n\n\n\n<p>&nbsp;* License URI: &nbsp; &nbsp; &nbsp; [https:\/\/www.gnu.org\/licenses\/gpl-2.0.html](https:\/\/www.gnu.org\/licenses\/gpl-2.0.html)<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>\/\/ Exit if accessed directly.<\/p>\n\n\n\n<p>if ( ! defined( &#8216;ABSPATH&#8217; ) ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;exit;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* Master Registration Function<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* All shortcodes are registered here.<\/p>\n\n\n\n<p>&nbsp;* This is hooked into &#8216;init&#8217;.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_register_all_shortcodes() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [current_year]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;current_year&#8217;, &#8216;my_current_year_function&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [welcome user=&#8221;Guest&#8221; show_icon=&#8221;false&#8221;]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;welcome&#8217;, &#8216;my_welcome_message_function&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ [box_alert type=&#8221;info&#8221;]&#8230;[\/box_alert]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;add_shortcode( &#8216;box_alert&#8217;, &#8216;my_box_alert_function&#8217; );<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>add_action( &#8216;init&#8217;, &#8216;my_register_all_shortcodes&#8217; );<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* Shortcode Function: [current_year]<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* A simple self-closing shortcode.<\/p>\n\n\n\n<p>&nbsp;* Returns the current 4-digit year.<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* @return string The current year.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_current_year_function() {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$year = date(&#8216;Y&#8217;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $year;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* Shortcode Function: [welcome]<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* A self-closing shortcode with attributes.<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* @param array $atts User-provided attributes (e.g., user=&#8221;Itamar&#8221;).<\/p>\n\n\n\n<p>&nbsp;* @return string The welcome message HTML.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_welcome_message_function( $atts ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 1. Merge user attributes with defaults<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$atts = shortcode_atts( array(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;user&#8217;&nbsp; &nbsp; &nbsp; =&gt; &#8216;Valued Visitor&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;show_icon&#8217; =&gt; &#8216;false&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;), $atts, &#8216;welcome&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 2. Sanitize and prepare variables<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$user_name = esc_html( $atts[&#8216;user&#8217;] );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$icon = &#8221;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;if ( $atts[&#8216;show_icon&#8217;] === &#8216;true&#8217; ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$icon = &#8216;&lt;span class=&#8221;welcome-icon&#8221;&gt;\ud83d\udc4b&lt;\/span&gt; &#8216;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;}<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 3. Build the HTML output<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message = &#8216;&lt;p class=&#8221;welcome-message&#8221;&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= $icon;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= &#8216;Hello, &#8216; . $user_name . &#8216;! Welcome to our site.&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$message .= &#8216;&lt;\/p&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 4. Return the final HTML string<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $message;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/**<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* Shortcode Function: [box_alert]<\/p>\n\n\n\n<p>&nbsp;* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n\n\n\n<p>&nbsp;* An enclosing shortcode with attributes.<\/p>\n\n\n\n<p>&nbsp;*<\/p>\n\n\n\n<p>&nbsp;* @param array $atts User-provided attributes (e.g., type=&#8221;warning&#8221;).<\/p>\n\n\n\n<p>&nbsp;* @param string $content The content between the tags.<\/p>\n\n\n\n<p>&nbsp;* @return string The alert box HTML.<\/p>\n\n\n\n<p>&nbsp;*\/<\/p>\n\n\n\n<p>function my_box_alert_function( $atts, $content = null ) {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 1. Merge user attributes with defaults<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$atts = shortcode_atts( array(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8216;type&#8217; =&gt; &#8216;info&#8217;, \/\/ &#8216;info&#8217; or &#8216;warning&#8217;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;), $atts, &#8216;box_alert&#8217; );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 2. Sanitize attributes<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$safe_type = esc_attr( $atts[&#8216;type&#8217;] );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 3. Process the inner content<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ This allows nested shortcodes and adds &lt;p&gt; tags.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$processed_content = do_shortcode( wpautop( $content ) );<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 4. Build the HTML output<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$html = &#8216;&lt;div class=&#8221;alert-box alert-&#8216; . $safe_type . &#8216;&#8221;&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$html .= $processed_content; \/\/ Add the processed content<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;$html .= &#8216;&lt;\/div&gt;&#8217;;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ 5. Return the final HTML string<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;return $html;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\/\/ &#8212; End of Plugin &#8212;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Debugging: What to Do When Your Shortcode Doesn&#8217;t Work<\/strong><\/h2>\n\n\n\n<p>It&#8217;s going to happen. You&#8217;ll save your file, refresh the page, and&#8230; it&#8217;s broken. Here&#8217;s how to fix it.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Problem: It&#8217;s Not Working at All (It&#8217;s Just Showing the <\/strong><strong>[bracket_text]<\/strong><strong>)<\/strong><\/h4>\n\n\n\n<p>This means WordPress doesn&#8217;t recognize your shortcode.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Check 1:<\/strong> Is your site-specific plugin <strong>activated<\/strong> in the Plugins menu? This is the most common issue.<\/li>\n\n\n\n<li><strong>Check 2:<\/strong> Did you spell the tag correctly in add_shortcode( &#8216;my_tag&#8217;, &#8230; )?<\/li>\n\n\n\n<li><strong>Check 3:<\/strong> Does the tag in your post <em>exactly<\/em> match the tag you registered? [my_tag] and [mytag] are different.<\/li>\n\n\n\n<li><strong>Check 4:<\/strong> Is your add_shortcode() call hooked into init?<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Problem: It&#8217;s Printing at the Top of the Page (Out of Order)<\/strong><\/h4>\n\n\n\n<p><strong>You are <\/strong><strong>echo<\/strong><strong>&#8216;ing, not <\/strong><strong>return<\/strong><strong>&#8216;ing.<\/strong> This is the number one mistake. Your function <em>must<\/em> collect all of its output into a single string variable (e.g., $html) and then, at the very end, have return $html;. If you use echo, PHP prints it <em>immediately<\/em>, before the rest of the page HTML is ready.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Problem: It&#8217;s Breaking the Page (White Screen of Death)<\/strong><\/h4>\n\n\n\n<p>You have a <strong>fatal PHP error<\/strong>. This is usually a simple syntax mistake.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Did you forget a semicolon ; at the end of a line?<\/li>\n\n\n\n<li>Did you forget a closing bracket } or parenthesis )?<\/li>\n\n\n\n<li>Did you misspell a function name? You&#8217;ll need to enable WP_DEBUG in your wp-config.php file to see the exact error message, or check your server&#8217;s error logs.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Problem: My Enclosing Shortcode Isn&#8217;t Showing Its Content<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Did you forget to add $content = null as the second parameter to your function?<\/li>\n\n\n\n<li>Did you forget to actually <em>use<\/em> the $content variable in your return string? (e.g., $html .= $processed_content;).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The Modern WordPress: Shortcodes vs. Blocks vs. Widgets<\/strong><\/h2>\n\n\n\n<p>Understanding shortcodes is key, but it&#8217;s also crucial to know where they fit in today&#8217;s WordPress ecosystem.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Shortcodes (The Past):<\/strong> These are legacy, but still vital. They are perfect for <em>macros<\/em> and <em>dynamic data<\/em> (like [current_year]). They are terrible for layout and design.<\/li>\n\n\n\n<li><strong>Gutenberg Blocks (The Present):<\/strong> A &#8220;Block&#8221; is the modern, native WordPress version of a shortcode. It&#8217;s a &#8220;shortcode on steroids.&#8221; It has a rich visual interface right in the editor, uses JavaScript (React), and provides a much better user experience. However, building a custom block is 100x more complex than building a shortcode and requires a totally different skillset (JavaScript, Node.js, etc.).<\/li>\n\n\n\n<li><a href=\"https:\/\/elementor.com\/pro\"><strong>Elementor Pro<\/strong><\/a><strong> Widgets (The Professional&#8217;s Present):<\/strong> For professionals, the Elementor workflow is the most efficient. Instead of writing PHP for a shortcode, you can often achieve the same result with <strong>Dynamic Tags<\/strong>. For example, to make a &#8220;Hello, Itamar!&#8221; welcome message, you don&#8217;t need a shortcode. You just add a Heading widget, click &#8220;Dynamic Tags,&#8221; and select &#8220;User Info&#8221; &gt; &#8220;User First Name.&#8221; This is a &#8220;no-code&#8221; way to accomplish the same dynamic-content goal.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>My Expert Recommendation<\/strong><\/h3>\n\n\n\n<p>As a web creation expert, my advice is to follow a clear hierarchy. As I, <strong>Itamar Haim<\/strong>, often tell my clients: &#8220;First, use your visual builder&#8217;s (like<a href=\"https:\/\/elementor.com\"> Elementor<\/a>) built-in widgets and dynamic features. They are the fastest, most stable solution. Second, for specialized features, find a dedicated, high-quality plugin from the repository. Only as a last resort, for truly custom, dynamic data that a plugin can&#8217;t handle, should you write your own shortcode.&#8221;<\/p>\n\n\n\n<p>And when you do need to use a shortcode (from a plugin or one you built), the<a href=\"https:\/\/elementor.com\"> Elementor<\/a> &#8220;Shortcode&#8221; widget is the perfect way to place it. You get the full visual, drag-and-drop power of Elementor to control the layout, and you can place your dynamic shortcode &#8220;macro&#8221; right where it needs to go. It&#8217;s the best of both worlds.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion: The Enduring Value of the Shortcode<\/strong><\/h2>\n\n\n\n<p>Shortcodes are a fundamental part of WordPress&#8217;s DNA. While modern visual builders have (rightfully) taken over their role for layout and design, the Shortcode API remains a simple, powerful, and accessible tool for any developer.<\/p>\n\n\n\n<p>You now have the complete, professional workflow. You know <em>why<\/em> you should (and shouldn&#8217;t) build a shortcode. You know <em>how<\/em> to build one safely in a site-specific plugin. And you understand how to create all three types: simple, attribute-based, and enclosing. This is a powerful skill that will serve you well in your WordPress journey.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Frequently Asked Questions (FAQ)<\/strong><\/h2>\n\n\n\n<p><strong>1. What&#8217;s the difference between a shortcode and a widget?<\/strong> A &#8220;widget&#8221; traditionally refers to a block of content you add to a sidebar or footer via the <strong>Appearance &gt; Widgets<\/strong> admin screen. A &#8220;shortcode&#8221; is a tag you insert <em>directly into your page or post content<\/em>. The lines are blurred now, as builders like<a href=\"https:\/\/elementor.com\"> Elementor<\/a> also call their drag-and-drop items &#8220;widgets.&#8221;<\/p>\n\n\n\n<p><strong>2. Can I use shortcodes in Elementor?<\/strong> Yes, absolutely.<a href=\"https:\/\/elementor.com\"> Elementor<\/a> has a dedicated &#8220;Shortcode&#8221; widget. You can drag this widget anywhere on your page and paste any shortcode (from a plugin or your custom one) into its settings. You can also type shortcodes into the &#8220;Text Editor&#8221; or &#8220;Heading&#8221; widgets.<\/p>\n\n\n\n<p><strong>3. Can I use shortcodes in my theme&#8217;s header or footer?<\/strong> Yes, but you can&#8217;t type the [my_tag] directly into the theme&#8217;s .php files. In your PHP <a class=\"wpil_keyword_link\" href=\"https:\/\/elementor.com\/library\/all-categories\/\" title=\"Alle categorie\u00ebn\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"21109\">template<\/a> files (like header.php), you must use the do_shortcode() function: &lt;?php echo do_shortcode( [my_shortcode]&#8217; ); ?&gt; If you use<a href=\"https:\/\/elementor.com\/pro\"> Elementor Pro<\/a>, you can build your header and footer visually with the Theme Builder and just drop the Shortcode widget in.<\/p>\n\n\n\n<p><strong>4. Is it safe to create my own shortcodes?<\/strong> It is safe if you follow two rules: 1. return your content, don&#8217;t echo it. 2. <strong>Always<\/strong> sanitize user-provided data from $atts using functions like esc_html() (for text) and esc_attr() (for HTML attributes) to prevent security issues.<\/p>\n\n\n\n<p><strong>5. Why is my shortcode showing as plain text?<\/strong> This means it&#8217;s not being registered correctly. Check that your plugin is active, you spelled the shortcode tag correctly in your post, and that your add_shortcode() function is spelled correctly and hooked into init.<\/p>\n\n\n\n<p><strong>6. Can I nest shortcodes?<\/strong> Yes, but only if the <em>parent<\/em> shortcode is built to support it. As we saw in Step 7, the parent function <strong>must<\/strong> run its $content through the do_shortcode() function (e.g., return do_shortcode( $content );).<\/p>\n\n\n\n<p><strong>7. What is the best way to add CSS for my shortcode?<\/strong> You have a few good options.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>For simple sites:<\/strong> Add it to <strong>Appearance &gt; Customize &gt; Additional CSS<\/strong>. This is the easiest.<\/li>\n\n\n\n<li><strong>For themes:<\/strong> Add it to your child theme&#8217;s style.css file.<\/li>\n\n\n\n<li><strong>For plugins (The &#8220;Pro&#8221; way):<\/strong> Your site-specific plugin can have its own stylesheet (my-shortcodes.css) and &#8220;enqueue&#8221; it, so the CSS only loads on pages where it&#8217;s needed. This is more advanced but better for performance.<\/li>\n<\/ul>\n\n\n\n<p><strong>8. What is <\/strong><strong>shortcode_atts()<\/strong><strong>?<\/strong> It&#8217;s a helper function from WordPress. It safely merges the user-provided attributes (the $atts array) with your array of default values. It&#8217;s the proper way to set default values for your attributes.<\/p>\n\n\n\n<p><strong>9. Should I put my shortcode in <\/strong><strong>functions.php<\/strong><strong> or a plugin?<\/strong> A plugin. Always a plugin. Use a &#8220;Code Snippets&#8221; plugin for an easy UI, or create your own &#8220;site-specific plugin&#8221; (as we did) for the most professional and stable solution. Never use your theme&#8217;s functions.php file for critical, theme-independent functionality.<\/p>\n\n\n\n<p><strong>10. Are shortcodes outdated?<\/strong> No. Their <em>role<\/em> has changed. They are no longer for page layout. They are for inserting <strong>dynamic data<\/strong> or <strong>application-like features<\/strong> (from plugins) into your content. The feature itself is alive and well, and a core part of the WordPress ecosystem. You can even get a<a href=\"https:\/\/elementor.com\/free-download\"> free download of WordPress<\/a> to start practicing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WordPress shortcodes are one of the platform&#8217;s most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like [my_gallery]. This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.<\/p>\n","protected":false},"author":2024234,"featured_media":141816,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[512],"tags":[],"marketing_persona":[],"marketing_intent":[],"class_list":["post-143486","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-resources"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Create a WordPress Shortcode in 7 Steps (A Developer&#039;s Guide)<\/title>\n<meta name=\"description\" content=\"WordPress shortcodes are one of the platform&#039;s most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Create a WordPress Shortcode in 7 Steps (A Developer&#039;s Guide)\" \/>\n<meta property=\"og:description\" content=\"WordPress shortcodes are one of the platform&#039;s most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/elemntor\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-20T02:28:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-20T12:42:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Itamar Haim\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@elemntor\" \/>\n<meta name=\"twitter:site\" content=\"@elemntor\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Itamar Haim\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\"},\"author\":{\"name\":\"Itamar Haim\",\"@id\":\"https:\/\/elementor.com\/blog\/#\/schema\/person\/5d24783541c454816685653dfed73377\"},\"headline\":\"How to Create a WordPress Shortcode in 7 Steps (A Developer&#8217;s Guide)\",\"datePublished\":\"2025-11-20T02:28:37+00:00\",\"dateModified\":\"2025-11-20T12:42:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\"},\"wordCount\":5424,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/elementor.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg\",\"articleSection\":[\"Resources\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\",\"url\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\",\"name\":\"How to Create a WordPress Shortcode in 7 Steps (A Developer's Guide)\",\"isPartOf\":{\"@id\":\"https:\/\/elementor.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg\",\"datePublished\":\"2025-11-20T02:28:37+00:00\",\"dateModified\":\"2025-11-20T12:42:44+00:00\",\"description\":\"WordPress shortcodes are one of the platform's most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.\",\"breadcrumb\":{\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage\",\"url\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg\",\"contentUrl\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg\",\"width\":1200,\"height\":628},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Blog\",\"item\":\"https:\/\/elementor.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Resources\",\"item\":\"https:\/\/elementor.com\/blog\/category\/resources\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Create a WordPress Shortcode in 7 Steps (A Developer&#8217;s Guide)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/elementor.com\/blog\/#website\",\"url\":\"https:\/\/elementor.com\/blog\/\",\"name\":\"Elementor\",\"description\":\"Website Builder for WordPress\",\"publisher\":{\"@id\":\"https:\/\/elementor.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/elementor.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/elementor.com\/blog\/#organization\",\"name\":\"Elementor\",\"url\":\"https:\/\/elementor.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/elementor.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/06\/images.png\",\"contentUrl\":\"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/06\/images.png\",\"width\":225,\"height\":225,\"caption\":\"Elementor\"},\"image\":{\"@id\":\"https:\/\/elementor.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/elemntor\/\",\"https:\/\/x.com\/elemntor\",\"https:\/\/www.instagram.com\/elementor\/\",\"https:\/\/www.youtube.com\/channel\/UCt9kG_EDX8zwGSC1-ycJJVA?sub_confirmation=1\",\"https:\/\/en.wikipedia.org\/wiki\/Elementor\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/elementor.com\/blog\/#\/schema\/person\/5d24783541c454816685653dfed73377\",\"name\":\"Itamar Haim\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/elementor.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/830174068538633c83fd732c583ea1fe9d4c813314075640bf78d5a621982848?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/830174068538633c83fd732c583ea1fe9d4c813314075640bf78d5a621982848?s=96&d=mm&r=g\",\"caption\":\"Itamar Haim\"},\"description\":\"Itamar Haim, SEO Team Lead at Elementor, is a digital strategist merging SEO &amp; AEO \/ GEO, and web development. He leverages deep WordPress expertise to drive global organic growth, empowering businesses to navigate the AI era and ensuring top-tier search performance for millions of websites.\",\"sameAs\":[\"https:\/\/elementor.com\/blog\/author\/itamarha\/\",\"https:\/\/www.linkedin.com\/in\/itamar-haim-8149b85b\/\"],\"url\":\"https:\/\/elementor.com\/blog\/author\/itamarha\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Create a WordPress Shortcode in 7 Steps (A Developer's Guide)","description":"WordPress shortcodes are one of the platform's most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/","og_locale":"en_US","og_type":"article","og_title":"How to Create a WordPress Shortcode in 7 Steps (A Developer's Guide)","og_description":"WordPress shortcodes are one of the platform's most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.","og_url":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/","og_site_name":"Blog","article_publisher":"https:\/\/www.facebook.com\/elemntor\/","article_published_time":"2025-11-20T02:28:37+00:00","article_modified_time":"2025-11-20T12:42:44+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg","type":"image\/jpeg"}],"author":"Itamar Haim","twitter_card":"summary_large_image","twitter_creator":"@elemntor","twitter_site":"@elemntor","twitter_misc":{"Written by":"Itamar Haim","Est. reading time":"20 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#article","isPartOf":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/"},"author":{"name":"Itamar Haim","@id":"https:\/\/elementor.com\/blog\/#\/schema\/person\/5d24783541c454816685653dfed73377"},"headline":"How to Create a WordPress Shortcode in 7 Steps (A Developer&#8217;s Guide)","datePublished":"2025-11-20T02:28:37+00:00","dateModified":"2025-11-20T12:42:44+00:00","mainEntityOfPage":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/"},"wordCount":5424,"commentCount":0,"publisher":{"@id":"https:\/\/elementor.com\/blog\/#organization"},"image":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage"},"thumbnailUrl":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg","articleSection":["Resources"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/","url":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/","name":"How to Create a WordPress Shortcode in 7 Steps (A Developer's Guide)","isPartOf":{"@id":"https:\/\/elementor.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage"},"image":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage"},"thumbnailUrl":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg","datePublished":"2025-11-20T02:28:37+00:00","dateModified":"2025-11-20T12:42:44+00:00","description":"WordPress shortcodes are one of the platform's most powerful and enduring features. They are the small keys that unlock massive functionality, allowing you to embed complex elements\u2014like contact forms, image galleries, or custom data\u2014into a post or page by typing a simple, memorable tag like . This single feature is a cornerstone of what makes the WordPress content editing experience so flexible.","breadcrumb":{"@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#primaryimage","url":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg","contentUrl":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/10\/imgi_19_How-Much-to-Charge-for-a-Website-01.jpeg","width":1200,"height":628},{"@type":"BreadcrumbList","@id":"https:\/\/elementor.com\/blog\/how-to-create-a-wordpress-shortcode\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog","item":"https:\/\/elementor.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Resources","item":"https:\/\/elementor.com\/blog\/category\/resources\/"},{"@type":"ListItem","position":3,"name":"How to Create a WordPress Shortcode in 7 Steps (A Developer&#8217;s Guide)"}]},{"@type":"WebSite","@id":"https:\/\/elementor.com\/blog\/#website","url":"https:\/\/elementor.com\/blog\/","name":"Elementor","description":"Website Builder for WordPress","publisher":{"@id":"https:\/\/elementor.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/elementor.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/elementor.com\/blog\/#organization","name":"Elementor","url":"https:\/\/elementor.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/elementor.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/06\/images.png","contentUrl":"https:\/\/elementor.com\/blog\/wp-content\/uploads\/2025\/06\/images.png","width":225,"height":225,"caption":"Elementor"},"image":{"@id":"https:\/\/elementor.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/elemntor\/","https:\/\/x.com\/elemntor","https:\/\/www.instagram.com\/elementor\/","https:\/\/www.youtube.com\/channel\/UCt9kG_EDX8zwGSC1-ycJJVA?sub_confirmation=1","https:\/\/en.wikipedia.org\/wiki\/Elementor"]},{"@type":"Person","@id":"https:\/\/elementor.com\/blog\/#\/schema\/person\/5d24783541c454816685653dfed73377","name":"Itamar Haim","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/elementor.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/830174068538633c83fd732c583ea1fe9d4c813314075640bf78d5a621982848?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/830174068538633c83fd732c583ea1fe9d4c813314075640bf78d5a621982848?s=96&d=mm&r=g","caption":"Itamar Haim"},"description":"Itamar Haim, SEO Team Lead at Elementor, is a digital strategist merging SEO &amp; AEO \/ GEO, and web development. He leverages deep WordPress expertise to drive global organic growth, empowering businesses to navigate the AI era and ensuring top-tier search performance for millions of websites.","sameAs":["https:\/\/elementor.com\/blog\/author\/itamarha\/","https:\/\/www.linkedin.com\/in\/itamar-haim-8149b85b\/"],"url":"https:\/\/elementor.com\/blog\/author\/itamarha\/"}]}},"_links":{"self":[{"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/posts\/143486","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/users\/2024234"}],"replies":[{"embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/comments?post=143486"}],"version-history":[{"count":3,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/posts\/143486\/revisions"}],"predecessor-version":[{"id":144207,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/posts\/143486\/revisions\/144207"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/media\/141816"}],"wp:attachment":[{"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/media?parent=143486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/categories?post=143486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/tags?post=143486"},{"taxonomy":"marketing_persona","embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/marketing_persona?post=143486"},{"taxonomy":"marketing_intent","embeddable":true,"href":"https:\/\/elementor.com\/blog\/wp-json\/wp\/v2\/marketing_intent?post=143486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}