Sie sind auf Seite 1von 8

Tntnet quick start

Authors: Tommi Mkitalo, Andreas Welchlin

This quick start includes:


how to install tntnet build and run your first application explanation of this first application further readings !I"

Tntnet is developped and tested with linux. It is known to run on Sun Solaris, IB and freeBS#.

Installation
$or installing Tntnet you need to install cxxtools before. %ou find cxxtools on the tntnet ho&epage http:''www.tntnet.org'download.h&s and install it with:
tar xzf cxxtools-2.0.tar.gz cd cxxtools-2.0 ./configure make su -c 'make install'

Sa&e installation(procedure with tntnet. Install it with:


tar xzf tntnet-2.0.tar.gz cd tntnet-2.0 ./configure make su -c 'make install'

)ow you have a working Tntnet(*nviron&ent.

How to create your first webapplication


To create a webapplication it is necessary to create so&e initial pro+ectfiles. This is achieved by entering: tntnet(config ((pro+ect,&yfirstpro+ect This creates:

a directory -&yfirstpro+ect. a source(file -&yfirstpro+ect.ecpp. containing your application a configurationfile -tntnet.conf.

a property(file for logging(configuration -tntnet.properties. a akefile

To build the application change to the new directory and execute /&ake-. To run the application enter /tntnet (c tntnet.conf-. )ow you can start your 0ebbrowser and navigate to http:''localhost:1222'&yfirstpro+ect. %ou can see the result of your first running tntnet(application, which prints the na&e of the application.

What have we done?


The sourcefile &yfirstpro+ect.ecpp has been translated to c33. This c33 progra&& was used to build a shared library which contains the whole webapplication. ! tntnet(webapplication is a si&ple web(page with special tags like <$ ... $>. The ecppc(co&piler creates a c33(sourcefile and a headerfile with the sa&e basena&e. They include a class, which has also the sa&e na&ed as the file. %ou can look into the generated code, if you want and so&eti&es it is useful to read it for further understanding of tntnet(applications. If the c33(co&piler has proble&s with your application it is also the best choice to look into the generated code. 4lease keep in &ind that the linenu&bers which are printed by the c33(co&piler on errors correspond to the generated cpp(file. They are not the linenu&bers of your ecpp(source. The tags <$ ... $> include a c33(expression. The result of the expression is printed into the resulting page, when the page is requested 5on runti&e6. Therefore a std::ostream is used, so that the type of the result can be any ob+ect, which has an outputoperator operator<<(ostream&, T) defined. The configurationfile /tntnet.conf- has 7 configurationvariables. - Listen. configures the 5local6 I4(adress and tcp(port, where tntnet will listen for inco&ing requests. If no port is configured, the default is 12, which is nor&ally only possible when tntnet runs with root privileges. The variable -PropertyFile. tells tntnet, where to find the logging(configuration. The entry -MapUrl. is the &ost i&portant one. It tells tntnet what to do with inco&ing requests. 0ithout this entry, tntnet answeres every request with / http-error 404 not found. -MapUrl. &aps the url ( which is sent fro& a webbrowser ( to a tntnet( co&ponent. ! co&ponent is the piece of code, which is nor&ally generated by the ecpp(co&piler 5ecppc6. That8s what we did obove with &yfirstpro+ect.ecpp. 9o&ponents are identified by their 5class(6na&e and the shared library which contains this class. 0e na&ed our class

-&yfirstpro+ect. and our shared library -&yfirstpro+ect.so.. The co&ponent(identifier is then &yfirstpro+ect:&yfirstpro+ect . So - ap;rl. tells tntnet to call this co&ponent, when the url 'test.ht&l is requested.

How to add an image to your webapplication


! nice webapplication is colorfull and has so&e i&ages. <et8s add one. 9reate or fetch so&e pictures. Say you have a picture -picture.jpg. 4ut it into your working(directory. odify your ht&l(page -&yfirstpro+ect .ecpp. to show an i&age, first:
<html> <head> <title>ecpp-application myfirstproject</title> </head> < ody> <h!>myfirstproject</h!> <img src"#picture.jpg#> </ ody> </html>

)ext we co&pile the &odified webpage including the picture and link everything together. 0e need to tell the ecpp(co&piler 5 ecppc), that the picture is a binary file and which &i&e(type to generate. The flag (b tells ecppc not to look for tags like =>...>?. The co&ponent needs to tell the browser the &i&e(type which is -i&age'+pg. for your picture. The option -m is used to tell ecppc the &i&e(type. The picture will be co&piled into the co&ponent.
ecppc myfirstproject.ecpp g$$ -c -f%&' myfirstproject.cpp ecppc - -m image/jpeg picture.jpg g$$ -c -f%&' picture.cpp g$$ -o myfirstproject.so -shared myfirstproject.o picture.o -lecpp

But you can co&pile this easier by editing the generated


myfirstproject.so( myfirstproject.o

akefile and change the line:

to:
myfirstproject.so( myfirstproject.o picture.o

Before tntnet is started it is necessary to extend our configuration. Tntnet needs to know, that -picture.+pg. is found in the shared library -&yfirstpro+ect.so.. @ur new tntnet.conf looks like this:
)ap*rl /myfirstproject.html myfirstproject+myfirstproject

)ap*rl /picture.jpg picture+myfirstproject ,isten 0.0.0.0 -000 %roperty.ile tntnet.properties

)ow we start our &odified webapplication which is found in &yfirstpro+ect.so. Start tntnet like before and look at the &odified page including your i&age.

Generalise the configuration


0hen adding new pages to tntnet applications you have to ensure, that tntnet finds all the co&ponents. ;ntil now we have added each single co&ponent into tntnet.conf. There is a way to generalise it by using regular expressions. Aust &odify tntnet.conf like this:
)ap*rl //.01.html 2!+ myfirstproject )ap*rl //.01.jpg 2!+ myfirstproject ,isten 0.0.0.0 -000 %roperty.ile tntnet.properties

*very request will be checked by tntnet for &atching the first of all regular expressions which are defined. *very request with the suffix -.ht&l. or -.+pg. &akes tntnet to look for a co&ponent with the basena&e of the request. @k B there is one funny thing in our configuration: we get our picture with http:''localhost:1222'picture.ht&l. But tntnet does not care and nor does the browser.

Adding some C++-processing


Tntnet is &ade for writing web applications in 933. In the first exa&ple you saw one type of tag: <$...$>. This encloses a 933(expression, which is evaluated and printed on the resulting page. 0eb applications often need to do so&e processing like fetching data fro& a database or so&ething. The tags <{ ... }> enclose a 933(processing(block. This 933(code is executed, when a browser sends a request to fetch the page. !s a short for& you can put the character 8 8 into the first colu&n, which &eans, that the rest of the line is 933. 0e change our &yfirstpro+ect.ecpp to look like that:
<html> <head> <title>ecpp-application myfirstproject</title> </head> < ody> <h!>myfirstproject</h!> <3 // 4e ha5e a c$$- lock here dou le arg! " !.06 dou le arg2 " 7.06 dou le result " arg! $ arg26 8>

<p> <2 arg! 2> $ <2 arg2 2> " 9 if /result "" 0.01 3 nothing 9 8 else 3 <2 result 2> 9 8 </p> </ ody> </html>

9o&pile and run the application with:


make tntnet -c tntnet.conf

aybe we should call it calc.ecpp. Sounds like a better na&e for a little calculator. But to be a real calculator the user should be able to enter the values. There is a solution to this, so go on reading.

rocessing parameters
Ct&l has for&s for dealing with user input. $or&s send their values to a web application. The application needs to receive these values as para&eters. Tntnet supports this by using the ecpp(tags < ar!s> ... <" ar!s> which enclose a para&eter definition. <et8s start with a si&ple exa&ple:
<9args> namefield6 </9args> <html>< ody> <form> :hat's your name; <input type"#text# name"#namefield#> <input type"#su mit#> </form> <hr> <ello <2 namefield 2> </ ody></html>

0e put a variablena&e into an args(block. This defines a 933 variable of type std::strin!, which receives the value of the request para&eter. The first ti&e we call our application, there are no para&eters, so 8na&efield8 is an e&pty string. It is possible to define so&e an non(e&pty default value by changing the definition to:
<9args> namefield " =:orld>#6 </9args>

The first ti&e our application is called we get this fa&ous -Cello 0orldD.(output 5sorry that it took so long until you get it6.

)ow we know all instru&ents which are needed to create a slightly &ore functional calculator:
<9args> arg!6 arg26 </9args> <3 dou le 5!? 526 std((istringstream s!/arg!16 s! >> 5!6 std((istringstream s2/arg216 s2 >> 526 8> <html>< ody> <form> <input type"#text# name"#arg!# 5alue"#<2arg!2>#> $ <input type"#text# name"#arg2# 5alue"#<2arg22>#> 9 if /s! @@ s21 3 // if oth input-streams 4ere successful extracting 5alues " <2 5! $ 52 2> 9 8 </form> </ ody></html>

!odularise a web application


! great feature of tntnet is the possibility to create web pages by calling subroutines. %ou can create s&all ht&l(snippets and put the& together into one big page. $irst we create a &enu, so we create a file with the na&e &enu.ecpp:
<a <a <a <a href"#page!.html#>%age href"#page2.html#>%age href"#page7.html#>%age href"#pageA.html#>%age !</a>< 2</a>< 7</a>< A</a>< r> r> r> r>

)ow we create E pages page1.ecpp to page4.ecpp with so&e content. 0e want our &enu to be on each of our pages and the following code shows how the &enu( co&ponent is e&bedded. This is page F:
<html> < ody> <ta le> <tr> <td><@ =menu# @></td> <td><h!><ere is page !</h!></td> </tr> </ta le> </ ody> </html>

It should not be too hard to derive page G to E fro& here. @ur

akefile looks like this:

BCDE'FG"page!.o page2.o page7.o pageA.o menu.o ''"g$$ 'HH.,IJG"-f%&' 9.cpp 9.h( 9.ecpp ecppc 2< pages.so( 2/BCDE'FG1 g$$ -o 2+ -shared -ltntnet 2K

The configuration does not differ too &uch fro& the first exa&ple. Aust replace :&yfirstpro+ect with :pages, because our &odule na&e is now pages.so instead of &yfirstpro+ect.so. 9all -&ake. to co&pile it and as usual run the application with -tntnet (c tntnet.conf.. ! block <& ... &> contains a subco&ponent(call. In our si&ple case we have a nor&al 933(string(constant here. It can be also a variable or a functioncall, which returns a std::string.

"urther #eadings

tntnet users guide 5tntnet.pdf6 Tntnet configuration(reference 5tntnet(configuration.pdf6 The de&o progra&s in directory -sdk'de&os.

Das könnte Ihnen auch gefallen