Creating a WordPress Widget

WordPress is an excellent platform for anyone to use for their blog, and it’s even better for developers who wish to extend its functionality through the inherent plugin architecture. This article will guide you through the steps of creating your own plugin, enabling it to act as a widget and creating its own control panel to use through the administration interface.

We will be creating a simple plugin that displays a short bio of the blog author in the sidebar. This was actually a real-world scenario I was faced with when the blog design called for a bio in the sidebar. Two of the requirements were  that the title (“author”) be represented by an image, and the author’s name be highlighted in bold. This situation called for custom markup to be generated instead of relying on the built-in WP sidebar functions.

So let’s get started.

The Foundation

The first thing to grasp is that a WordPress (WP) plugin, in its simplest form, is nothing more than a single PHP file residing in the wp-content/plugins folder. We will call our plugin mviAuthor.php.

A comment block needs to reside at the top of the file for WP to recognize information about your plugin.

Comment block
Comment block

The lines above are self-explanatory. WP uses this information in the admin panel as shown below.

Manage plugins
Manage plugins
Activate plugin
Activate plugin

The next step is to define a class that represents our plugin. Using a class is not necessary, but it keeps your code cleaner. If you are not familiar with using classes in PHP, refer to the documentation at php.net (http://www.php.net/manual/en/language.oop5.php). Let’s define our class.

Setup the main class
Setup the main class

All we’ve done here is declare the class (line 14) if it doesn’t exist (line 13) and include a default constructor (line 15).  We will need to display the author information, so let’s start simple and just display some static text.

Display author
Display author

Note that this function resides within the MVIAuthor class. We now have a function that can be called to actually output something to the screen. Let’s now set this up as a widget we can use.

Remember that this PHP file be run as long as we have activated the plugin. Therefore, the code in the file will be run every time a WP page loads. What we need to do then is to define a function to call when the plugins are loaded, register this plugin as a widget and define a function that will be called when the registration triggers. Let’s first react to the plugins getting loaded.

Add action
Add action

This statement is defined outside of any class or function, so it will run whenever WP loads the plugins. When they are loaded, a function named mviAuthor_init will called. Here is the definition for that function.

Author Init
Author Init

This function, also outside of the class, registers the plugin as a widget. The registration action calls a function named widget_MVIAuthor, and is defined below.

Plugin loaded
Plugin loaded

When this function is called, it makes sure the class has been defined (line 90), instantiates the class (line 91) and calls its displayAuthor function (line 92). If you go to the Widgets page in your WP admin panel, you will now see your widget in the Available Widgets panel.

Available widgets panel
Available widgets panel

If you drag the MVI Author widget over to the Sidebar panel, then look at your blog, you will see “This is the author text” displayed in the sidebar.

The Control Panel

Obviously we don’t want our widget to display “This is the author text”, but neither do we want to replace that text with something we want, directly in the PHP file either. If we did, we would have to require anyone using our widget to modify source code just to change their bio information. Luckily, WP lets you define a control panel for your widget, giving users an easy way to modify dynamic data.

Our first step is to register the function that will handle the control panel, so lets add a line to our mviAuthor_init function.

Register widget and panel
Register widget and panel

After registering the plugin as a widget, we then register the widget’s control panel by stating the function that will be called to handle the panel (line 107). Let’s now define that function.

Control panel function
Control panel function

Again, if the class exists (line 98), instantiate the class (line 99) and call a function to handle the control panel (line 100).

The function to handle the control panel resides within the MVIAuthor class. There is a lot going on within this function, so we will build it in little steps (Do not try to run the code in this function until you see it completely built. Otherwise WP will throw errors). The first step is to define how the control panel will look.

Control function
Control function

On the surface, we are simply displaying a small form, allowing the user to input the author’s name and a short bio.

Widget settings
Widget settings

Now we need a way to save the data that you will input here. Just clicking the Save button at this point will do nothing. First, we need to determine if the user has clicked the Save button. To do that, we will add a hidden field to our form, then test to see if its value was posted.

Hidden input
Hidden input

Using Dynamic Data

We can now test if $_POST[‘bioSubmit’] and $_POST[‘nameSubmit’] exist, and if so, save them to the WP database. This is done with the built-in update_option function.

Save setting to database
Save setting to database

We’ll just check if $_POST[‘bioSubmit’] exists (line 33). If so, we will assign the post variables to local variables (lines 34 and 36) and save them to the database (lines 35 and 37). Now we can retrieve those names from the database, using the built-in get_option function,

Retrieve settings
Retrieve settings

make sure the values exist,

Set default
Set default

and display them on the form.

Display settings
Display settings

Note that the options are returned from WP as an array, so to display the author’s name we use the syntax $aName[‘mviAuthorName’]. We can now expand the displayAuthor function to display the values retrieved from the WP database.

Display author
Display author

What I’ve done here is grab the values using the built-in get_option function (lines 58 and 59), checked to make sure they exist and if not, store nothing (lines 61 through 73), then display the data. I’ve added a couple of classes so I can target them with CSS (lines 75 and 80). I’ve also displayed the image as my widget title. Note here that I used the built-in bloginfo function and passed it the ‘template_url’ property to link to my image.

Summary

Here is an outline of the steps used to create the widget:

  1. Create a PHP file and place it in the wp-content/plugins folder
  2. Define a class that represents your widget
  3. Add two functions to the class: one to display output to the sidebar and one to handle the control panel
  4. Define two functions outside of the class that will be called upon widget and control panel registration
  5. Define a function outside of the class that calls the widget and control panel registration functions
  6. Add an action to the file that starts the whole process when the WP plugins are loaded


Faster Fast Food

To stay on the subject of McDonald’s, while giving the cashier the order for my six-person family on my last visit, I was thinking about how I routinely give this lengthy order, and how there’s a good chance I may miss a subtle difference from one week to the next (apple dippers instead of fries, or ranch dressing instead of honey mustard. Oh, the wrath I receive when I deliver a tray with the wrong dipping sauce).

So I started taking orders for my family with the trusty notepad app on my iPhone. I walk into the restaurant and read the order off my iPhone to the cashier. Wouldn’t it be nice, I thought, if I could just send the order from my iPhone to the cashier’s terminal? This method would have several benefits, including:

  • Order accuracy (this helps me out more than McDonald’s since I’m the one who usually gets something wrong)
  • Saves time (it takes me quite a while to spill out the details of several custom meals. Think about how this would speed up the line at Subway! No more “wheat bread, six inches, toasted, lettuce, onions, green peppers, light mayo, honey mustard, salt…and on the next one….”)
  • Payment integration (you might as well pay with the app while you’re at it instead of reaching into your wallet for your card, or worse, cash)

There are several ways this could be handled, but we’ll just play around with one idea here. I’m thinking each restaurant would have its own app. That way, each could keep its own menus up-to-date. I would take my family’s order with the app by tapping on menu items (probably much like the cashiers do with their touch screens) instead of typing in my notepad. I could save the entire order as a favorite to use again, or use as a basis for quickly creating an order with only a few changes.

I walk into the restaurant with the app fired up. The cashier asks me what I would like, I inform him that I’ll be sending it over. I press send, he acknowledges, I confirm the total, my card gets charged, and I wait for my order to be assembled. Here is a diagram of the process:

Fast food app
Fast food app architecture

Digital Donations

I was at McDonald’s the other day, looking at the mostly empty donation box in front of the cash register, and was wondering if Ronald McDonald House Charities had felt an impact from the current trend of plastic money over paper. I have rarely carried cash for several years now, and I know many others do the same. Several years before then, when I did carry cash, I didn’t hesitate to throw my change into the donation box.

There’s got to be a way for us plastic users to easily donate to this and other worthy causes. I remembered a few years ago, when another fast food restaurant was asking for donations to help the homeless, and they asked if you would like to round up your bill. I thought this was an excellent idea and made it so easy to give. For example, if your meal cost $4.45, you could round up your bill to $5.00, and the extra $0.55 would go to charity. This method works for plastic as easily as it does for cash. You are told the total amount of your bill, including the donation, and you pay as you wish.

I think McDonald’s and RMHC would do well in implementing a similar program. To raise the idea another level, what if the credit card terminal prompted the customer for a donation amount? The options would be something like “round up”, “$1.00”, “$2.00”, and “Cancel”. This may prove to increase donations even further, as many people may opt for at least the one dollar option.

I have diagrammed the process below. Do you see any barriers to this implementation? What may work better?

Digital donations
Digital donations

Adding jQuery to a Custom DotNetNuke Module

Step 1: Register jQuery

In the code behind for the page you will be making jQuery calls, register the library in the OnPreRender event:

protected override void OnPreRender(EventArgs e)
{
string moduleDir = this.TemplateSourceDirectory;
Page.ClientScript.RegisterClientScriptInclude("jQueryScripts", moduleDir + "/scripts/jquery-1.3.2.js");
Page.ClientScript.RegisterClientScriptInclude("jsUtilities", moduleDir + "/scripts/utilities.js");
}

The first line stores the path to the module’s folder. I stored the jQuery library in the module’s scripts folder, so the next line registers the library with a supplied key (your choice of name) and the path to the library.

The third line registers another javascript library, this time one of my own javascript files.

Step 2: Initialize jQuery

DNN has name conflict issues with jQuery so the following line is needed (thanks to Steve Johnson at Abstract Coder for this tidbit):

var $j = jQuery.noConflict();

I included this in my utilities.js file outside of any functions.

Step 3: Call jQuery Functions

It is important to note that all of your calls to jQuery functions will use this $j variable instead of the normal, single $ you will find documented just about everywhere.  So for example, the document ready function will look like this:

$j(document).ready(function() {
//your code here
});

Now you can write your normal javascript code and call jQuery functions throughout. Just remember to use the $j variable.

Step 4: Accessing Control IDs

This step is not specific to jQuery, but I wanted to include it because I found that many people, including myself, were having a hard time trying to figure out how to target controls with javascript. Consider the following ASP.NET control on a page:

<asp:textbox id="simpleTextBox" runat="server" />

When using this control server-side, say with C#.NET, you write things like:

string t = simpleTextBox.Text;

So, naturally, you’d think to access this control via javascript, you would write something like:

t = document.getElementById("simpleTextBox")

However, ASP.NET will prefix all of your controls with parent container IDs to avoid conflicts. Thus your ID of simpleTextBox will be converted to something like dnn_ctr459_EditMyModule_simpleTextbox. This doesn’t matter to your code as it stays server-side, but once it hits the client, your javascript code has no clue what simpleTextBox is anymore.

My solution is to specifically tell javascript what the new name of the control is (my thanks to steveradich’s post at aspdeveloper.net for nudging me in the right direction here).

1. Register the javascript event handler when the page loads

protected void Page_Load(object sender, EventArgs e)
{
simpleTextBox.Attributes.Add("onclick", "testFunction('" + simpleTextBox.ClientID + "')");
}

The key to this line of code is the ClientID property. We are sending our javascript code the new name of the control here.

2. Access the control from javascript

testFunction(cid) {
c = document.getElementById(cid);
}

Note here that we are using the same getElementById function, but now we are armed with the new ID of the control.

3. Target the control with jQuery

The following is an example of targeting the control using jQuery syntax:

$j('#' + cid).slideDown('normal');

*Note: I used this solution with my current installation of DNN, which
is 4.9. Version 5.0 has native jQuery support, which may change some of
these steps.

Integrating a Third-Party Search Service Into Magento

I’ve just finished integrating a custom search module into Magento and thought I’d share how I decided to lay out the main components. Again, I’m still feeling out how all of the different pieces of the Magento puzzle fit together, so I’m sure there are better ways of doing this. However, refer to the diagram below, and I will detail my implementation.

Magento search module integration
Module integration

I have a search container that actually holds two different search types. The first search type is the built-in Magento store search. I did not change any functionality for this module, so I simply modified the stylesheets to have it fit into my theme. The second search type, however, allows the user to search a third-party service, and display the results inline with the current store. You don’t have to think of a specific web service, just a generic one which receives a search term and returns results.

As with all Magento modules, the new module must be registered with the framework (see earlier post). After that is done, the module must be displayed. I wrote a view.phtml page to display the custom search form. There is nothing too interesting about this file, just note that it contains its own form with its own action attribute. However, in this example, this behavior is identical to the built-in search form, which is to post back to the current page. In this case, it will add the search term to the page’s query string.

To display the results, note that the result.phtml file is always rendering HTML. There’s just nothing to render unless there is a search term present in the page’s query string (provided by clicking the custom search button). If a search term is present, result.phtml sends its parent object (search2.php, as defined in page.xml) the search term. Search2.php then calls the web service, receives the results then sends them back to result.phtml for rendering to the page.

Integrating a Blog with an Existing CMS

I recently finished a project for a client whose site was built on the DotNetNuke CMS. He wanted to integrate a blog into his site, so I was faced with three choices:

  1. Find a suitable blog module for DotNetNuke
  2. Write a DNN blog module from scratch
  3. Find another blog platform and use it alongside the CMS

After failing to locate a blog module that I thought would satisfy the client, and not having the budget to write one from scratch, I was left with one choice. However, the next challenge presented itself. Since the visitor already has a login to the CMS site, it would be nice if they didn’t also have to login to the blog. This was going to require some custom coding, so the chosen blog platform had to expose a robust API. WordPress looked like it had all the answers. Now that I had the two platforms, the challenge was to get them to talk to each other.

The WordPress API includes functions for creating new users and logging them in. So the plan was to develop a WordPress plugin that would automatically check who the current CMS user was, register them with the blog if necessary, then log them in. WordPress would know who was logged in by checking a cookie stored by the CMS.

The following diagram illustrates the main components of the solution:

Blog and CMS
Blog and CMS

I would like to point out a couple items of interest with this solution:

  1. Cookies are only able to be read by code within the same domain. Therefore, you would not be able to use this method if your CMS was at www.yourdomain.com and the blog was hosted at, say, WordPress.com.
  2. Once the user clicks the blog link at the CMS, the cookie is stored for the blog’s use. If the user was visiting the site on a shared computer, you would not want another user to visit the blog and be automatically logged in as the previous user. Therefore, the cookie expires at the end of each user’s session.

If anyone else has had to tackle something similar to this, or have other ideas on how this could have been accomplished, I would love to hear from you.

Magento Architecture for a Simple Module

Preparing to write my first custom Magento module, I dove into the documentation that was available, as well as various blog posts, and slowly started to understand some of the pieces. The whole picture was eluding me, however, so I began to diagram how everything fit together. I referred to the following pages when creating the diagrams:

http://activecodeline.com/writing-a-custom-module-in-magento-detailed-walktrough/

http://www.exploremagento.com/magento/simple-custom-module.php

http://stackoverflow.com/questions/576908/how-does-magento-code-work

Please note two cautionary items before reading further. 1) I am new to the Magento framework, so the following explanations are based on my limited knowledge of this subject. 2) These diagrams detail an extremely simple custom module that does not take advantage of many advanced features, including layouts and controllers. I am hoping though that they may shed some light for some of you. I am currently working through some of those advanced features, however, and hope to post an article when I am comfortable with them as well.

