Working With HTML

Top  Previous  Next

Tibbo programmable devices feature a built-in webserver.

The webserver supports server-side scripting. That is, you can include Tibbo BASIC or Tibbo C code within the HTML page and thus generate HTML content dynamically.

 

Here are two simple programs — one in BASIC and one in C — that demonstrate the dynamic HTML coding technique.

To fully understand this code you need to study the sockets (sock.) object.

For now, let me just direct your attention at how the BASIC or C code is included into the HTML file: the executable code is enclosed between <? and ?> escape sequences.

Everything outside of <? ?> is considered to be the regular HTML and is sent to the browser "as is".

 

When the embedded HTTP server receives a GET (or POST) request, it starts sending the requested HTML file.

The server reads the HTML file from top to bottom, and transmits its contents to the browser with no alteration — until it encounters a block of BASIC or C code.

Once the server reaches the code portion the VM begins executing this code.

 

It is not possible to define procedures within an HTML file.

This is because the entire file is considered to be a virtual procedure.

Moreover, having the code in two <? ?> fragments does not split it into two procedures (implications).

The fact that the entire code within each HTML file is considered to be a part of a single virtual procedure has implications on the way events are handled (reminder: there is a single queue for all events). The next event waiting in the event queue won't be executed until the end of the HTML procedure is reached. Just because the HTML procedure consists of two or more fragments does not mean that other events will somehow be able to get executed while the HTTP server outputs the static data between those fragments. Use the doevents statement if you want other event handlers to squeeze in while a long complicated HTML file is being generated and sent to the browser.

 

Note also how you can intermix the HTML and BASIC/C code.

In the example below there is a for-next loop that executes 10 times. Jammed in between is a line in HTML (<i> Foo </i>).

Because this line is positioned "within" the for-next loop it is passed through 10 times as well. This is a very powerful coding technique!

In other words, the file output is not always a simple top-to-bottom-and-stop affair. Your code may force the HTTP server to loop, branch, skip portions of file, and so on.

 

I already explained that in TIDE file extensions exist largely for your convenience. The actual type of a file is defined separately.

Add New File to Project, Add Existing File to Project, and Change File Type dialogs all offer a way to set the file type, and there are two selections for HTML files: HTML File (C) and HTML File (BASIC).

It is this selection that defines what language is expected inside the HTML file.

 

 

main.tbs (BASIC):

main.tc (C):

sub on_sys_init()
  net.ip="192.168.1.201" '<=== put a suitable IP address here
 
  dim f as byte
  for f=0 to 4 'allocate five sockets for the webserver
     sock.num=f
   
     sock.txbuffrq(1)
     sock.varbuffrq(1)
     sock.redir(PL_REDIR_SOCK0 + sock.num)
     sys.buffalloc
   
     sock.protocol=PL_SOCK_PROTOCOL_TCP
     sock.httpportlist="80"
     sock.inconmode=PL_SOCK_INCONMODE_ANY_IP_ANY_PORT
  next f
end sub

void on_sys_init(){
  net.ip="192.168.1.201"; //<=== put a suitable IP address here
 
  unsigned char f;
  for(f=0;f<5;f++){ //allocate five sockets for the webserver
     sock.num=f;
   
     sock.txbuffrq(1);
     sock.varbuffrq(1);
     sock.redir(PL_REDIR_SOCK0 + sock.num);
     sys.buffalloc();
   
     sock.protocol=PL_SOCK_PROTOCOL_TCP;
     sock.httpportlist="80";
     sock.inconmode=PL_SOCK_INCONMODE_ANY_IP_ANY_PORT;
  }
}

index.html (BASIC):

index.html (C):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><BODY>
BEGINNING OF OUTPUT<br>
 
<?
dim f as byte
for f = 0 to 9
?>
 
  <i> Foo </i>
 
<? next f ?>
   
<br>END OF OUTPUT<br>
</BODY></HTML>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><BODY>
BEGINNING OF OUTPUT<br>
 
<?
unsigned char f;
for(f=0;f<10;f++){
?>
 
  <i> Foo </i>
 
<? } ?>
   
<br>END OF OUTPUT<br>
</BODY></HTML>

 

The code above will send the following to your browser:

 

BEGINNING OF OUTPUT
foo foo foo foo foo foo foo foo foo foo
END OF OUTPUT

 

Here is another way to generate the same output. In this code example the for—next loop uses the programmatic way to print Foo ten times:

 

index.html (BASIC):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><BODY>
BEGINNING OF OUTPUT<br>
 
<?
dim f as byte
for f = 0 to 9
  sock.setdata("<i> Foo </i>")
  sock.send
next f
?>
   
<br>END OF OUTPUT<br>
</BODY></HTML>

 

Which coding style is better — the first one or the second one? There is no clear winner. The choice is yours!

 

Since there are no procedures inside an HTML file, all variables defined on the "HTML file level" have the global scope (this was covered in Scopes).

For example, the variable f in the example above is a global variable, even though it has but a local significance. This increases the overall memory required by the project.

If you define a variable inside the for—next loop, however, this variable will (of course) be a local, not a global variable.

The bottom line is that you can minimize the total memory required by your project by avoiding, whenever possible, declaring global variables within HTML files.

This can be achieved by enclosing complex HTML code within procedures and calling this procedures from HTML.

 

Further reading

There are many additional nuances that must be explained before you become proficient in creating web-enabled Tibbo BASIC and C applications.

For example, I did not explain how to receive and work with HTTP variables that are often supplied wiht GET and POST requests.

All this, and more, is explained in the socket (sock.) object's documentation. HTTP, specifically, is covered in the Using HTTP section.