Hastymail2 is an Open Source IMAP webmail client written in PHP. Our focus is compliance, usability, security, and speed.
2015-04-16 Update:

Sadly Hastymail2 is no longer being maintained. Happily this is because we are working on a new web-based E-mail client, called Cypht. If you need support your best bet is the #hastymail IRC channel at freenode. Thanks to everyone who contributed to and supported this project!



    Hastymail has a powerful plugin system that PHP developers can use to alter the way Hastymail works. Plugins can add pages within the Hastymail application (including css files), alter existing pages by inserting XHTML, modify internal data structures within Hastymail, make AJAX callbacks using our AJAX system, and even communicate with a configured SQL server. In order to keep the plugin system overhead to a minimum, the system defines filenames and some function names that a plugin has to use in order to function properly. The files and functions that need to be created are dependent on the features that the plugin uses. Currently Hastymail2 has 31 plugins in SVN. All plugins detailed on this page are part of the main Hastymail2 download in a subdirectory called "plugins". 

Existing Plugins

    This plugin adds auto-complete ability to the To, Cc, and Bcc fields of the compose page. It requires javascript and is still a beta version. It searches all configured contact sources and allows addresses to be selected via the arrow and enter keys or the mouse.

    This plugin adds a "Calendar" link to the main Hastymail2 menu. It can display a yearly, monthly, weekly, or daily view of any timeframe. It supports events stored in either Mysql or Postgres and has a summary display for the current days events that can be enabled below the folder tree.

    This plugin adds 3 settings to the compose page options on the options: Confirm any click of the send button; confirm any click of the send button if the subject is blank; confirm when navigating away from the compose page if a message was started but not sent.

    This plugin adds a toolbar to the message view page that allows users to quickly search for selected text on the web. When text is selected the toolbar activates and the text can be searched using Google, Wikipedia, a thesaurus, or a dictionary with results opening in a new browser window. The search buttons are defined with a simple PHP array in the plugin's settings file so any search site that supports using an HTTP GET request can be added easily.

   This plugin adds 2 extra fields to the compose page that let a user add a custom header and header value to the outgoing message.

This plugin adds a custom reply-to field to the compose page that will override the profiles reply-to value for the current message.

   This plugin allows users to move, flag, or delete messages in a folder based on a pre-made set of rules. It has a rule management page and can be set to auto-filter the inbox. 

   This is an example plugin that does not really do very much but has lots of comments to explain how the plugin system works.

   This plugin replaces the HTML textarea on the compose page with an instance of the tinyMCE WYSIWYG javascript HTML editor allowing users to send HTML formatted email. A text version is included with the outgoing message.

This plugin allows sites to setup different IMAP server back-ends that are dynamically selected based on the user's login name.

    This plugin adds javascript/AJAX based extended help message to the options page when mousing over an option's description.

    This is a simple plugin that replaces that interface notices and error messages with a javascript version that goes away after 3 seconds.

    This plugin affects the "Sign" button on the compose page. It uses javascript to fetch the signature then insert it into the message at the current cursor position.

   This plugin uses the plugin API's ability to supply addresses to the contacts dialog on the compose page by connecting to an LDAP server for addressbook information. It can be used as a template for other plugins that could incorporate addresses from a database or other source.

    This plugin provides sites with the ability to log various Hastymail events. It has a number of options to control where, what, and how often to log.

This plugin allows admins to setup an alias lookup for the username logged in with and the username used for IMAP communication. It supports storing the alias list in either Mysql, Postgres, or a flat file
This plugin improves the navigation of digest messages by displaying the subject/from/date of each digest part in a list below the main message headers and above the body on the message view.
    This plugin lets users tag messages with multiple keywords then navigate them across multiple folders
This plugin allows users to override the Sent folder when composing a message. If replying to a message one can also move the replied-to message to the custom Sent folder selection.
    This plugin is an RSS/ATOM feed reader with some neat features including caching, merging feeds and
content filter options.
   This plugin provides 2 options to play a sound file and/or pop open a notice window when a new message arrives
   This plugin lets users setup external accounts to fetch mail from and have that mail delivered to an IMAP folder
    This plugin adds support for displaying IMAP quota information. This is a beta plugin with limited testing
    This plugin adds the ability to select multiple messages in listings using shift-click
    This plugin adds a dedicated spam folder that can be quickly emptied
    This plugin adds a dialog to the bottom of the search page that makes it easy to re-run or edit previous searches
    This plugin adds the currently logged in username to the top of each page
This plugin provides support for downloading uuencoded attachments. The encoded content is replaced within the text part of the message with a note indicating a file was found and the attachment is listed in the message parts section of the page with a download link.