I will dissect the module here, but you may view the whole thing at once at the bottom of this post.

For the new module to be registered and seen by Magento, an XML file needs to be created in the following path: [store]/app/etc/modules/, where [store] is your store’s root directory. The XML file needs to be named with the following convention: [namespace_module].xml, where namespace is your code’s namespace (defined by you, usually your company name) and module is your module’s name.

Magento Module Registration
Magento module registration

Your actual module resides in the following path: [store]/app/code/local/[namespace]/[module] and its several subfolders. You will create a configuration file in the etc folder called config.xml.

Configure the Magento Module
Configure the Magento module

Now the module needs to do something when it is called by a template, so we will create a code file called View.php and place it in the module’s Block folder.

Configuring the View
Configuring the view

We will now move over to the theme, or skin, to see how to make use of this module on an actual store page. Your theme contains a template folder which holds folders for your modules. We will create a View.phtml file that outputs direct HTML and calls a function for more HTML in its model, or block, at View.php.

Output of the view
Output of the view

The only thing left is to actually instantiate the module on a store page. This will most likely be done as an integrated part of your theme, but for now we will keep it simple. Enter the CMS portion of your store and open up a page of your choice. Enter the following line somewhere in the body:

{{block type=”Namespace_Module/View” template=”module/View.phtml”}}

