USE CASE

In this simple example, I am not taking IP origin into account.

Implementation

Server Side Code
package Yote::Util::Counter;

use base 'Yote::AppRoot';

sub _init {
    # this is called only when the app is loaded for the first time.
    my $self = shift;

    # create a hidden field called _counts
    # fields starting with an underscore are not passed to the client side
    $self->set__counts( {} );
}

sub increment {
    my( $self, $data, $account, $env ) = @_;

    # not used, but this demonstrates how the IP address can be obtained
    my $ip = $env->{ REMOTE_ADDR }; 

    # data in this case is the name of the page we are tracking. It is the value
    #  of the argument passed into the javascript method call ( see below )
    my $count = $self->get__counts()->{$data} + 1; 
    $self->get__counts()->{$data} = $count; 
    return $count;
}


1;
Client Side Code
The following code snippet illustrates how the server side code can be invoked from the client side. Yote javascript depends on jquery being used.
<script src="/yote/js/jquery-latest.js"></script>
<script src="/yote/js/yote.js"></script>
<script src="/yote/js/yote.util.js"></script>
<script>
$().ready(function(){
 $.yote.init(); // must be called once before any objects are used.

 // fetches the app from the server side, as long as it can be found in the classpath.
 var page_counter = $.yote.fetch_app('Yote::Util::Counter');

 // increments and returns the count for the main page
 var count = page_counter.increment( Samples Page' );

 alert( 'The Main Page has been viewed ' + count +  ' times' );
});
</script>

Here is a very simple to do list app that only shows one thing to do at a time. The app has four use cases :

To start, we create a package that is going to be a Yote App. All Yote Apps descend from the Yote::AppRoot class.

Server Side Code

package Yote::Sample::SimpleTodo;

use base 'Yote::AppRoot';

sub _init_account {  
  # Gets called when a person uses this app for the first time.
  # This is useful to populate their account data container with initial values.

  my( $self, $account ) = @_;

  my $first = "Enter todo items";

  # create a list for the 'my_todos' field and add $first to it.
  $account->add_to_my_todos( $first ); 

  # attach the value of $first to the current_todo field.
  $account->set_current_todo( $first ); 
} #_init_account

sub add_item {
  # all yote subs called from the client side get passed in the following arguments.
  # data is the data given to the client javascript object call of the app. 
  #      In this case, it is a string that is the to do item.
  # account is the account for the currently logged in user. 
  #   The account is a container that stores items for this app that relate to
  #   who is logged in now.
  # environ is a hash of environment values given at the time of the request.
  #   Most often used from this is IP address to deteremine locale of the requester.
  my( $self, $data, $account, $environ ) = @_;

  # add the value to the 'my_todos' field's list but do not duplicate that value in the list.
  $account->add_once_to_my_todos( $data );
} #add_item

sub pick_random_todo {
  # picks a random to do item from the list.
  # returns the picked entry.
  my( $self, $data, $account, $environ ) = @_;
  
  my $todos = $account->get_my_todos();
  my $rand = $todos->[ rand( @$todos ) ];
  $self->set_current_todo( $rand );
  return $rand;
} #pick_random_todo

sub complete_current_item {
  # removes the current todo item and picks an other random one, returning it
  my( $self, $data, $account, $environ ) = @_;

  my $current = $account->get_current_todo();
  $account->remove_from_my_todos( $current );

  return $self->pick_random_todo( $data, $account, $environ );
} #complete_current_item

1;

The above completes the server side coding for this app.
The following is a javascript snippet that interacts with the app. We can use the parts of the snippet to create a real app page.

Client Side Code

  $.yote.init();  // connects to the server
  var todo_app = $.yote.fetch_app('Yote::Sample::SimpleTodo');
  alert( "The current todo item is " + todo_app.get_current_todo() );
  todo_app.add_item( "Find even more things to do" );
  todo_app.pick_random_todo();
  todo_app.complete_current_item();
  alert( "The current todo item is now " + todo_app.get_current_todo() );