Yote Platform Page
What Yote Is
Yote is a framework, a server, client templating engine and a set of libraries designed for functional
demos or small to moderate traffic web applications. It is implemented in perl and javascript and is
very rich in syntactic sugar. The core of yote is based around an object model of container objects
organized in a graph. Yote objects are easily and in most cases automatically created and are
automatically saved to an object graph store.
A yote program typically needs no schema or intervention with a database. Most of the programming is done
on the client side. It is designed to allow its design to be rapidly shaped. It is not (at this time) for
high volume, high performance websites. It is also designed to for security. A gatekeeper on the server
side enforces which user or client is allowed to edit or see what.
Example - a rolodex in 15 steps with only client side code.
The purpose of this example is to give a taste of Yote's tepmlating system. A searchable rolodex
is something that can be of immediately use. This also demonstrates basic installation and
configuration. YMMV and this setup was tested on a vanilla Ubuntu installation.
Design goals
Design a rolodex where all may edit, add and remove entries.
The entries should be paginated and searchable.
Installation and configuration
- Get Yote. The simplist way is to use cpan.
$> sudo cpan Yote
- Shut off any webservers running on port 80
- start yote
$> sudo yote_server
Yote will now ask setup questions. Use defaults for everything
except the root password, which has no default.
Create an app
- Open up the Yote Admin Page and log in with the root credentials you created.
The admin page is at http://localhost/admin.html
- Add an app. Give it the name 'Rolo'.
- Add an object with read and write permissions for all to the app. Call this rolodex.
The app object itself requires a root login to modify and we want all to be able to
use and modify the rolodex, so we must create an object with the loose permissions.
Write the App Front End
- Copy the app template file for editing
$> cp /opt/yote/html/app_template.html
/opt/yote/html/rolo.html
Edit /opt/yote/html/rolo.html with your favorite editor.
- Define the main template to use for the rolodex. Define this outside of the body, or use
the sample template script sections and change the template name.
<script type="text/template" class="yote_template_definition" template_name="RolodexMain">
<h2>Rolodex App</h2>
<DIV class="box">
<$@ Show_Rolodex Empty _.rolodex entries @$> <BR>
</DIV>
<DIV class="box">
<$$ New_Rolodex $$>
</DIV>
</script>
- <$$ templatename $$>
-
Fills in the named template in this spot.
The current context is copied and passed to the template being filled out. A context
is just a collection of variables that are relevant to the template creation and functions
called from it.
- <$@ listtemplatename emptytemplatename targetobject listname @$>
-
This construct is for displaying lists of things. The first parameter is the template to show
if the list has entries. The second is a template to show if there is nothing in the list.
The third parameter is what object the list is attached to and the fourth is the name of the list.
The default variable in the context of these templates will be the list specified.
The default parent in the context of these templates will be the target object.
- _.rolodex
-
One underscore character means the default variable of the context the template is filled with.
In this case, the default variable is the app itself. The dot notation specifies an object
attached to the first. In this case, the rolodex object was created in step 3 of
the Create an App section. The entries list attached to this will be the
default variable for the copy of the context passed to the Show_Rolodex and Empty templates.
- Use the main template in the body of the document.
<BODY>
<DIV class="yote_template side_panel" template="RolodexMain" default_variable="rolo_app">
</div>
</body>
The template RolodexMain will be filled in inside this div. It will be passed the registered
default variable called rolo_app.
- Inside the javascript block, define and register the app variable with the templating system.
var app = $.yote.fetch_app( 'Rolo' );
$.yote.util.register_item( 'rolo_app', app );
- Define a template to show if there is nothing in the collection of entries.
<script type="text/template" class="yote_template_definition" template_name="Empty">
No entries found.
</script>
- Create a template for the rolodex list to be displayed in. It will show up to 10 entries at a time.
<script type="text/template" class="yote_template_definition" template_name="Show_Rolodex">
<h3>Rolodex Entries</h3>
<$$$ var search_fields firstname lastname email $$$>
<$$ SearchList $$><BR>
<TABLE>
<TR> <TH>First Name</TH> <TH>Last Name</TH> <TH>Email</TH> <TH>Cell Number<> <TH>Homepage</TH> <TH>Delete</TH> </TR>
<@ Show_Rolodex_Entry 10 @>
</TABLE>
<$$ Paginator $$>
</script>
- <@ templatename maxnumbertoshow @>
-
This template will be filled up to 10 times. For each time, the context's default variable
will be a different list entry. In addition, this
- Paginator
-
This is an other template that is defined in /template/templates.html and included by default.
It expects the default variable to be a container ( list or hash ) object.
- <$$$ var varname value $$$>
-
Variables are assigned in this manner and are made available to the context of this template
and all templates called from it. In this case, search_fields is given the value
'firstname lastname email' and will be used by the SearchList template to determine how to
search.
- SearchList
-
This is a template that is defined in /template/templates.html and included by default.
It expects the default variable to be a list object and expects the search_fields variable
to be defined.
- Create the template to show a single entry. This template is going to be filled in up to 10 times.
and appears in the middle of a table, so it should be a table row in this case.
<script type="text/template" class="yote_template_definition" template_name="Show_Rolodex_Entry">
<TR>
<TD> <$ edit _ firstname $> </TD>
<TD> <$ edit _ lastname $> </TD>
<TD> <$ edit _ email $> </TD>
<TD> <$ edit _ cell $> </TD>
<TD> <$ edit _ homepage $> </TD>
<TD> <$ list_remove_button _ entries $> </TD>
</TR>
</script>
- <$ edit object field $>
-
This creates an edit box that a user can click on and change the value of field on the object.
The default variable _ in this case is the list entry that this template was called
to fill for.
- <$ list_remove_button objecttoremove listnameinitsparent $>
-
This removes the object in question from the list named that is attached to the context's default parent.
The default parent was set in the <$@ .. @$> template call.
- Make a template to add new entries.
<script type="text/template" class="yote_template_definition" template_name="New_Rolodex">
<$$$ new firstname <input type="text" placeholder="First Name" > $$$> <BR>
<$$$ new lastname <input type="text" placeholder="Last Name" > $$$> <BR>
<$$$ new email <input type="email" placeholder="Email Address"> $$$> <BR>
<$$$ new cell <input type="phone" placeholder="Cellphone" > $$$> <BR>
<$$$ new homepage <input type="text" placeholder="Homepage URL" > $$$> <BR>
<$ newbutton _.rolodex entries New Rolodex Entry $>
</script>
- <$$$ new varname controldefinition $$$>
-
Add a variable to a part of the context that is set aside for new object variables. The variable
is bound to the value of the control specified here, which is filled into the template. An id
is automagically assigned to the control and registered in the context.
- <$ newbutton object containerinobject buttontext $$>
-
Newbutton creates a button that is bound to a function that creates a new object and adds
it to the container named that is part of the object given. It knows to look for the object
fields in the context that were defined with the new directive.
Now it is done. Toss in a little CSS and it looks like this. The boxes under the fields indicate that field is editable. When moused over and clicked, an edit field with an OK and Cancel button appears.
How Yote is Organized
Yote apps are composed of container objects that link together and all trace back a reference to
the root of the app. Likewise, the app roots all connect to a YoteRoot object, which is the primary
node of the object graph.
A running Yote server may have many aps and users. Each user has one set of credentials and a
separate account for each app that they user. The server also has a cron engine that runs commands
at specified times or periods.
Glossary
- Yote::Obj / javascript object.
-
This perl class defines basic Yote object. Nearly all other classes are subclasses of this.
Client end objects are proxies for the server side objects. All object methods called on the
client side are transparently executed on the back end.
- App
-
An app is a singleton object that is used to run the web application.
It has a unique name and can be obtained by calling
$.yote.fetch_app( appname );
.
An app by default can only be modified by a root account.
The app contains the following
- map of login ID to Account
- map of account handle to account
- information about the app url/domain
- settings for emails specific to this app
- settings for accounts ( such as do they need to be validated to be able to log in )
The app datastructure contains a list of user accounts that have signed on to the app.
The app is responsible for removing or creating a login and sending an optional validation request email.
It also provides password recovery feature. Even though the credentials for a login are app-wide,
one app may send out differently formatted emails for those functions.
- Login
-
Yote makes a distinction between a login and an account. The Login is a set of credentials a user
has for the Yote system. A login spans all accounts so one user has only one login.
It is the login which may have the root bit.
Any account connected to a login with the root bit is considered to also be a root account.
- Master Login
-
These credentials are defined in the Yote settings and may not be changed. This login cannot have its
root privileges revoked.
- Account
-
A user will have an account for every app that they use. An Account is a container for app specific data.
What is this data? It's anything the app wants it to be. Yote's data structures are free form and mutable.
- YoteRoot
-
Objects in Yote are stored in a graph. The first node of that graph, the entry point of that graph,
is the YoteRoot. All logins and apps are attached to this object. A cron system is attached to this
object. This object provides methods to enable and disable accounts.