Installing Plugins

    Installing a plugin is simple. Unzip or untar the plugin code and place the resulting directory in hastymail2/plugins/. Then add the name of the plugin to the hastymail.conf file with a line like

plugin = plugin_name

The name of the plugin is also the name of the directory placed in hastymail2/plugins/ that contains the plugin code. Remember anytime you you change the hastymail.conf file you must rerun the installation script to create the hastymail.rc file that is actually used by the application. Users MUST logout and then back in before a newly installed plugin will be available for use. 


Creating a plugin

    Creating a plugin is not hard. The API defines the function names and filenames a plugin can use. The number of files and amount of code to build a plugin depends on how much the plugin is going to do. First lets review the basic steps then look at each in more detail, followed by some links to the full source documentation.

  1. Choose a plugin name
  2. Create the config.php file and in it define which hooks the plugin will use
  3. Create the additional required php files, which depends on the hooks used in step 2, and in those files create the required functions.
  4. Make your plugin functional with normal PHP inside the required files/functions.


1. Choose a plugin name

    Plugin names are used throughout the plugin code as a prefix for required function names. The plugin name is also the name of the directory in which the plugin code will be stored. For simplicity and consistency these names should be all lowercase and contain only a-z and underscore. Plugin names must be unique so select a simple but descriptive name for your plugin. Lets use a fictional plugin that we will name "foobar" as an example. All the code for this plugin would then reside in