substituting namespace and module for your actual names.

What has happened here is that you’ve instantiated your module’s view (View.php) using the template (View.phtml). View.phtml now outputs HTML and calls its underlying model to provide more functionality.

I hope this makes sense for you and comes in as a handy supplement to the aforementioned links, as I am only beginning to grasp it. Feel free to comment and set me straight if I’m off in left field on any of this.

Here are the diagrams in full:

Magento module architecture
module architecture
Magento module skin architecture
Skin architecture

Future World Directional Sign in Blender

I was in the mood to model with Blender today, so I recreated a typical directional sign found in Future World at EPCOT. What I find interesting about this excercise is that the entire model is basically made out of primitives (cylinders, cubes, etc.) But when put together, the design looks really cool, thanks to the brilliant Disney Imagineers.

Future World Directional Sign
Future World Directional Sign

There are a few techniques worth mentioning, however. Refer to the figure below.

Slicing an Object
Slicing an Object

The outer frame is a cylinder, that was simply extruded around a corner. One end of the cylinder was rotated 45 degrees around the Y-axis, then extruded down the Z-axis.

The lattice work is made up of elongated cubes. All of them originally overhung the outer frame. I couldn’t find any kind of “slicing” operation, so I created another elongated cube to act as my slicing object. I positioned it where I wanted the slice to occur, then performed a Boolean Difference operation with each piece of lattice.

