Dynamic Navigation Menu

Most web applications feature a multi-page structure, with the common inclusion of a menu for streamlined navigation. This menu is typically situated at the top or side of each page, offering users easy access to various sections of the site. In more complex web applications, you may even find sub-menus, either drop-down lists or side sub-menus, typically created on the left side of the page. These sub-menus add a layer of depth, helping users navigate complex content hierarchies more efficiently.

One technology that provides a simple yet effective solution for creating modern, dynamic web applications is "Server Side HTML Includes" This technique allows for modularity in the web development process by enabling sections of HTML code to be reused across multiple pages. This reusable code could represent a webpage navigation bar, footer, or other common element. By using Server Side Includes, these components can be maintained in a single file and included wherever necessary, reducing repetition and enhancing maintainability.

Moreover, "Server Side HTML Includes" also supports templating, a powerful feature allowing developers to dynamically inject data into predefined HTML structures. This enables the generation of unique web pages based on dynamic content while still adhering to a consistent layout and design. Using templates facilitates the separation of an application's logic from its presentation, leading to cleaner and more organized code.

In this way, "Server Side HTML Includes" simplifies the construction of modern web applications and enhances the user experience through efficient navigation systems and dynamic content presentation. Whether you're building a simple website or a complex dashboard application, this technology offers robust tools for creating a flexible, user-friendly interface.

Download Example Source Code

Download example from GitHub

Note: The example also includes a seeded hash-based form authenticator, making the authentication secure even on a non-TLS connection.

Designing the Dynamic Navigation Menu

In the figure below, the left image shows a typical web page that is part of a web application. The text in yellow shows where header data, such as CSS and JavaScript, the navigation menu, and the main page content should be located. We will go into detail on how to create a menu later on in this tutorial. The image to the right in the figure below shows how this page can be split into three components and then dynamically re-assembled at runtime by using server-side include. The reason we want to split this page into a "header", the main content, and a "footer", is that the header and footer are almost identical for all pages. We can reuse the header and footer on all pages for the web application by splitting the page up, as shown below, thus simplifying coding by reducing repetitive work. We will also minimize the size of the web application since we do not have to duplicate common code for each webpage in the application. Instead, all webpages in the application perform a server-side include on the header and footer.

Dynamic Navigation Menu

Figure 1: Shows how a page can be split up into three components, where common website code goes into the header and footer.

Creating a server-side navigation menu (a simple dashboard) as shown in this tutorial, is easy. However, for a more solid foundation, check out the tutorial How to Build an Interactive Dashboard App.

How to design the menu

HTML and CSS provide several options when it comes to creating a menu and many of these options are based on HTML lists as shown below.

<div id="nav"> <ul> <li><a href="network.lsp">Network</a></li> <li><a href="security.lsp">Security</a></li> <li><a href="user.lsp">Users</a></li> <li><a href="admin.lsp">Admin</a></li> </ul> </div>

Figure 2: The HTML code for a menu and how the menu looks when CSS is not applied.

The Chrome browser includes an HTML element inspector that enables you to manipulate the CSS for the menu to the left. The HTML inspector makes it easy to understand the effects of the applied CSS. Right click the menu on the left using the Chrome browser and select "Inspect element" to bring up the HTML inspector. Then, for a non selected "a" element, uncheck the CSS for : linear-gradient and watch how the menu turns dull.

The menu does not look particularly attractive when Cascading Style Sheets (CSS) is not applied to it. The example below shows the same menu after applying CSS.

Figure 3: The menu from Figure 2 after applying CSS.

A complete explanation for how the CSS works for the above menu is beyond the scope of this tutorial, but a few things are worth noting. We used CSS3 for the above menu and most new browsers today can handle CSS3. The menu will also work in older browsers but will have a dull look. The menu does not include any images. The gradient color is managed by using CSS3. Clicking a menu button inverts the color gradient order and the button will appear pressed. You can find several online tools that can help you create CSS3 color gradients, and one such tool is the CSS Gradient Generator.

Dynamic header generation

We have so far showed you how to create a menu by using the HTML list element and styling it using CSS. The code for the menu in Figure 2 shows standard static HTML. We could have put this HTML into our header file that is to be included by all pages in our web application "as is", but the problem with this solution is that we would not see the selected (active) page visually in the menu. We want to have the selected page's menu button visually appear pressed. You can test this by clicking our test menu in Figure 3. The menu button you click should appear pressed. Having a pressed (selected) menu button for the active page makes it easier for the web application user to know what page is active. We mentioned above that the button appears pressed when we revert the gradient color order and this can easily be achieved by creating a class for this purpose in the CSS. This class can then be applied to the selected page button.

<li><a class="selected" href="network.lsp">Network</a></li>

Figure 4: The menu button appears pressed when the "selected" class is set for the anchor element.

We only want the “selected” class on the menu button for the currently active webpage, thus our only option is to dynamically create the HTML for the menu. The following code fragment shows how to create the <li> elements in the menu.

 1 local links={
 2    {'network.lsp','Network'},
 3    {'security.lsp','Security'},
 4    {'users.lsp','Users'},
 5    {'admin.lsp','Admin'}
 6 }
 7 for index,link in ipairs(links) do
 8    local isactive -- Set isactive to true or false
 9    response:write('<li><a href="',link[1],'"',
10                   isactive and ' class="selected"' or '',
11                   '>',link[2],'</a></li>')
12 end

