Lesson 1. Navigation menu

Let's begin at the beginning, as they say. Let's assume you want to build a site. The first thing you'll need to figure out is how the information on the site should be organized, how many categories, sections, etc. should be there. All these questions arise at the very first stage, which is "The site's organization".

And what should the navigation be like? A good navigation system must meet many demands. It must be simple, easily recognizable, uniform, usable, quickly loadable, and it must indicate precisely where the user is at the moment. Moreover, the site shouldn't give out "Error 404" message, that is, none of the links must be "dead". If you have previously made sites, you have probably faced the problem of proper navigation.

Is there anyone who doesn't want to have a handy solution, which could automate the whole process-a solution, which would enable you to write a code once and for ever, leaving just one place to edit further on, and add as many sections as you wish?

Creating a menu which can guide a user safely through the site is the task we want to begin this manual with. Why this? Simply because a great amount of tags like:

<a href="some_page.html">

is hard to control. What if you have to add one more section? You will have a tough time changing every page with your own hands. And, keeping in mind that "to err is human," can you be sure that after such an update your visitors won't get "Error 404" messages? Here is the problem which can be easily solved by Parser.

The solution is simple: we create a function in Parser that will generate a necessary fragment of HTML. In Parser's terminology, functions are called methods. Wherever we need such a code, we will simply command to insert the navigation menu and the page containing the menu will be created. This needs just a few simple steurips:

1. All information about our links will be stored in one file, which will further allow us to make necessary changes in just one place. In the root directory of our future site we'll thus create file sections.cfg with the following content:

section_id

name
uri

1

Mainpage
/

2

News
/news/

3

Contacts
/contacts/

4

Prices
/price/

5

Your opinion
/gbook/


Here we use a so-called tab-delimited format, where table's columns are delimited with tab character and rows-with newline character. If you copy this table into a text editor, tab and new line characters will be just pasted by it automatically. However, if you are going to create and edit such tables manually, what you should keep in mind is that when dealing with tables, we ALWAYS use tab-delimited format.

2. In the same directory (root directory) we create file auto.p, where we'll store all the parts, which Parser will use further on to construct the site. AUTO means that these parts will always be available to Parser at any time and extension ".p"-as you have probably guessed already-means... yeah, right-in the flesh!

3. File auto.p will contain the following code:

@navigation[]
$sections[^table::load[sections.cfg]]
<table width="100%" border="1">
   <tr>
   ^sections.menu{
      <td align="center">
          <a href="
$sections.
uri"><nobr>$sections.name</nobr></a>
      </td>

   
}
   </tr>
</table>

Data stored in this file is what our navigation menu will be based on further.

All preliminary work is now complete. Now we should create the file where it all will appear (e.g. index.html) and tell Parser to insert the navigation menu. In Parser we use the term "to call method" and write it like this:


^navigation[]

Now we just open the HTML file in browser and see ready-to-serve navigation menu. From now on, we can put this magic
^navigation[] in any page and Parser will insert our menu there. The page will be generated "on-the-fly." Gotcha!

If you can see it in your browser-congratulations! You have just entered the world of dynamic sites. Very soon you will be able to use databases to generate your pages and do many other things.

Still, between the cup and the lip a morsel may slip, as they say. Let's now analyze what we've done to succeed. Look at the code in auto.p. Don't be scared if it still seems unclear. In just a few moments we'll clear up the matter. Look at the first line, which is


@navigation[]

It looks almost exactly like ^navigation[], which we put into our page (index.html) to get the menu. The only difference is the first character (@ instead of ^), but it is this character that makes all difference-by using it, we define a method to be called later. Starting a line in Parser with character @ we imply that we now define some block to be used later. The word following character
@ (navigation) will be the name of the new method. It is up to us to pick up a name for a method. We may call this method let_us_place_the_menu_here, but such a name will be harder to operate with. Still, if you wish, you may call it so.

It is vitally important to give simple and clear names. They must indicate clearly what the object will store and do. Don't fray nerves and don't waste time of yours or those, who may have to analyze your code later. Your names may be in any language, but you should keep uniformity-don't mix languages naming one object in German and another one-in Swahili...

Let's take the next line:


$sections[^table::load[sections.cfg]]

