Welcome Guest, Not a member yet? Register   Sign In
Superfish recursive library
#1

[eluser]Rob Pomeroy[/eluser]
A basic, nested Superfish menu lends itself to a class, for ease of creation and use. I've had a first stab at this. Note that jQuery is a prerequisite of Superfish.

The general principle is that of a tree. All nodes have the following:

- description
- url
- icon
- array of nodes (for sub menus)

It's nicely recursive. PHP's SPL RecursiveIterators were an obvious first choice for implementing this, but they didn't really work the way I'd hoped (possibly due to my ignorance, but as many have found, the SPL documentation isn't great).

Anyway, my approach leads to compact creation of Superfish menus. There's lots of room for improvement here, but here's my step-by-step approach. Note that I am historically a procedural programmer, so I've probably made some obvious OO gaffs (be gentle!):

1. Place superfish.js and hoverIntent.js (I removed the "jquery." prefix) at /js.

2. Place superfish.css at /css and customise as required.

3. Add the following to your <head> (changing "REPLACE" to "script" throughout) - I have this in my main template view file:
Code:
<link rel="stylesheet" type="text/css" media="screen" href="/css/superfish.css">
<REPLACE src="/js/hoverIntent.js" type="text/javascript"></REPLACE>
<REPLACE src="/js/superfish.js" type="text/javascript"></REPLACE>
<REPLACE type="text/javascript">
jQuery(function(){
  jQuery('ul.sf-menu').superfish({
    pathClass:   'navCurrent',
    speed:       'fast'
  });
});
</REPLACE>

4. Place the following at /system/application/libraries, called "Sf_menu":
Code:
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
  * Recursive class for dealing with Superfish menus
  */

class Sf_menu {

  /**
   * @var string Description of node (or null, for root of tree)
   */
  public $desc;

  /**
   * @var string URL of this node
   */
  public $url;

  /**
   * @var string URL of any icon being used in the menu (or null)
   */
  public $icon;

  /**
   * @var array Array containing Sf_menu nodes (empty if this has no children)
   */
  public $node_array;

  /**
   * Default Constructor
   */
  function __construct($desc=null, $url=null, $icon=null, $node_array=null) {
    $this->desc = $desc;
    $this->url  = $url;
    $this->icon = $icon;
    $this->node_array = $node_array;
  }


  function sf_print($css_class='sf-menu', $current_url='/') {
    if(isset($this->desc)) {
      echo "<li>\n";
      echo "<a >url==$current_url ? "class='current'" : '')."href='{$this->url}'>";
      if(isset($this->icon)) {
        echo "<img >icon}' style='width: 16px; height: 16px;' /> ";
      }
      echo "{$this->desc}</a>\n";
    }
    if(isset($this->node_array)) {
      echo "<ul class='$css_class'>\n";
      foreach($this->node_array as $node) {
        $node->sf_print($css_class, $current_url);
      }
      echo "</ul>\n";
    }
    if(isset($this->desc)) {
      echo "</li>\n";
    }
  }


}
?&gt;

5. Create the menu object like this (note that you probably shouldn't go more than 3 levels deep but I haven't created any code to prevent this):

Code:
$this->load->library('Sf_menu');
$root = new Sf_menu(
  null, null, null, array(
    new Sf_menu('Home', '/'),
    new Sf_menu('Backups', '/backup', null,
      array (
        new Sf_menu('Active Servers', '/backup/knutsServers/active'),
        new Sf_menu('Backup jobs', '/backup/knutsServers/jobs')
      )
    ),
    new Sf_menu('Email', '/email', null,
      array (
        new Sf_menu('Manage/Search Email Addresses','/email/menu/manage','/images/icons/users32.png'),
        new Sf_menu('Add Email Address','/email/menu/add','/images/icons/userplus32.png'),
        new Sf_menu('View Permitted Senders','/email/menu/senders','/images/icons/linedpapercheck32.png'),
        new Sf_menu('MailMapper','/email/menu/mailmapper','/images/icons/MailMapper.png')
      )
    ),
    new Sf_menu('EPCS', '/EPCS', null,
      array (
        new Sf_menu('Transfer VNC Installation File','/EPCS/menu/VNC'),
        new Sf_menu('Sysinfo','/EPCS',null,
          array (
            new Sf_menu('Display/Edit Sysinfo Alerts', '/EPCS/sysinfo/alerts'),
            new Sf_menu('Create New Sysinfo Alert', '/EPCS/sysinfo/newAlert'),
            new Sf_menu('Display/Edit Email Contacts', '/EPCS/sysinfo/contacts')
          )
        )
      )
    ),
    new Sf_menu('AD', '/ActiveDirectory', null,
      array (new Sf_menu('Display Users', '/ActiveDirectory/menu/users'))
    )
  )
);

6. Output (display) the menu like this:

Code:
$root->sf_print('sf-menu', $_SERVER['PATH_INFO']);

7. I added a CSS rule for a.current, to style the menu item for the current page differently:

Code:
a.current {
  background-color: #FCEDA1;
}

References:
Superfish: http://users.tpg.com.au/j_birch/plugins/superfish
HoverIntent: http://cherne.net/brian/resources/jquery.hoverIntent.js




Theme © iAndrew 2016 - Forum software by © MyBB