4.9 Main Navigation Bar

Adding the horizontal navigation bar will be a bit more difficult so we are going to create a new file for this task:

File lib/menus.cws:

site.main_menu = "TODO";

This script simply define a string which will store the main menu and will be included from lib/template.cws.

File lib/template.cws:

include ("menus.cws");

// rest of file skipped..

Now, later in the same file, we replace:

  <! Begin Main Menu >
  Main Menu
  <! End Main Menu >

with:

  <! Begin Main Menu >
  @@ site.main_menu @@
  <! End Main Menu >

Summarizing, every page will:

  1. define page content, a quotation and its author;

  2. include the template file.

Template file will in turn include other files defining complex elements like navigation bars.

I want to point your attention on the elegance of this approach: your pages aren't exposed to the complexity of navigation bars. Every page simply defines its content and demands everything else to other scripts.

Of course, we could define the navigation bar inside lib/template.cws instead of adding a new file to the project but it wouldn't be a good ide. We want lib/template.cws to define site layout without cluttering with the logic of navigation bars, banners etc.

Now, it's time to write a suitable lib/menus.cws file. How should the main menu look like? Let's have a look at the second HTML file created in Section 4.5 (we didn't use it as a template because it was too specific but we said it would be useful later). The main menu was:

  <! Begin Main Menu >
  <a href="animal_rights/index.html" class="menu">Animal Rights</a> |
  <a href="vegetarianism/index.html" class="menuactive">Vegetarianism</a> |
  <a href="vivisection/index.html" class="menu">Vivisection</a> |
  <a href="furs_leather/index.html" class="menu">Furs & Leather</a> |
  <a href="hunting/index.html" class="menu">Hunting</a> |
  <a href="entertainment/index.html" class="menu">Entertainment</a>
  <! End Main Menu >

This is the output we expect when our script is included from pages belonging to section Vegetarianism. To achieve this result we must provide our template:

First, let me create a new file inside directory lib/ called structure.cws. This file will define site's structure in form of arrays. At first glance, an array like the following should suffice our needs:

site.sections [] = {
  "vegetarianism",
  "vivisection",
  "furs_leather",
  "hunting",
  "entertainment"
}

However, every section needs at least two informations:

So, we define a multidimensional array: an array whose elements are themselves arrays.

File lib/structure.cws:

site.sections [ ] = {
  { "vegetarianism", "Vegetarianism"            }, 
  { "vivisection",   "Vivisection"              },
  { "furs_leather",  "Furs and Leather"         },
  { "hunting",       "Hunting"                  },
  { "entertainment", "Animals in Entertainment" }
};

Now, we have to include this file from template.cws:

File template.cws:

include ("structure.cws");
include ("menus.cws");

// rest of file skipped..

File structure.cws must be included before menu.cws since the former provides structure information needed by the latter.

Before we go on let me point your attention on a very important topic: we have just added a dependency in our project so we'll need to create a new makefile with cows-mkgen before updating pages with make.

To create the menu, we can loop over this array and, for each section:

Now, we have to locate the pages; an easy way would consist in defining a variable at the beginning of every page. As an example: section = "vegetarianism"; However, there is a smoother way to achieve our goal since this information is already present in every page thanks to the convention used to choose filenames. Page vegetarianism/hunger.html as an example belongs to section vegetarianism.

Cows provide the inputfile () function which returns the name of the processed file, and the tokenize () function, which splits strings into tokens delimited by a given string or character.

So, let's write the code; here it is: pure and simple.

File lib/menus.cws:

<cows>

// Locate page

file_name  = inputfile ();
tokens [ ] = tokenize (file_name, "/");
n_tokens   = length   (tokens []);

/* When this script is included from vegetarianism/hunger.cws
   array tokens [ ] will store the following values: 
   * vegetarianism
   * hunger.cws
   When this script is included from index.cws tokens [] will store 
   a single value: 
   * index.cws
*/

if (n_tokens == 1) 
{
  /* Home Page  */
  current_section = "";   
} 
else 
{
  current_section = tokens [0];   
}

// Create main menu

site.main_menu = '<a href="' + linkadjust ()
  + 'index.html">Home Page</a> | ';

i=1;

foreach (section [ ] in site.sections [ ]) 
{
  if (section [0] == current_section) 
  {
    site.main_menu += '<a href="' + linkadjust () + section [0] + 
        '/index.html" class="menuactive">' + section [1] + '</a>'; 
  } 
  else 
  {
    site.main_menu += '<a href="' + linkadjust () + section [0] + 
        '/index.html">' + section [1] + '</a>'; 
  }
  // Every item but the last will be followed by a vertical bar:
  if (i < length ( site.sections [])) 
  {
    site.main_menu += ' |\n';
    i++;
  }
}

</cows>

Now, we run cows-mkgen to update the Makefile (since we've added a new file to the project) and rebuild the site:

$ cows-mkgen
$ make
cows   index.cws index.html
cows   vegetarianism/suffering.cws vegetarianism/suffering.html
cows   vegetarianism/health.cws vegetarianism/health.html
cows   vegetarianism/hunger.cws vegetarianism/hunger.html
cows   vegetarianism/index.cws vegetarianism/index.html
cows   vegetarianism/act.cws vegetarianism/act.html

Let's have a look at the menus:

From file index.html

... beginning of file skipped

<! Begin Main Menu >
<a href="animal_rights/index.html" class="menu">Animal Rights</a> |
<a href="vegetarianism/index.html" class="menu">Vegetarianism</a> |
<a href="vivisection/index.html" class="menu">Vivisection</a> |
<a href="furs_leather/index.html" class="menu">Furs and Leather</a> |
<a href="hunting/index.html" class="menu">Hunting</a> |
<a href="entertainment/index.html" class="menu">Animals in Entertainment</a>
<! End Main Menu >

end of file skipped ...

From file vegetarianism/hunger.html

... beginning of file skipped

<! Begin Main Menu >
<a href="../animal_rights/index.html" class="menu">Animal Rights</a> |
<a href="../vegetarianism/index.html" class="menuactive">Vegetarianism</a> |
<a href="../vivisection/index.html" class="menu">Vivisection</a> |
<a href="../furs_leather/index.html" class="menu">Furs and Leather</a> |
<a href="../hunting/index.html" class="menu">Hunting</a> |
<a href="../entertainment/index.html" class="menu">Animals in Entertainment</a>
<! End Main Menu >

end of file skipped ...

This manual can be downloaded from http://www.g-cows.org/.