Figure 5: Shows how to dynamically create the <li> elements in the menu.

Line 1 to 5 declares a two-dimensional Lua array and this array includes all links and page titles for the web application.

Line 7 iterates over the outer array. The iterator returns the index position and the inner array. We have four elements in our outer array so line 8 to 11 will execute four times. The inner array contains the link and the page title.

Line 8 must set the variable isactive to true if the current page matches the current element in the array we are looping over. We will later explain how this is done.

Line 9 to 11 dynamically creates the <li> elements in the menu. Notice that we add the class "selected" to the <li> element to make the menu button appear pressed if variable isactive is true.

The only part missing in the puzzle is how to set the isactive variable on line 8. To do this, we first need to look at one of the pages in our web application that includes the header. The following example shows the network.lsp page.

 1 <?lsp title="Network" response:include".header.lsp" ?>
 2 <h1>Network</h1>
 4 <?lsp response:include"footer.shtml" ?>

Figure 6: Shows the network.lsp page and how the LSP header file and the HTML footer file are included at runtime.

Notice the global variable assignment title="Network" on line 1 above. The Mako Server provides a short lived global environment and this environment is only active as long as the request is active. The global variable title will also be available when the .header.lsp file executes. The title is used on line 8 in figure 5 and the correct code for this line in Figure 5 is as follows:

 8 local isactive = title == link[2]

The variable isactive is set to true in .header.lsp If the title set in the parent page matches the current title in the array we are looping over. The short-lived environment allows the parent page to set a variable for the included page. The short-lived environment is explained in the main documentation. See the Command (Request/Response) Environmment for details.

We also use the global title variable when emitting the HTML title element in .header.lsp:


Notice that the .header.lsp file name starts with a dot. File names that start with a dot are hidden and cannot be accessed via a browser. The file is only visible to server-side code such as to function response:include. The HTML footer page uses the extension shtml; this file is only visible to server-side code. The difference between the header and the footer is that the header is an LSP page and is executed on the server, and the footer is just a static HTML file.

HTML Templates

The menu we designed in this tutorial would typically be part of a website theme. Designing your own theme (or dashboard app) can be challenging, especially if you are new to CSS. Our recommendation is to have a web designer create a template for your website. A website template, such as a dashboard template, can easily be converted to a server side generated website by splitting the template into three components, as explained in this tutorial. A custom made template is recommended if you design a commercial product. You can also find many free templates on the Internet, but you must make sure you select a template than can easily be converted to a dynamic website. In other words, the template must include a menu that can be converted to a dynamically created server-side menu, as shown in this tutorial. In the next tutorial, we show how to use a free dashboard template as a starter for a more advanced dashboard application.


Many server technologies include support for server-side includes, including LSP, PHP, and Apache SSI. There are also many tools that can pre-process HTML with embedded "HTML includes" directives and create static HTML. The web site css-tricks.com provides a list of several tools that can be used. However, "server-side includes" are best for sites that include dynamically generated content, such as dashboard apps.

Creating a dashboard application using "server-side includes" is easy and a great solution for basic dashboard applications. Having said that, "server-side includes" has its limitations, and you may consider following the suggestions in the tutorial How to Build an Awesome Interactive Dashboard App.

Navigating Complexities? We've Got You!

Our extensive tutorials on embedded web servers and IoT are your roadmap to success. But every journey can have its challenges. Our seasoned experts are here to pave the way if you're pressed for time or hit a roadblock. At Real Time Logic, we equip you with knowledge and offer a helping hand when you need it most. Together, let's achieve the extraordinary!


OPC-UA Client & Server

An easy to use OPC UA stack that enables bridging of OPC-UA enabled industrial products with cloud services, IT, and HTML5 user interfaces.

Edge Controller

Edge Controller

Use our user programmable Edge-Controller as a tool to accelerate development of the next generation industrial edge products and to facilitate rapid IoT and IIoT development.

On-Premises IoT

On-Premises IoT Platform

Learn how to use the Barracuda App Server as your On-Premises IoT Foundation.

Embedded Web Server

Barracuda Embedded Web Server

The compact Web Server C library is included in the Barracuda App Server protocol suite but can also be used standalone.

WebSocket Server

Microcontroller Friendly

The tiny Minnow Server enables modern web server user interfaces to be used as the graphical front end for tiny microcontrollers. Make sure to check out the reference design and the Minnow Server design guide.

WebDAV Server

Network File System

Why use FTP when you can use your device as a secure network drive.

HTTP Client

Secure HTTP Client Library

PikeHTTP is a compact and secure HTTP client C library that greatly simplifies the design of HTTP/REST style apps in C or C++.

WebSocket Client

Microcontroller Friendly

The embedded WebSocket C library lets developers design tiny and secure IoT applications based on the WebSocket protocol.

SMTP Client

Secure Embedded SMTP Library

Send alarms and other notifications from any microcontroller powered product.

Crypto Library

RayCrypto C Library

The RayCrypto engine is an extremely small and fast embedded crypto library designed specifically for embedded resource-constrained devices.

Embedded PKI Service

Automatic SSL Certificate Management for Devices

Real Time Logic's SharkTrust™ service is an automatic Public Key Infrastructure (PKI) solution for products containing an Embedded Web Server.


Modbus TCP client

The Modbus client enables bridging of Modbus enabled industrial products with modern IoT devices and HTML5 powered HMIs.

Posted in Tutorials by bd