The outer cylinders, that will eventually hold the arrows that point to the associated attractions, are actually made up of three cylinders. I began with the first cylinder and deleted its end faces, so I basically just had a hollow ring. I duplicated the ring, then scaled it down to make an inner ring. On each end of this dual cylinder, I made faces between the inner and outer rings. I then created a third cylinder, kept its faces intact, and scaled it to fit inside the inner ring.

PayPal, ASP.NET and PDT

I am working on a client’s site, which requires subcribing to a newsletter via PayPal. Other requirements include:

  • The site lives within the DotNetNuke content management system
  • A custom DNN module must be written with C# and ASP.NET to handle post-processing of the transaction data

After reading through the documentation at PayPal’s developer site, I thought I had a handle on how to write the code. I was wrong, and thankfully several forums and a handy tool later, the code appeared to be working (although I was consitently getting a FAIL response from PayPal’s PDT interface). After scouring the docs and forums again for a solution to the FAIL problem, I finally realized that maybe the reason for the FAIL was that the payment was not going through.

I’m testing this process within PayPal’s sandbox, so I went into the settings to find out if I had set something wrong. And of course I did. I had previously set up a few accounts manually, obviously not quite understanding how to get everything setup properly. The email addresses were not verified, for one thing. Luckily, PayPal has an option to setup preconfigured buyer and seller accounts.