Here is the key line of our code. It is quite big, so let's examine it part by part. The line starts with
$ (dollar sign) and word 'sections' after it. This is the way we indicate a variable in Parser. It's easy, yet worth remembering: if you see $var in the text, that means you deal with a variable 'var'. A variable may contain any type of data: numbers, strings, tables, files, images, or even a piece of code. If we want to assign 'www.parser.ru' to variable $parser_home_url we should use structure like this: $parser_home_url[www.parser.ru]. Later on, we can access the variable's value by referring to it, that is, writing $parser_home_url wherever we need, and then the value, which is www.parser.ru, will be output.

In short:


$var[…]
-assign variable
$var
-retrieve value


A detailed explanation can be found in section "Variables".

In our case, variable
$sections will store the table taken from sections.cfg.

Any table in Parser is regarded as an independent object, with which only certain actions can be performed. For example, if object is a table, we can add or delete rows in it. As long as a variable can store any data, we should indicate that the value we assign is nothing else but table.

A lyrical digression:
Let's take a real world example. All vehicles can be roughly divided into certain major classes such as cars, trucks, vans, caterpillars, motorcycles, etc. Any vehicle is inevitably an object of a class. You can tell vehicles of one class from those of another, because all the vehicles belonging to a class have common characteristics, such as vehicle weight, maximum load weight, etc. Any vehicle can perform some actions like move, stand still, or break. Any vehicle has its own distinctive properties. And, what is most important, every vehicle must be CREATED, it cannot just appear by itself. When someone invents a new vehicle model, one knows what class the vehicle will belong to, what properties it will have, and what it will be able to do. It's just the same in Parser: every object belongs to a certain class. Every object of a class can be created by the constructor of this class and will inherit properties (fields) and methods (actions) common to all such objects.



Let's sum it up
Any object in Parser belongs to a certain class and has the fields and methods of this very class. To use this object, you must first create it with the class constructor. Learn this terminology by heart-it is what your work will be totally based on.

Let's get back to our code. We assigned the following value to variable
$sections:

^table::load[sections.cfg]

By this, we have created an object of class
table with constructor load. Common rule we use to create an object looks like the following:

^class::constructor[parameters]

A detailed description may be found in section
"Passing parameters".

As a parameter here, we passed the path to our file with the table.

Variable
$sections now contains the table with sections of our site. Parser regards it as an object of class table and knows precisely what actions can be performed with it. So far, we need only one method of the class-menu, which iterates through the table. We also need values from fields of the table itself. The syntax used to call a method of an object is:

^object.class_method[parameters]

To retrieve a value from object fields (as we deal with a definite table with the fields defined by ourselves) we use a construction:

$object.field

Now, that we know it all, we can easily see the meaning of the last part of our code:

<table width="100%" border="1">
   <tr>
   
^sections.
menu{
      <td align="center">
         <a href="
$sections.
uri"><nobr>$sections.name</nobr></a>
      </td>
   
}
   </tr>
</table>

We generate an HTML table, where each column will contain values taken from the fields of our table $sections: uri (section's uri) and name (section's name). We use method menu to iterate through the table and retrieve data stored in it. Thus, it doesn't actually matter how many sections we have-none of them will be lost or skipped. We are free to add or remove sections, or even change their order. All changes will be made only to file sections.cfg and the logic of the work will remain intact-simple but nice!

Let's summarize:

What have we done?
We have written our first piece of code in Parser and learnt how to create a navigation menu for any page of our site using data stored in a separate file.

What have we learnt?
We got a glimpse of conceptual definitions of the language (class, object, property, and method) as well as certain basic constructions of Parser.

What should we remember?
Parser is an object-oriented language. Every object belongs to a certain class, has its own properties and can use methods of the class it belongs to. To create an object one must use a constructor of the class.

Syntax of working with objects:


$variable[value]
Assigning a variable
$variable
Retrieving a variable's value
$variable[^class_name::constructor[parameters]]
Creating an object of class class_name and assigning it to variable
$variable.field_name
Retrieving the value of an object's field stored in variable
^variable.method[]
Calling an action (method of the class, which the object stored in the variable belongs to)


What's next?
We are going to improve our menu, because it has certain imperfections so far: it places a useless link (which leads to the page we see at the moment), has columns of different width. In our second lesson, we are going to solve these problems and add some useful extras.


Copyright © 1997–2021 Art. Lebedev Studio | http://www.artlebedev.com Last updated: 04.09.2008