avatarTravis Weston

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

4201

Abstract

In this case it isn’t true polymorphism, since there are some methods that must be added to make it work, but shoot, I liked the name.</p><p id="4eb2">Sue me.</p><h1 id="cfa3">Back to the refactoring!</h1><p id="c2b5">The first thing we need to do is clean this code up. First we convert functions to a class, and give that class a namespace of HelloDolly.</p><p id="670a">Next, there’s really no need to convert a multi-line string to an array, just to get a random line. So we convert that chunk of text to an array, remove the conversion line, and update the random selection to use <code>array_rand</code>.</p><p id="4bd1">That still leaves us with all of those WordPress core functions built in, and broken now.</p><p id="6b1d">What we’re going to do is use <a href="https://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a> to pass in two <a href="https://www.php.net/manual/en/functions.anonymous.php">anonymous functions</a> which will accept the same arguments, and those will run the WordPress core functions.</p><p id="dd0d">All of these functions are moved to a <code>wp-loader.php</code> file, including the Plugin header comment that tells WordPress which file is the entry point to the plugin.</p><p id="3228">When we’re done, our hello.php file will look like this:</p> <figure id="c4bf"> <div> <div>

            <iframe class="gist-iframe" src="/gist/anubisthejackle/b65cc32a0d77ab810963d8e769fb03a5.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="d4f5"><i>Note: Looking at it now, I really should have used a <a href="https://www.php.net/manual/en/class.closure.php">Closure</a> instead of two anonymous functions. Using a Closure would have precluded the need to pass the anonymous functions to local variables to call them.</i></p><p id="9e3b">Now that we’ve split the core WordPress methods out, they need to go somewhere. That would be <code>wp-loader.php</code>, which looks like this:</p>
    <figure id="ed40">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/anubisthejackle/da007fdb9ace2a959855514549cbfbc1.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="cebd">First, we check to make sure that we are running inside of WordPress. The <code>WPINC</code> constant is always defined in WordPress, so that is a good proxy.</p><p id="27c8">From there we create our anonymous functions which are essentially proxies for the WordPress core functions, and pass those to the new HelloDolly class.</p><p id="d763">From there, we pass the Hello Dolly class as a parameter to a new WordPress DisplayDriver class, and call the register method.</p><p id="c6eb">That class looks like this:</p>
    <figure id="5e90">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/anubisthejackle/c4b080525439d70944282ada180f3ef0.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="0503"><i>Note: To keep the code as self-contained as possible, I eschewed the use of Composer or autoloading. You could easily add in an autoloader, however, to get rid of the require calls.</i></p><p id="73fe">I didn’t really need to build the <code>printProxy</code> method here, but I wanted to show how you could use a proxy method to call a method that requires more parameters.</p><p id="e750">These two plugins are identical in functionality. So why bother?</p><p id="10e9">Well, this is where we make the plugin Polymorphic.</p><h1 id="2c38">Preparing the Joomla!</h1><p id="de3e">Before this project, I had never even installed Joomla, let alone written a module for it. That would be why it took me an entire 15 minutes of development time to write this Joomla module.</p><p id="38cf">For the Joomla module we are going to need three things:<

Options

