Lasso Server provides a means for bundling source files, HTML, images and other media types into a single deployable unit called a LassoApp. LassoApps are served over the web using Lasso Server's FastCGI interface. Lasso Server is required to run LassoApps. A single server can run multiple LassoApps at the same time.
The LassoApp system provides a light framework of features to make app development easier and to support a clean and maintainable design. This system also permits data in one app to be accessed and shared by another, allowing multiple apps to be used in concert.
Though LassoApps consist of regular files, those files are logically structured into a tree of nodes and resources. This node tree is constructed to match the file and directory structure inside the LassoApp bundle. Each node is associated with one or more resources. Resources are generally either Lasso pages, CSS, JavaScript, HTML/XML, image or other raw or binary data type.
Nodes represent the object structure behind a live LassoApp. This object structure is hierarchical, like a directory structure. The node tree begins with the root
node. That root node has a series of subroot
node, each of its sub
Each node has a name and this name is used when locating a particular node within the tree. Nodes are addressed using standard forward
/lasso9/LassoAppName/resourceName
/lasso9/AddressBook/groups/userX
The default web server configuration for Lasso Server will direct all paths beginning with "/lasso9" to Lasso Server. This is the default method for accessing LassoApps over the web, though the configuration can be modified for other situations or server requirements. See Server Configuration below.
Nodes not only serve as containers for sub
Each resource is associated with a content type and this content type is used when handling, or representing, the object produced by a resource. This handling occurs automatically when a node is requested via a web request and is formatted for output via HTTP. This handling is performed by a variety of content representation objects, each tailored for specific file extension, like .jpg or .js, and content type such as image/jpeg or application/javascript. New content representation objects can be added and existing representations can be tailored for specific application objects.
If there exists a content representation object for a given node resource and content type, then that resource can invoked and the resulting object is given to the content representation object for transformation or special handling.
To illustrate, consider a resource such as a PNG image file, which comes from a static unchanging .png file within a LassoApp. After the LassoApp is bundled for deployment, that image file may not actually exist on disk, being instead contained within the LassoApp in a specialized format. Given the resource's PNG content type, the system chooses the appropriate content representation object. In turn, that object sets an Expires header for that web request, improving application performance by preventing future redundant image requests. The content representation object does not have to modify the object data, and in this case with PNGs, sets a HTTP header but returns back the unaltered binary image data.
Another example would be a node resource which produces a "user" object, containing a first name, last name, etc. A content representation can be added which handles that particular object type and formats it for display as HTML. Another content representation can be added which formats it for sending back as JSON data, while another can be added to convert it to the vCard format.
This node/resource/content representation system permits the logic for producing a particular application object, such as "user" or a set of database result rows, to be divorced from its display. It also allows application objects to be represented in a variety of manners, and for those representations to be modified, without having to extend the application objects themselves.
Additionally, the system is unobtrusive, permitting the developer to utilize their own methodologies and frameworks while still taking advantage of the LassoApp system in pieces or as a whole.
All LassoApps reside as either a file or a directory located within the LassoApps folder. The LassoApps folder is located within the current Lasso home. See the Setup Guide for details on Lasso home directories.
LassoApps begin as a directory named according to the application. This directory contains all of the files for the application. Before deployment, this directory is processed into the desired format. However, Lasso Server will happily serve a plain LassoApp directory as long as it is placed in the proper location. This means that an application can be deployed as a regular directory of files and also that a developer needn't take any special steps transitioning between developing and testing an application.
While the above is generally true, it is currently required to restart Lasso Server when ADDING or REMOVING files from an in
Serving simple content such as images, or raw text and HTML is as simple as putting the file into the LassoApp root directory. As long as the file has the appropriate file suffix (e.g. .jpg, .txt, .html) then it will be served as expected. Files with a suffix other than .lasso
, .lasso9
or .inc
will be served as plain data, meaning they will not be parsed, compiled and executed by Lasso Server.
Processed content is any data produced programmatically by executing .lasso
source code files. Such data can be generated wholly by Lasso code, or partially, by embedding Lasso code in HTML or other types of templates. This type of content must reside in a file with a suffix of .lasso
, .lasso9
or .inc
.
The out.lasso
file is text/html. Lasso Server will automatically set the outgoing content type accordingly. A file using the default content type can be accessed given a matching url with either no suffix, a .html
suffix or a .lasso
suffix. For example, a file in an address book type application might be named as follows.
/AddressBook/users.lasso
Assuming the standard Lasso Server web server configuration, that file could be accessed with the following urls and the content would be served as text/html.
http://localhost/lasso9/AddressBook/users
http://localhost/lasso9/AddressBook/users.lasso
http://localhost/lasso9/AddressBook/users.html
The out
/AddressBook/users[html].lasso
/AddressBook/users[xml].lasso
/AddressBook/users[rss].lasso
The files shown above will expose the following urls.
http://localhost/lasso9/AddressBook/users.html
http://localhost/lasso9/AddressBook/users.xml
http://localhost/lasso9/AddressBook/users.rss
Explicit content types can be used in concert with a similarly named regular .lasso
file. In this situation, first the primary file is executed and then its value is made available to the secondary file as it is executed. The primary file is always executed. Only the secondary file which corresponds to the requested content type is executed.
/AddressBook/users.lasso primary content
/AddressBook/users[html].lasso secondary
/AddressBook/users[xml].lasso secondary
/AddressBook/users[rss].lasso secondary
Given the files shown above, if the url http://localhost/lasso9/AddressBook/users.html
was accessed, first the file users.lasso
would be executed, then the file users[html].lasso
would be executed. The value produced by the first would be made available to the second. This technique is used to separate the object produced by the primary file from its display, which is handled by the secondary file.
In this scenario, the file users.lasso
might return an array of all the users in the address book. That list of users might need to be presented to the client in a variety of formats: HTML, XML or RSS. The primary file users.lasso
is concerned only with producing the array of users. The secondary files each handle converting that array into the desired format.
Since primary files usually return structured data, it is generally required to return the value using a return
statement. However, primary files which simply need to return string data can use the
The following examples show a series of files that produce and format a list of users for both HTML and XML display. The list is generated first by the user.lasso file, then that list is processed by the user[html].lasso and users[xml].lasso files.
/** contents of users.lasso **/ /* return an array of users */ return array(user('Stephen', 'J', 'Gould'), user('Francis', 'Crick'), user('Massimo', 'Pigliucci'))
<!-- content of users[html].lasso --> <html> <title>Users List</title> <body> <table> <tr><th>First Name</th><th>Middle Name</th><th>Last Name</th></tr> [ // the primary value is given to us as the first parameter local(usersAry = #1) // start outputting HTML for each user with user in #usersAry do {^ '<tr><td>' + #user->firstName + '</td> <td>' + #user->middleName + '</td> <td>' + #user->lastName + '</td> </tr>' ^}
<!-- content of users[xml].lasso -->
<userslist>
[
// the primary value is given to us as the first parameter
local(usersAry = #1)
// start outputting XML for each user
with user in #usersAry
do {^
'<user><firstname>' + #user->firstName + '</firstname>
<middlename>' + #user->middleName + '</middlename>
<lastname>' + #user->lastName + '</lastname>
</user>'
^}
]
</userslist>
One or more specially named files can be placed in the root level of a LassoApp directory that will be executed the first time a LassoApp is loaded into Lasso Server. These files are named beginning with _install. followed by any additional naming characters and ending with a .lasso suffix. The simplest install file could be named _install.lasso
. For example, an install file that performed a specific task, such as creating database required by the app, could be named _install.create_dbs.lasso
.
Lasso Server will record the first time a particular install file is run. That file will not be executed again. Only install files at the root of the LassoApp are executed.
LassoApps can contain a special set of files that are executed every time the LassoApp is loaded. This loading occurs whenever Lasso Server starts up. These files are named beginning with _init. followed by any additional naming characters and ending with .lasso. _init.lasso
is the simplest valid init file name. Only initialization files at the root of the LassoApp are executed.
Initialization files are used to define all of the types, traits and methods used within the application. This includes the definition of thread types, which can be used to synchronize aspects of the application, hold globally shared data, or perform periodic tasks.
During the normal operation of an application, definitions should be avoided. Have them located only in _init files. Relassoapp_include
. This lets the definition be loaded at startup while also letting the developer execute the file "manually" as it is updated during development.
When serving a LassoApp, Lasso Server will ignore certain files based on their names. Though the files can be included in a LassoApp, Lasso will not serve or process the files. The following files will be ignored:
All other file names are permitted without restriction.
When creating a LassoApp, it is important to not hard
To illustrate, consider a LassoApp which contained an image file called icon.png within an images sub
<img src="<?= lassoapp_link('/images/icon.png') ?>" />
The path which gets inserted into the HTML document will vary depending on the system's configuration, but the end result would be the same: the image would be displayed.
lassoapp_link must be used anytime a path to a file within the app is needed. Behind the scenes, Lasso Server will alter the path so that it points to the right location. lassoapp_link only operates on paths to files within the current LassoApp. That is, lassoapp_link does not work with paths to files in other LassoApps running on the same system.
It is possible to directly access, or include, a LassoApp node given it's path. This can be used to pull in file data within the current LassoApp as well as other LassoApps running on the system. This technique can be used to assemble a result page based on multiple files working on concert.
To include a LassoApp file, the lassoapp_include method is used. This method accepts one string parameter, which is the path to the file to include. This path does not need to be altered via the lassoapp_link method. However, the path should be a full path to the file and should include the name of the LassoApp which contains the file. Additionally, lassoapp_link takes content representations into account. Therefore, if the HTML representation of a file is desired, the file path should include the .html extension.
For example, a LassoApp result page could consist of pulling in two other LassoApp files. Earlier in this chapter, several files were described representing a users list. These files represented the users list in several formats, particularly XML and HTML. Combined with a groups list, an opening page from the hypothetical AddressBook LassoApp might look as follows.
<html> <title>Title</title> <body> Users list: <?= lassoapp_include('/AddressBook/users.html') ?> Groups list: <?= lassoapp_include('/AddressBook/groups.html') ?> </body> </html>
lassoapp_include can be used to pull in any of the content representations for a file, including the primary content. If the raw user list (as shown earlier in this chapter) were desired, the lassoapp_include method would be used, but the .lasso extension would be given in the file path instead of the .html extension, as in the example above. Because of this, the return type of the lassoapp_include method may vary. It may be plain string data, bytes data from such as an image, or any other type of object.
The following example includes the users list and assigns it to a variable. It then prints a message pertaining to how many users exist. This illustrates how the result of lassoapp_include is not just character data, but is whatever type of data the LassoApp file represents. In this case, it is an array.
local(usersList = lassoapp_include('/AddressBook/users.lasso'))
'There are: ' + #usersList->size + ' users'
A LassoApp can be packaged in one of three ways: as a directory of files, as a zipped directory and as a compiled platform specific binary. Each method has its own benefits. Developers can choose the packaging mechanism most suitable to their needs.
The first method is as a directory containing the application's files. This is the simplest method, requiring no extra work by the developer. The same directory used during development of the LassoApp can be moved to another Lasso server and run as
The second method is to zip the LassoApp directory. This produces a single .zip file that can be installed on a Lasso server. Lasso Server will handle un
Developers should ensure that a LassoApp directory is zipped properly. Specifically, Lasso requires that all of the files & folders inside the LassoApp directory be zipped and not the LassoApp directory itself. On UNIX platforms (OS X & Linux) the zip command line tool can be used to create zipped LassoApps. To accomplish this, a developer would cd into the LassoApp directory and issue the zip command. Assuming a LassoApp name of AddressBook, the following command would be used.
zip -qr ../AddressBook.zip *
The above would zip the files & folders within the AddressBook directory and create a file named AddressBook.zip at the same level as the AddressBook directory. The "r" option indicates to zip that it should recursively zip all sub
Using the lassoc tool, included with Lasso Server, a developer can compile a LassoApp directory into a single distributable file. LassoApps packaged in this manner will have the file extension .lassoapp. Packaging in this manner provides the greatest security for one's source code because the source code is not included in the package and is not recoverable by the end user.
Compiled binary LassoApps are platform specific. Because these LassoApps are compiled to native OS
Both the lassoc tool and the freely available GCC compiler tools are required to compile a binary LassoApp. Several steps are involved in this task. However, Lasso Server ships with a makefile which simplifies this process. To use this makefile, copy the file into the same location as the LassoApp directory. Then, on the command line, type:
make DirectoryName.lassoapp
Replace DirectoryName with the name of the LassoApp directory in the above command. The resulting file will have a .lassoapp extension and can be placed in the LassoApps directory. Lasso Server will load the LassoApp once it is restarted.
Although LassoApps are available through the path /lasso9/AppName, it is often desirable to dedicate a site to serving a single LassoApp. This can be accomplished by having the web server set an environment variable for Lasso to indicate which LassoApp the web site is serving. The environment variable is named LASSOSERVER_APP_PREFIX
. Its value should be the path to the root of the LassoApp. For example, if a site were dedicated to serving the Lasso Server Administration app, the value for the LASSOSERVER_APP_PREFIX variable would be: /lasso9/admin
. Having the variable set in this manner would cause all lassoapp_link
paths to be prefixed with /lasso9/admin
.
The LASSOSERVER_APP_PREFIX variable is used in concert with other web server configuration directives to provide transparent serving of a LassoApp. The following example for the Apache 2 web server illustrates how the Lasso Server Administration app would be served out of a virtual host named "admin.local".
<virtualhost :80=""> ServerName admin.local ScriptAliasMatch ^(.*)$ /lasso9/admin$1 RewriteEngine on RewriteRule ^(.*)$ - [E=LASSOSERVER_APP_PREFIX:/lasso9/admin] </virtualhost>
Consult your web server documentation for further information.
©LassoSoft Inc 2015 | Web Development by Treefrog Inc | Privacy | Legal terms and Shipping | Contact LassoSoft