2. Create a config.php file.

    In our example of creating a plugin named "foobar" we will be working in the "/hastymail2/plugins/foobar" directory. Here we create a file called config.php. This file is required for any active plugin. Here we define which hooks a plugin will use in the Hastymail code. There are 3 kinds of hooks. First lets look at a sample config.php file then examine the contents:


     $foobar_hooks = array(

    'work_hooks'        => array('update_settings', 'message_send'),
    'display_hooks'     => array('compose_options', 'compose_options_table'),
    'page_hook'         => false,


The only code in the config.php file should be an array of defined hooks the plugin will use. The array name should be:

$<plugin name>_hooks 

In the example the  array is named "$foobar_hooks" since our plugin name is "foobar". Hooks are broken down into 3 types: work hooks; display hooks; and the special "page hook".

  • Work Hooks
    This is a list of hooks that the plugin will use to do backend work, such as process the results of a form or make a database query. All the available work hooks are documented in /hastymail2/docs/plugin_work_hooks.txt. If no work hooks are required then 'work_hooks' can be left out of the hooks array or can be set to an empty list. If at least one work hook is defined in the config.php file then the plugin must have a work.php file in it's main directory, and for each work hook defined the work.php file must have a specific function named <plugin_name>_<work_hook_name>.

  • Display Hooks
    Like work hooks the display hooks part of the hooks array is a list of hooks the plugin will use. If any display hooks are used the plugin must have a display.php file which functions named after each hook.  A full list of all the available display hooks can be found in the source at /hastymail2/docs/plugins_display_hooks.txt

  • Page Hook
    Unlike the display and work hooks the page hook is set to either true or false (if not present it will be assumed to be false). The page hooks is a special hook that allows a plugin to have it's own complete pages within hastymail, where as the other hooks allow a plugin to do work or inject code into existing hastymail pages. If the page_hook value is set to true, the plugin must have a page.php file in it's main directory. This file must contain at least 2 functions, one named url_action_<plugin_name> and the other named print_<plugin_name>

In our example config.php file our plugin uses 2 work hooks, "update_settings" and "message_send". Therefore we will need to create a work.php file with at least 2 functions named "foobar_update_settings" and "foobar_message_send". The plugin also uses 2 display hooks, "compose_options" and "compose_options_table" so we must create a display.php file for our plugin with at least 2 functions named "foobar_compose_options" and "foobar_compose_options_table". Finally our plugin is not using the page hook option so we do not need a page.php file. You can create as many other files as you want for class or function definitions, but the files described above must be correctly named, and the functions associated with hooks must also be correctly named, otherwise your plugin will not work correctly.


3 Create the additional required php files.

    Our fictional plugin is going to need both a work.php file and a display.php file because it uses both work and display hooks. An example display.php file based on the config.php defined above would look something like:

<?php /* display.php */

function foobar_compose_options($tools) {
    /* plugin builds XHTML to return here */


function foobar_compose_options_table($tools) {
    /* plugin builds XHTML to reutrn here */


Note that the required function names are the work hook names from config.php with the plugin name as a prefix. Each of these functions should return a string of XHTML that will be output at this "hook point". For example anything the first function returns will be output at the "compose_options" display hook, which is located in the options section of the compose page. Display hooks should only return XHTML to be inserted, NOT echo or print anything. The default argument to these functions, $tools, is a special object that provides methods to your display functions to interact with hastymail internal data. In the source the /hastymail2/docs/plugins_display_hooks.txt file describes the location and name of all the display hooks, and /hastymail2/docs/plugins_tools.txt details all the methods available to plugins.

 A sample work.php file for our "foobar" plugin would look something like this:

<?php  /* work.php */

function foobar_ message_send($tools) {
    /* do some work here */

function foobar_update_settings($tools) {
     /* do some work here */


Like the display hook functions each of these is named <plugin_name>_<hook_name> and has a default argument of the $tools object.

Our foobar plugin example does not use the page hook, since it is set to false in the config.php, but if it did use the page hook it would need a page.php file with the following functions:

<?php /* page.php */

function url_action_foobar($tools, $get, $post) {
    /* do work here */

function print_foobar($result, $tools) {
    /* return XHTML output for the page here */


 The arguments and return values to these 2 special page hook functions are explained at the end of section 4.

4. Make your plugin do something!

    All the above steps setup a place for you to code your own logic and work with user input so while the foobar example plugin would "work" it does not do anything. by using the defined functions as a framework for the plugin code you can add functionality and new features to hastymail. Additional functions and include files are up to the plugin author to decide on. As long as the config.php file and any additionally required files are created and contain the correctly named functions you can add to the plugin code in any way you wish.

    Keep in mind there is an order of execution for plugin functions associated with hooks. Some hooks run on every page load and others only on specific pages.  Work hooks always run before any display hooks, and in the page.php file the url_action_<plugin_name> function runs before the print_<plugin_name> function. Display hooks for a page are executed top down, then left to right, in terms of the XHTML layout. So a plugin function using the "menu" display hook executes before a function using the "footer" display hook. Work hooks are more varied, and many only execute under special circumstances. For example the "send_message" work hook is only executed when "send" is clicked on the compose page and all the required fields are valid.

Lets expand our example "foobar" plugin. Imagine that we want to add a new option to the options page under the "general options" section, and we want this to be saved in the users settings when logged out. The first step is to determine the appropriate hook locations our plugin will use. Lets start with the display hook. In the display hooks reference file (hastymail2/docs/plugins_display_hooks.txt) we can look at all the display hooks available on the options page. To add to the general options section we can use the 'general_options_table' hook which is described like so:

 general_options_table   This hook outputs at the bottom of the general
                         options section. It is within a table so any output
                         should be a table row(s).

We add this to the 'display_hooks' list in our plugin's config.php file, then in the display.php file create a function named foobar_general_options_table. An example of this function for simple checkbox option could be:

function foobar_general_options_table($tools) {
    $custom = $tools->get_setting('setting_name');
    $data = '<tr><td class="opt_leftcol">This is our plugin option</td>
             <td><input type="checkbox" name="form_element_name" value="1" ';
    if ($custom) {
        $data .= 'checked="checked" ';
    $data .= '/></td></tr>';
    return $data;

This is the first example of using the $tools object, which is crucial for working with hastymail. The hooks provide a framework for your plugin to work within, but the $tools object is the API that your plugin uses to interact with the software. The tools object is a collection of methods to perform tasks useful to a plugin. In the example we use the get_setting() method to grab our custom setting from hastymail, which is called  'setting_name' in this example. This method returns false if the setting does not exist. We use this in the variable $custom to determine if the checkbox should be checked or unchecked.

    Now we need a corresponding work hook to tell hastymail to store this value in the user settings. The hook we want for this is called "update_settings" (all work hooks are listed in hastymail/docs/plugins_work_hooks.txt). In our work.php file we create a function named foobar_update_settings such as the following:

function foobar_update_settings($tools) {
    if (isset($_POST['form_element_name']) && $_POST['form_element_name']) {
       $tools->save_options_page_setting('setting_name', 1);
    else {
        $tools->save_options_page_setting('setting_name', 0);


 This hook is executed when a user updates there settings and uses another $tools method called save_options_page_setting(). This is a special tools method that can only be used from the "update_settings" work hook function. Some $tools methods are limited to certain hooks, other can be run from only work or display hooks and some from any hook. All methods and the hooks they can be used from are documented in the source in hastymail/docs/plugins_tools.txt. In the example we use the save_options_page_setting() method to name our setting 'setting_name' and store either a 0 or 1. We decide what value to save by looking for the checkbox we named 'form_element_name' in the POST data.


There is a lot more documentation in the Hastymail2 source code, and we will be updating this page with the latest information just as soon as we can. If you have a question or comment please let us know with our contact page

Get Hastymail at SourceForge.net. Fast, secure and Free Open Source software downloads