/p><ol><li>A Module XML Configuration File</li><li>A Module Entry file</li><li>A template directory / file</li></ol><p id="4200">I’m not sure if the last one is a requirement, but it was used in the tutorial on the Joomla website, so I used one here.</p><p id="734b">First, the XML file.</p> <figure id="95f4"> <div> <div>

            <iframe class="gist-iframe" src="/gist/anubisthejackle/3a126552bb25f8dcdeb8b4c142ae7cfa.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="6e06">I won’t try to explain exactly what each of those means, but I will point to the files block. Each of those files needs to be named exactly how it is there, and in the locations it says.</p><p id="8b7c">We’ve already talked about our core plugin code, which doesn’t change here, so let’s look at the mod_hellodolly.php file.</p><p id="aabd">This is our Joomla! equivalent to the wp-loader.php file.</p>
    <figure id="15bc">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/anubisthejackle/6b0dab04dc3a482d3501f4cabbd9e7a5.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="459f">Luckily, Joomla has a constant it uses to define when modules are being run inside of Joomla directly. So we use that here, and everything else looks almost identically.</p><p id="696a">The only difference would be line 16, where we use <code>JModuleHelper::getLayoutPath</code> to load the default layout in our <code>tmpl</code> folder.</p><p id="2ce6">That file isn’t <i>really</i> necessary here. We could easily just echo the code directly, but I wanted to emulate a full module.</p>
    <figure id="b091">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/anubisthejackle/88e72f37e35df2688909987ef3ff0c4f.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="42de">As you can see, there’s not a lot going on here. Just print the CSS, and the formatted lyric, and be done with it.</p><h1 id="ba8e">And we’re done</h1><p id="318d">That’s it. That is everything you need to create a plugin that will install both in Joomla! and WordPress, directly.</p><p id="e650">On Joomla, if you look at the install directory after installing, you’ll notice only the files listed in your XML are actually saved to disk. That means you could upload the Zip with the entire WordPress plugin on it as well, and it will only install the required files for the Joomla code.</p><p id="0932">WordPress will install every file, but will simply not use the Joomla portion.</p><p id="b688">Try it out, check out my example repository, zip the contents, and upload it to your WordPress and Joomla! sites.</p><div id="36e1" class="link-block">
      <a href="https://github.com/anubisthejackle/hello-dolly">
        <div>
          <div>
            <h2>anubisthejackle/hello-dolly</h2>
            <div><h3>A refactored version of Hello Dolly used as an example in my Medium post GitHub is home to over 50 million developers…</h3></div>
            <div><p>github.com</p></div>
          </div>
          <div>
            <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*Bysha-N5Lj15iDmb)"></div>
          </div>
        </div>
      </a>
    </div><p id="5221">When you’re done that, go forth and create polymorphic plugins.</p><p id="7639">Then <a href="https://twitter.com/n00bJackleCity">hit me up on Twitter</a> when you do it, so I can check them out.</p><p id="3536"><i>If this article was interesting to you, you’re going to love the stream of tech-consciousness that is my Twitter feed. <a href="https://twitter.com/n00bJackleCity">Head over there and give me a follow</a>. You won’t be disappointed.</i></p></article></body>

Polymorphic plugins with proper architecting

Photo by Luca Bravo on Unsplash

I love DVDs. I know, everything has gone digital these days, but I still love DVDs. Why? Because I own a lot of video game systems, and when I want to watch a DVD, all I have to do is stick it into one of them and turn it on.

It just works.

Why don’t our plugins just work? Why do I need to download a different file to load a plugin on WordPress than I do to load a plugin into Joomla? Or Drupal? What if I want to use that plugin code on my own site, but I don’t use a CMS?

“But, Travis, that’s impossible. Those are entirely different systems!”

Is it, though?

Not only am I going to say it isn’t impossible, I’m going to prove it to you. Sure it’s not easy but it is both doable, and makes for better code over-all.

Enter “Hello Dolly”

Hello Dolly is easily the most recognizable plugin for anyone who uses WordPress. That’s largely because it comes pre-installed with WordPress.

It’s also, objectively, not well written. Of course it’s doesn’t really need to be. The plugin itself is only a few lines long, and among being the most installed plugins is also the most uninstalled plugin. I don’t have numbers to backup that claim, I just assume it’s true.

I’m not here to pick on Hello Dolly. Matt Mullenweg has proven himself a capable developer, so we’re not going to insult his skillset, that’s not hte point of this article.

The point is: I rewrote Hello Dolly into a polymorphic plugin.

Say what now?

You can take the zip file from my Hello Dolly (Redux) plugin and upload it directly to both WordPress and Joomla! and it will instantly work. Out of the box. There are some setup steps for Joomla, but that’s just the way Joomla works.

First, let’s look at the original Hello Dolly plugin.

Simple, 100 lines of code, and 3 functions. There are a few problems that we’ll discuss, but the plugin is perfectly suited for what it is: A pre-installed WordPress plugin.

Let’s break it down

What is the first thing that you notice in that plugin? For me, it’s the heavy coupling between the Hello Dolly plugin and the WordPress core. The plugin immediately knows that it is a WordPress plugin, because for it to run it has to have access to the add_action function.

In fact, there are four different WordPress core functions, with add_action being the least invasive of them. Can you find them all? Take a look before reading further.

Did you find them?

