The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Nes::Tutorial - Step by Step Nes Tutorial.

Install Nes

See: README file

Create Work Space for Tutorial

We assume you already have installed and enabled Nes for cgi-bin.

According to its distribution its web root directory could be in /var/www/html, /var/www/htdocs, etc.

For this tutorial we will assume that your web root directory is /var/www, change it throughout the tutorial if needed.

Create a working directory on your web root directory with the name nes_tutorial

    mkdir /var/www/nes_tutorial

The next step is to set this directory to make it possible executing Nes templates, is done with the shell command:

    set_nes_site

Configured:

    set_nes_site --dir_cfg=/var/www/nes_tutorial

With this we have created a file .htaccess with the configuration because Nes templates can execute in this directory.

The .nes.cfg file serve to configure Nes and also for your own Perl script or application. There is a value that needs to be changed, otherwise Nes release a warning:

    private_key

It is a password used to encrypt data such as cookies, so it is very important to give a value to private_key.

Create a file in /var/www/nes_tutorial with the name .nes.cfg, with the following content.

/var/www/nes_tutorial/.nes.cfg:

    private_key      = ChangeIt
    nes_tutorial_var = test variable

Change 'changeit' with the password you want. And with this nes_tutorial is ready to work.

Create first Nes Template

Nes templates have the extension .nhtml, any file with this extension, in nes_tutorial directory, will be treated as a Nes template.

Create a file named 'nes_01.nhtml' in 'nes_tutorial' with following contents:

    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
      <b>Hello Nes Tutorial</b>
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_01.nhtml

* Change 'yousite' with your domain or 'localhost'

'nes_01.nhtml' has no special feature, is only HTML. To include dynamic content, must tell Nes to run a script for this template.

We therefore need a Perl script. Creates a file named 'script_02.pl' in 'nes_tutorial' with the following contents:

    #!/usr/bin/perl

    use Nes;
    my $nes = Nes::Singleton->new();

    $nes->out();

    1; 

It is very important that Nes scripts returns 1, or displays an error. Another feature is that you do not need permission of execution to run the script, unless you want run the script and not the template.

Now we tell the template that our script is 'script_02.pl' with the Tag '{: NES 1.0 ( 'script_02.pl' ) :}'

