Published by Mijingo

movie icon image

ExpressionEngine How-to Articles

Topics range from beginner to advanced, but are all born out of real world, professional, day-to-day use of ExpressionEngine. Need more information? Get training videos and ebooks on ExpressionEngine from Mijingo.

Building an Accessory, Part I

In this two part tutorial we’re going to walk you through building an accessory. The first part will cover creating a very simple HTML-based accessory with your contact information. The second part will build on the first using ExpressionEngine’s native code to create a fully functional contact form. Part I assumes you understand HTML, while part II will assume you know some PHP.

Let’s get started.

What is an Accessory?

Described in the documentation, an accessory is a little tab at the bottom of the ExpressionEngine control panel that gives users quick access to all types of information. Some of the best ones include Template Variables and CP Analytics. These examples are very complex. We can build something just as useful, but much simpler.

Why build an Accessory?

An accessory isn’t very difficult to build, and adding your own accessory to a client’s site adds a level of polish that will surely impress. In our case we’re building a contact form for clients that tells us what page they are on when they submit the form. This means we can debug based on their location, and they don’t have to stray to far to get help. It will make our job easier and will create a simple way for clients to report problems.

How does ExpressionEngine load accessories?

ExpressionEngine loads accessories with, what we call, “automagic.” When EE looks in the third_party directory and finds your accessory, it checks the file to make sure it has met specific requirements (which we’ll discuss later). ExpressionEngine does the heavy lifting as long as you follow the accessory conventions; otherwise you’ll be wondering where your accessory is and why it won’t install. The golden rule: don’t break from the conventions.

Creating the accessories’ directory

All third party add-ons go in the /system/expressionengine/third_party/ directory. This includes extensions, modules, fieldtypes, accessories and plugins. Each individual add-on goes into a separate directory (but an add-on can include one of each type such as an extension and an accessory). If your add-on has more than one word for its name, then you have to change that space into an underscore. Folder names and filenames (as well as all add-on filenames) are lowercase.

Say we have an add-on called “Awesome Town”. We create a folder in /system/expressionengine/third_party/ called awesome_town. All our files go in this folder: /system/expressionengine/third_party/awesome_town/

The add-on we’ll be building will be called First Contact and will sit in a folder named first_contact. Create the first_contact folder in the /system/expressionengine/third_party/ directory.

Naming our accessory files

Accessories main code sits in a file called acc.accessory_name.php. In ExpressionEngine all add-ons have a prefix to denote their type. For example, an extension begins with ext (ext.playa.php) and a fieldtype begins with ft. The file name must be the same name as the folder we created in the previous step with the appropriate prefix and .php to end it (ExpressionEngine does some automagic loading that requires it… for now). We’ll name our accessory file acc.first_contact.php.

So create this file in the /system/expressionengine/third_party/first_contact/ folder we created.

Creating the accessory shell

All accessories have a very basic starting layout. You can copy and paste the following code as much as you like. It’s our basic accessory shell.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * The First Contact Accessory
 *
 * @package First Contact
 * @author Kenny Meyers
 */
class First_contact_acc {
    
var $name                'Contact Your Developer';
    var 
$id            'first_contact_acc';
    var 
$version        '1.0';
    var 
$description            'This is an accessory allowing you to get in touch with your developer, <a href="http://kennymeyers.com">Kenny Meyers</a>';
    var 
$sections        = array();
    
/**
     * Constructor
     */
    
public function First_contact_acc()
    
{
        $this
->EE =& get_instance();
    
}
    
    
    
public function set_sections()
    
{
        
//Sections go here
    
}
}

/* End of file acc.first_contact.php */
/* Location: ./system/expressionengine/third_party/first_contact/acc.first_contact.php */ 

Paste the above code into your acc.first_contact.php file.

Breaking the code down

The first line begins:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 

