Fun With Magento Widgets

By Joshua Romero

Recently we were tasked with creating a homepage for a client that allowed both them and their 27 affiliate sites to edit and organize how they saw fit. Six primary affiliate sites featured their own branding and colors while the other 21 sites could choose from one of a variety of pre-determined color themes.

There were a few ways we could have solved the problem. We ended up choosing to utilize Magento’s built-in widget functionality. The reason we chose widgets is because it seemed the easiest way to allow the client to have a GUI to upload images and edit text fields while being able to choose where, and in what order, the widgets appeared on the homepage. This article chronicles what we discovered about Magento widgets.

The first thing we decided on was to use the BEM naming convention for the CSS. It allowed us to write the styles in such a way that if the client wanted to use one of the homepage widgets on another page, they could do so without breaking the layout. We also knew we would be using the widget logic on other projects, so we chose to make sure to name every part of the widget the same, to build consistency. It also has the advantage of making it super-easy to find a particular file just by doing a search for, say, “primary-slider”.

All total, the homepage used six widgets: Homepage Slider, Promo Block, Products Block, Welcome Block, SEO Block, and Blog Block. We will just be focusing on the Homepage Slider since widgets all follow the same basic pattern and the Homepage Slider was the most intricate.

gaugeinteractive_flexslider_xml
GaugeInteractive_Flexslider.xml

The first thing you’ll need to do is establish a new extension for Magento to pick up by creating an XML file in the app/etc/modules folder. You’ll notice that I’m using a dependency. This is so the client can upload images to the widget. You can find the Widget Image Chooser extension on GitHub.

Next, we will go to our app/code/local folder and create the GaugeInteractive folder with the following subfolder setup.

folder-structure
Flexslider Extension folder structure

Really simple. We’ve got our requisite config.xml file that sets up our Helper and Block files and a widget.xml file for all of our widget configuration. Let’s take a quick peek at the Data.php Helper file.

data_php
Data.php

This file simply sets up the translation functionality that Magento provides. You’ll notice in our XML files we’re using the translate attribute to define which XML nodes we want Magento to translate for us. Now let’s take a look at our config.xml file.

config_xml
config.xml

You can see from the image above that all we’ve done is set the version number and declare our global Block and Header classes for the system to pick up.

widget_xml
widget.xml

This is an abbreviated version of the full widget.xml file. This simply defines the first image settings. In reality, there are four image sections, as you’ll see referenced in the Flexslider.php file below.

So let’s break this down: we create the new node <gaugeinteractive_flexslider> and fill in a couple of attributes. The node name is what you’ll search for when adding the widget in the admin area. The description is pretty self-explanatory. Below that you’ll see the node. It’s in here that we describe the different settings for the end-user to have available. Finally, we have the node where we tell the widget where to look for the .phtml file that will output our widget to the front-end. Let’s take a look at the Flexslider.php file.

flexslider_php
Flexslider.php

Widgets extend the Mage_Core_Block_Template class and implement the Mage_Widget_Block_Interface class. All widgets must extend and implement these two classes, otherwise they will not work.

We can use the _prepareLayout() method to add our CSS only to the page when the widget is called. This saves us a few kilobytes and a request (unless you’re merging and minifying your CSS. You are merging and minifying your CSS, aren’t you?) for our users.

Next we define a public method for our .phtml file to use. We could use the getData() method but because we’re dealing with sets of images with their own independent values, it’s cleaner and easier (at least to me) to spell it out this way.

Lastly, we use the asort() function to sort the array by the first item $this->get*ImagePosition() and return the collection.

The final piece of the puzzle is the flexslider.phtml file. This is the template file we declared in our widget.xml file.

flexslider_phtml
flexslider.phtml

Again, very simple and portable. You can see we’re calling our getImages() method we defined in the Flexslider.php Block file, and then using a foreach loop to go through each image and output the values in our element. You’ll also notice I’m using the element. The client wanted the ability to control both the desktop and mobile images, so we experimented and went with this solution using an excellent polyfill by Scott Jehl and friends.

Now that the setup is done, let’s take a quick look at the admin side of things.

widget_instance_settings
Widget Instance settings
widget_instance_properties
Widget Instance properties
widget_instance_options
Widget Instance options

That’s pretty much it. Depending on where you want to use it, and how you want it to show up on your page, you might have to configure extra settings in your local.xml file to make sure the widget shows up where you want it to.

This has been a pretty quick, basic overview of how we went about creating a widget for a client. If you know of a better way or see anything that could be improved, please feel free to reach out and let us know.