Therefore we create a new template with the name 'nes_02.nhtml' and the following contents:

    {: NES 1.0 ( 'script_02.pl' ) :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
      <b>Hello Nes Tutorial</b>
      </body>
    </html>

When we do:

    http://yousite/nes_tutorial/nes_02.nhtml

Nes load and run script_02.pl

But our template continues without doing anything special, we will create another script with the name 'script_03.pl' with the following contents:

    #!/usr/bin/perl

    use Nes;
    my $nes = Nes::Singleton->new();

    my %tags;
    $tags{'var_hello'} = 'Hello Nes Tutorial';

    $nes->out(%tags);

    1;

And a new template with the name 'nes_03.nhtml' with the following content:

    {: NES 1.0 ( 'script_03.pl' ) :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
      <b>{: $ var_hello :}</b>
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_03.nhtml

In 'script_03.pl' we have defined the hash variable '%tags', with the name of variable for the template 'var_hello' and value 'Hello Nes Tutorial'. So when we included the Tag '{: $ var_hello :}' this has been replaced by the value 'Hello Nes Tutorial'

Includes and Object

The objects are a fundamental feature of Nes. With them we avoid rewrite the same code, even create Web applications without writing anything or very little Perl code.

Let's create an Nes Object. Create a file in 'nes_tutorial' with the name 'lucky_01.nhtml' and the following content:

    {: NES 1.0 ( 'lucky_01.pl' ) :}
    <html>
      <head>
        <title>Lucky</title>
      </head>
      <body>
        The lucky number is: <b>{: $ number :}</b>
      </body>
    </html>

And a script named 'lucky_01.pl' and the following content:

    #!/usr/bin/perl

    use Nes;
    my $nes = Nes::Singleton->new();

    my %nes_tags;
    $nes_tags{'number'} = int(rand(10));

    $nes->out(%nes_tags);

    1;

To show it works:

    http://yousite/nes_tutorial/lucky_01.nhtml

But this is nothing more than a template. We create an object so that every time we want a 'lucky number' in a Web not have to rewrite everything.

We created a template with the name 'lucky_02.nhtml' and the following content:

    {: NES 1.0 ( 'lucky_01.pl' ) :}
    {: $ number :}

To show it works create a template with the name 'lucky_test.nhtml' and the following content:

    {: NES 1.0 none :}
    <html>
      <head>
        <title>Lucky</title>
      </head>
      <body>
        The lucky number is: <b>{: include ('lucky_02.nhtml') :}</b>
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/lucky_test.nhtml

Also this works:

    http://yousite/nes_tutorial/lucky_02.nhtml

From that moment every time we want a 'lucky number' only we must included in our templates '{: include ( 'lucky_02.nhtml' ) :}'

The first line of the template 'lucky_test.nhtml' is {: NES 1.0 none :} means we have no Perl script to this template, but we want to use the Nes Tags.

But this is just a 'include' like any other, not Object might call, if not support parameters.

Let's create our final Object with the name 'lucky.nhtml' and the following content:

    {: NES 1.0 ( 'lucky.pl' ) :}
    {: # 

        lucky.nhtml

        Description:
           Shows a random number between min and max.

        Usage:
            {: include ( 'lucky.nhtml',
                          min,    {: # optional, default 0 :}
                          max     {: # optional, defautl 9 :}
                       )
            :}

        Example, random number between 1 and 5: 

            {: include ( 'lucky.nhtml',1,5 ) :}

    :}
    {: $ number :}

We've added a comment documenting their use.

And now the Perl script named 'lucky.pl' and content:

    #!/usr/bin/perl

    use Nes;
    my $nes = Nes::Singleton->new('lucky.nhtml');
    my $q   = $nes->{'query'}->{'q'};
    my $min = $q->{'lucky_param_1'} || 0;
    my $max = $q->{'lucky_param_2'} || 9;

    my %nes_tags;
    $nes_tags{'number'} = $min + int(rand($max+1-$min));

    $nes->out(%nes_tags);

    1;

With $nes->{'query'} we get the query object, $nes->{'query'}->{'q'} is equivalent to do:

    my $q = CGI->new;

In addition to GET or POST with Nes::Singleton->{'query'} we pick parameters of objects in the following format:

    objectname_param_number

For our example the name of the object is lucky.nhtml, the extension is ignored, then the first parameter:

    Nes::Singleton->{'query'}->{'q'}{'lucky_param_1'}

Now create a template to include and prove lucky, with the name 'template.nhtml' and the following content:

    {: NES 1.0 none :}
    <html>
      <head>
        <title>Template</title>
      </head>
      <body>
        The lucky number is: <b>{: include ('lucky.nhtml',10,20 ) :}</b>
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/template.nhtml

You can include lucky object in any Nes template, since he accepts parameters, you will not need modification.

In this example it is just a random number, but we can do object, from modules from CPAN, JavaScript, forms, Ajax, etc. and once created the object you can simply:

    {: include ( object, [parameter] ) :}

Nes Environment Variables

Now let's create a template to see the operation of Nes Environment Variables.

Create a file named 'nes_05.nhtml' in 'nes_tutorial' with following contents:

    {: NES 1.0 none :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
      <pre>
      Nes Version     : {: * nes_ver :}
      This Template   : {: * nes_this_file :}
      var in .nes.cfg : {: * cfg_nes_tutorial_var :} 
      HTTP_HOST       : {: * env_HTTP_HOST :}
      QUERY_STRING    : {: * env_QUERY_STRING :}
      name in GET     : {: * q_name :}
      </pre>
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_05.nhtml?name=value

Conditional Replacement

We can use expressions to the replacement condicial.

Create a file named 'nes_06.nhtml' in 'nes_tutorial' with following contents:

    {: NES 1.0 none :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
      {: ~ ( * q_var eq 'Hello' ) <b>Hello Tutorial</b> :}
      {: ~ ( * q_var == 1 )       <b>var is 1</b> :}
      {: ~ ( * q_var =~ /^N/ )    <b>{: * q_var :} begins with N</b> :}
      {: ~ ( * q_var =~ /lucky/ )
          {: include ('lucky.nhtml',1,10 ) :}
      :}
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_06.nhtml?var=Nes
    http://yousite/nes_tutorial/nes_06.nhtml?var=Hello
    http://yousite/nes_tutorial/nes_06.nhtml?var=1
    http://yousite/nes_tutorial/nes_06.nhtml?var=lucky

Data Tables

We can show the data tables.

Create a file named 'nes_07.nhtml' in 'nes_tutorial' with following contents:

    {: NES 1.0 ( 'script_07.pl' ) :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
        <table border="1">
        {: @ users
          <tr>
            <td> {: @$ users.name  :} </td>
            <td> {: @$ users.email :} </td>
          </tr>
        :}
        </table>
      </body>
    </html>

And create a file named 'script_07.pl' in 'nes_tutorial' with following contents:

    use Nes;
    my $nes = Nes::Singleton->new();

    my %tags;
    my $table = [ 
                    { 
                      name   => 'One',
                      email  => 'one@example.com',
                    },
                    { 
                      name   => 'Two',
                      email  => 'two@example.com',
                    },
                    { 
                      name   => 'Three',
                      email  => 'three@example.com',
                    }                                    
                ];

    $tags{'users'} = $table;

    $nes->out(%tags);

    1; 

To show it works:

    http://yousite/nes_tutorial/nes_07.nhtml

Plugins

You can add functionality using plugins to Nes, you can create your own or use by third parties.

Here we see how to use plugins.

The plugin can be executed before or after your script, depending on the requirements of the plugin.

Create a file named 'nes_08.nhtml' in 'nes_tutorial' with following contents:

    {: NES 1.0 ( 'none', '{: * cfg_plugin_top_dir :}/filter_demo.pl' ) :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
        Nes blink
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_08.nhtml

This plugin is a filter demonstration, simply replace the word 'Nes' for '<blink>Nes</blink>'

As it is a filter should be the end, as our template does not require script we put 'none'.

Forms

Create a file named 'nes_09.nhtml' in 'nes_tutorial' with following contents:

    {: NES 1.0 none :}
    <html>
      <head>
        <title>Nes Tutorial</title>
      </head>
      <body>
        <form method="POST" name="test0" action="">
            <table  border="0">
              <tr>
                <td align="right">
                User:
                </td>
                <td align="left">
                <input name="user" type="text"  
                size="12" value="{: * q_user :}"/>
                </td>
              </tr>
              <tr>
                <td align="right">
                Password:
                </td>
                <td align="left">
                <input name="password" type="password"  
                size="12" value="{: * q_password :}"/>
                </td>
              </tr>        
            </table>
            <input name="send" type="submit" value="Send" />
        </form> 
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_09.nhtml

The form recalls the value of the fields, because we have put field value in "value" 'value="{: * q_user :}"'

We will now add a captcha to the form.

Create a file named 'nes_10.nhtml' in 'nes_tutorial' with following contents: (this is big, copy/paste :-) no problem)

    {: NES 1.0 ('{: * cfg_plugin_top_dir :}/captcha.pl','none') :}
    <html>
      <head>
        <meta http-equiv="content-type" 
        content="text/html;charset=utf-8" />
        <title>Nes Tutorial</title>
      </head>
      <body>
      <form method="POST" name="test1" action="">
        {: # captcha parameters:
            name,type,digits,noise,size,sig,spc,expire,attempts 
        :}
        {: & captcha (test1,ascii,4,2,2,,,3m,5/1) 
         <table width="100%" border="0">
          <tr>
            <td align="right">User:</td>
            <td width="20%">
            <input name="user" type="text"  
            size="12" value="{: * q_user :}"/>
            </td>
            <td width="60%" rowspan="3">
    <pre>
    nes_captcha_plugin_test1_error_last : {: * nes_captcha_plugin_test1_error_last :} 
    nes_captcha_plugin_test1_error_fatal: {: * nes_captcha_plugin_test1_error_fatal :} 
    nes_captcha_plugin_test1_attempts   : {: * nes_captcha_plugin_test1_attempts :}
    nes_captcha_plugin_test1_is_ok      : {: * nes_captcha_plugin_test1_is_ok :}
    </pre>        
            </td>
          </tr>
          <tr>
            <td align="right">Password:</td>
            <td width="20%">
            <input name="password" type="password"  
            size="12" value="{: * q_password :}"/>        
            </td>
          </tr>
          <tr>
            <td align="right">{: & captcha_code :}</td>
            <td width="20%">
            Security code:<br>
            <input type="text" name="test1" size="8" /> 
            {: ~ *nes_captcha_plugin_test1_error_fatal 
               <blink>&#10038;</blink> <br> 
               <small>Incorrect code</small>
            :}        
            </td>
          </tr>
          <tr>
            <td align="right"></td>
            <td width="20%">
            <input name="send" type="submit" value="Send" />        
            </td>
          </tr>      
         </table>
        :}
      </form> 
      </body>
    </html>

To show it works:

    http://yousite/nes_tutorial/nes_10.nhtml

The Captcha Plugin required to be loaded before the script, that we've put before 'none'.

Captcha is a type 'ascii', to prevent some characters deform the captcha, we have 'meta' 'charset = utf-8'.

The captcha define some environment variables 'nes_captcha_plugin *', we've posted to the right, so you can check its value.

We have put a comment with the parameters of the captcha, you can try to change them and see the result.

The meaning of the parameters:

    name    : should be like the 'input' to the value of the Captcha
    type    : ascii
    digits  : digit number that shows the captcha
    noise   : noise level 0-9
    size    : font size
    sig     : foreground caracter
    spc     : background caracter
    expire  : expire time
    attempts: max attempts/time, 5/1 is 5 attempts in 1 minute

Where we want to show the captcha '{: & captcha_code :}'

Keep in mind that the variables 'nes_captcha_plugin *' have a block scope:

    {: * nes_captcha_plugin_test1_is_ok :}     <- ERROR, no value here
    {: & captcha (test1)
        ...
        {: * nes_captcha_plugin_test1_is_ok :} <- Ok
    :}

Since Perl, can verify Captcha:

    use Nes;
    my $captcha = nes_plugin->get( 'captcha_plugin', 'test1' );
    if ( $captcha->{'is_ok'} ) {
    ...

* nes_plugin is obsolete since version 1.03, the new plugin API is 'register' see: Nes::Plugin::API

Install Tutorial

You can install this tutorial with the following command:

    set_nes_site --from_exam=tutorial --to_exam=/full-path-to/root-www/Tutorial

* Change /full-path-to... for you particular path

AUTHOR

Skriptke: Enrique F. Castanon

VERSION

Version 1.03 April 2010

COPYRIGHT

Copyright (c) Enrique F. Castanon Barbero. All rights reserved.

LICENSE

This program is free software; you can redistribute it and/or modify it under the same terms and conditions as GNU Public License (GPL).

This means that you can, at your option, redistribute it and/or modify it under either the terms the GNU Public License (GPL), or under the Perl Artistic License.

See http://dev.perl.org/licenses/

DISCLAIMER

THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

Use of this software in any way or in any form, source or binary, is not allowed in any country which prohibits disclaimers of any implied warranties of merchantability or fitness for a particular purpose or any disclaimers of a similar nature.

IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION (INCLUDING, BUT NOT LIMITED TO, LOST PROFITS) EVEN IF I HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

SEE ALSO

Nes, Nes::Singleton, Nes::nes.cfg, Sample to use Nes; http://nes.sourceforge.net/