What this first snippet does is check to see if ExpressionEngine is accessing the file. If not, if it’s a HUMAN or a devious Hacker-bot out to destroy your site, it will return to the browser a page that says “No direct script access allowed”.

/**
 * The First Contact Accessory
 *
 * @package First Contact
 * @author Kenny Meyers
 */ 

This is a class DOCBLOCK, a form of documentation in PHP. This is just telling people what the class is and what package it belongs to as well as whom is the nuisance behind its terribleness. You can find out more about DOCBLOCK, here, but be warned… it’s a terrible place.

class First_contact_acc { 

We declare the class following the ExpressionEngine development style guide (you MUST read this). It’s important, if you’re building an accessory, to add _acc to your class name. ExpressionEngine uses this internally to recognize an accessory class, much like we prefixed the file with acc. It’s one of those conventions that allows for EE to do some automagic stuff without too much hassle.

Metadata
var $name        'Contact Your Developer';
var 
$id            'first_contact_acc';
var 
$version        '1.0';
var 
$description    'This is an accessory allowing you to get in touch with your developer, <a href="http://kennymeyers.com">Kenny Meyers</a>';
var 
$sections        = array(); 

The listing of the First Contact Accessory in ExpressionEngine

The listing of the First Contact Accessory in ExpressionEngine

The next area is very important. We’re setting the Accessories properties. This is data that will appear in the CP and to our users. For example, the $name variable shows up on the accessory page (as you can see in the screenshot above). It’s abnormal to set your $name as something other than the class name (e.g. “First Contact”), however we have to consider our clients. If they see “First Contact” they’re going to be confused, so we choose a more human-friendly call to action.

The $id shows up in the HTML for the accessory. Yes this is actually the HTML element class for the accessory’s tab navigation item and the id for the accesorry’s div. It will let you style solely your accessory instead of change the control panel. We’ll cover styling your accessory in part II. You can see the markup below

HTML for the Accessory

HTML for the Accessory

$version will show up in your control panel on the accessory pane. It’s just to let users know which version of the accessory they have installed. If there are any updates they will be able to verify that they have the latest version.

var $description shows up right next to the version. It’s self-explanatory. Describe what your accessory does. I’ve included some HTML so clients remember who I am, but it’s rare you’ll want to do this.

$sections is an important one, which we’ll get to shortly (cue suspense music).

Think of the above code as telling ExpressionEngine different properties of your Add-on. Much like a driver’s license has all your pertinent information (DOB, height, weight), this is the accessory describing itself.

PHP
/**
     * Constructor
     */
    
public function First_contact_acc()
    
{
        $this
->EE =& get_instance();
    

Most classes require what’s called a constructor. Essentially it’s the function that builds an object (nerdy programmatic stuff). Conceptually, this is far advanced for this lesson so just include this. We’ll talk about the $this->EE function in the next article. Right now, a copy and paste job, with a little forgetfulness, will help us get through this.

public function set_sections()
    
{
        
//Sections go here
    

We’ll get to the above, but first I’d like to talk about this:

}

/* End of file acc.first_contact.php */
/* Location: ./system/expressionengine/third_party/first_contact/acc.first_contact.php */ 

End your accessories with this. You can see it has the accessory filename and it pinpoints its location. If you build your own accessory in the future replace it with your information (don’t use acc.first_contact.php for example).

It is not necessary to end these files with a closing PHP tag, like this: ?>. You can find more about this line ending in the style guide.

Once you have all this information typed in, save your acc.first_contact.php file. You should be able to install the accessory now. Go to Add-Ons -> Accessories, look for Contact Your Developer and click on the Install button.

Sections

Now we can get to the bread and butter of ExpressionEngine accessories. This PHP function:

public function set_sections()
    
{
        
//Sections go here
    

Our goal with this version of our accessory is to provide a simple means of contacting us. This means we have to determine what information we want to convey. Let’s give them our name, email, website and mailing address.

public function set_sections()
    
{
        $this
->sections['Contact Info']  '<p>Kenny Meyers<br /> <a href="mailto:kenny@kennymeyers.com">kenny@kennymeyers.com</a><br /> 1234 Anywhere Ave<br /> Narnia, CA 90210 <br /><a href="http://kennymeyers.com">kennymeyers.com</a></p>';
    

If you refresh the page, you’ll see that your information is now available at the bottom.

What just happened

Remember that var $sections = array(); from the top of your class? It turns out ExpressionEngine looks to that for your accessory content. So when it loads your accessory, it calls that set_section function and loads that array (or list) of content.

This piece of code…

$this->sections["Contact Info"]  '<p>Kenny Meyers<br />
<a href="mailto:kenny@kennymeyers.com">kenny@kennymeyers.com</a><br />
1234 Anywhere Ave<br /> Narnia, CA 90210 <br />
<a href="http://kennymeyers.com">kennymeyers.com</a></p>'

...translates to this in plain English:

This accessories section ($this->sections) has a heading of “Contact Info” ($this->sections[“Contact Info”]). The ‘Contact Info’ section has this content ( = ‘<p>Kenny Meyers<br />...’).

So if you wanted to create an additional section you could just add one below it.

$this->sections["Contact Info"]  '<p>Kenny Meyers<br />
<a href="mailto:kenny@kennymeyers.com">kenny@kennymeyers.com</a><br />
1234 Anywhere Ave<br /> Narnia, CA 90210 <br />
<a href="http://kennymeyers.com">kennymeyers.com</a></p>'
;
$this->sections["Buy Ryan's Book slave"'<a href="http://eequickstartguide.com/">BUY NOW THE MAN IS HAVING A BABY FOR THE LOVE OF PETE</a>'

While the PHP is not pretty the actual accessory will look like image below.

Basic accessory with contact information.

Basic accessory with contact information.


So you can see, ExpressionEngine automagically creates its own section.

Our Accessory

Here is our finished accessory:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * The First Contact Accessory
 *
 * @package First Contact
 * @author Kenny Meyers
 */
class First_contact_acc {
    
var $name        'Contact Your Developer';
    var 
$id            'first_contact_acc';
    var 
$version        '1.0';
    var 
$description    'This is an accessory allowing you to get in touch with your developer, <a href="http://kennymeyers.com">Kenny Meyers</a>';
    var 
$sections        = array();
    
/**
     * Constructor
     */
    
public function First_contact_acc()
    
{
        $this
->EE =& get_instance();
    
}
    
    
    
public function set_sections()
    
{
        $this
->sections["Contact Info"]  '<p>Kenny Meyers<br /> <a href="mailto:kenny@kennymeyers.com">kenny@kennymeyers.com</a><br /> 1234 Anywhere Ave<br /> Narnia, CA 90210 <br /><a href="http://kennymeyers.com">kennymeyers.com</a></p>';
        
$this->sections["Buy Ryan's Book slave"'<a href="http://eequickstartguide.com/">BUY NOW THE MAN IS HAVING A BABY FOR THE LOVE OF PETE</a>';
    
}
}

/* End of file acc.first_contact.php */
/* Location: ./system/expressionengine/third_party/first_contact/acc.first_contact.php */ 

Again, just to reiterate, this code is in the file acc.first_contact.php in the /system/expressionengine/third_party/first_contact/ directory.

Moving Forward

In the next article, we’ll add a contact form to the First Contact accessory. It will be fantastic and you will all be delighted. Stay tuned!

Kenny Meyers
About Kenny Meyers

Kenny Meyers is a web developer based out of San Francisco who currently works for the excellent Virb.com. Kenny has worked on the web in some capacity for 12 years and has helped organize, write and build some great ExpressionEngine sites including Mithun.com and the upcoming Omni Group website. When he's not crying alone, Kenny writes regularly, abusing adjectives and hyperbole, at Happy Magic Fun Time and runs his mouth on twitter @kennymeyers.