PayPal Sandbox
PayPal Sandbox

After I setup a couple of preconfigured accounts, everything worked beautifully. I’ve never seen this mentioned in any of the forums, so hopefully, this will be what some of you are looking for.

Curves and DupliVerts in Blender

The next step for my EPCOT scene was a curved guardrail. I knew I was going to have to get a grasp of two main concepts: extruding along a path and duplicating objects along a path.

EPCOT West - Bench with Umbrella and Rail
EPCOT West - Bench with Umbrella and Rail

The top and bottom of the guardrail, as well as the ends, involved extruding a circular cross section along a path. For the top and bottom, I drew a Bezier curve to the desired shape. I then drew a Bezier circle to act as the cross section. Then I simply selected the curve and told it to use the circle as its bevel shape. For the ends, I created a path and adjusted its vertices to the desired shape. Again, I created a circle to act as the cross section, selected the path and told it to use the circle for its bevel shape. Why did I use a path instead of a Bezier curve for the ends? I’m not sure. I think at the time I was unsure how to add more control points to the curve, and a path comes with five control points as default. This allowed me to bend the ends 90 degrees to meet up with the rails.

The posts are made up of simple cylinders. Obviously I only wanted to create one cylinder and have it duplicated along the rail. So the first thing I did was to duplicate the rail curve to act as a path for the posts to follow. I then converted the curve to a mesh object and subdivided it a few times until I had the desired number of vertices. I created one post and made the new mesh its parent. I then selected DupliVert, and I had a path full of posts.