If not, don’t worry, I’ll list them here:

  1. add_action
  2. wptexturize
  3. get_user_locale
  4. __

The fourth one is probably the hardest to find. I missed it my first look through the code, myself.

Let’s take a step back for one second

What even is a polymorphic plugin? Well, if you didn’t gather it earlier, I’ll define it clearly here: Polymorphism is the ability for a thing to take on many forms. In object oriented programming, we use it to describe classes that are able to be treated as other classes.

In this instance, I’m using polymorphic to describe how a single plugin can be used by multiple content management systems. In this case it isn’t true polymorphism, since there are some methods that must be added to make it work, but shoot, I liked the name.

Sue me.

Back to the refactoring!

The first thing we need to do is clean this code up. First we convert functions to a class, and give that class a namespace of HelloDolly.

Next, there’s really no need to convert a multi-line string to an array, just to get a random line. So we convert that chunk of text to an array, remove the conversion line, and update the random selection to use array_rand.

That still leaves us with all of those WordPress core functions built in, and broken now.

What we’re going to do is use dependency injection to pass in two anonymous functions which will accept the same arguments, and those will run the WordPress core functions.

All of these functions are moved to a wp-loader.php file, including the Plugin header comment that tells WordPress which file is the entry point to the plugin.

When we’re done, our hello.php file will look like this:

Note: Looking at it now, I really should have used a Closure instead of two anonymous functions. Using a Closure would have precluded the need to pass the anonymous functions to local variables to call them.

Now that we’ve split the core WordPress methods out, they need to go somewhere. That would be wp-loader.php, which looks like this:

First, we check to make sure that we are running inside of WordPress. The WPINC constant is always defined in WordPress, so that is a good proxy.

From there we create our anonymous functions which are essentially proxies for the WordPress core functions, and pass those to the new HelloDolly class.

From there, we pass the Hello Dolly class as a parameter to a new WordPress DisplayDriver class, and call the register method.

That class looks like this:

Note: To keep the code as self-contained as possible, I eschewed the use of Composer or autoloading. You could easily add in an autoloader, however, to get rid of the require calls.

I didn’t really need to build the printProxy method here, but I wanted to show how you could use a proxy method to call a method that requires more parameters.

These two plugins are identical in functionality. So why bother?

Well, this is where we make the plugin Polymorphic.

Preparing the Joomla!

Before this project, I had never even installed Joomla, let alone written a module for it. That would be why it took me an entire 15 minutes of development time to write this Joomla module.

For the Joomla module we are going to need three things:

  1. A Module XML Configuration File
  2. A Module Entry file
  3. A template directory / file

I’m not sure if the last one is a requirement, but it was used in the tutorial on the Joomla website, so I used one here.

First, the XML file.

I won’t try to explain exactly what each of those means, but I will point to the files block. Each of those files needs to be named exactly how it is there, and in the locations it says.

We’ve already talked about our core plugin code, which doesn’t change here, so let’s look at the mod_hellodolly.php file.

This is our Joomla! equivalent to the wp-loader.php file.

Luckily, Joomla has a constant it uses to define when modules are being run inside of Joomla directly. So we use that here, and everything else looks almost identically.

The only difference would be line 16, where we use JModuleHelper::getLayoutPath to load the default layout in our tmpl folder.

That file isn’t really necessary here. We could easily just echo the code directly, but I wanted to emulate a full module.

As you can see, there’s not a lot going on here. Just print the CSS, and the formatted lyric, and be done with it.

And we’re done

That’s it. That is everything you need to create a plugin that will install both in Joomla! and WordPress, directly.

On Joomla, if you look at the install directory after installing, you’ll notice only the files listed in your XML are actually saved to disk. That means you could upload the Zip with the entire WordPress plugin on it as well, and it will only install the required files for the Joomla code.

WordPress will install every file, but will simply not use the Joomla portion.

Try it out, check out my example repository, zip the contents, and upload it to your WordPress and Joomla! sites.

When you’re done that, go forth and create polymorphic plugins.

Then hit me up on Twitter when you do it, so I can check them out.

If this article was interesting to you, you’re going to love the stream of tech-consciousness that is my Twitter feed. Head over there and give me a follow. You won’t be disappointed.

Plugin Development
Wordpress Development
Joomla Development
Php Development
Clean Architecture
Recommended from ReadMedium