Creating custom navigation with MidCOM
One frequent question I see on #midgard is how to customize the default navigation options shipping with the MidCOM template site. In my opinion, there are two options: Either stick with the existing navigation styles and customize via CSS, or roll your own in PHP.
MidCOM provides a wonderful tool called Navigation Access Point (NAP) for site designers want to create their own custom navigation systems. It provides a PHP programming interface for listing the site structure. First, a bit of NAP terminology:
- Node
- Directory, or subtopic in the MidCOM site structure
- Leaf
- Page, or article under a node
- Children
- Both nodes and leaves under a given node
- Root node
- The first level node, or front page of MidCOM site
Constructing the navigation happens in two steps:
- Figure out where you are:
$current_node = $GLOBALS["midcom_site"]['nap']->get_current_node();
- List the children of the node:
$children = $GLOBALS["midcom_site"]['nap']->list_child_elements($current_node);
The $children array contains both nodes and leaves under the $current_node in NAP array format which you can then traverse:
foreach ($children as $child) {
As we're listing all child elements from the node instead of only nodes with list_nodes() or leaves with list_leaves() we next need to instantiate correct child type for display:
if ($child[MIDCOM_NAV_TYPE] == "node") { // This is a subtopic, instantiate it as node $node = $GLOBALS["midcom_site"]['nap']->get_node($child[MIDCOM_NAV_ID]); // Display the link in whatever way you want echo "<div><a href=\"".$node[MIDCOM_NAV_URL]."\">".$node[MIDCOM_NAV_NAME]);</a></div>\n"; // This is where you would place a call for listing children of the node } elseif ($child[MIDCOM_NAV_TYPE] == "leaf") { // This is an article (or event or some other document type) $leaf = $GLOBALS["midcom_site"]['nap']->get_leaf($child[MIDCOM_NAV_ID]); // Display the link echo "<div><a href=\"".$leaf[MIDCOM_NAV_URL]."\">".$leaf[MIDCOM_NAV_NAME]);</a></div>\n"; }
And there you have a very simple navigation listing of children under your current directory. You can easily modify this to list children of your root node by switching from get_current_node() method to get_root_node() method.
This example also doesn't check for possible content visibility settings. You can check for these using the MIDCOM_NAV_VISIBLE boolean in the node and leaf arrays.
In the other news, if you get error "Apache2(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80" when restarting Apache after addition of a new VirtualHost with datagard, the problem is that you have multiple "Listen 80" directives in your Apache configuration. Comment out the one in /etc/midgard/apache/httpd.conf.
Figured this one when troubleshooting with Robert Guerra from Canada.