Lasso Soft Inc. > Home

Lasso Apps

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.

  • Basic Concepts describes underlying the LassoApp system
  • Constructing a LassoApp describes how to construct a Lasso application
  • Packaging a LassoApp details how to process a LassoApp for distribution
  • Server Configuration shows how to tailor LassoApp serving

Basic Concepts

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

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 sub-nodes and those sub-nodes have zero or more sub-nodes beneath them. In the case of the root node, each of its sub-nodes represent the currently installed and running LassoApps.

Each node has a name and this name is used when locating a particular node within the tree. Nodes are addressed using standard forward-slash path syntax. The root node is named "lasso9", so it is accessed using the path /lasso9. The names of sub-nodes are appended to the path following a "/".

  /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.

Resources

Nodes not only serve as containers for sub-nodes, they also represent zero or more resources. These resources represent data files, such as images, css, or Lasso source files. Resource are used to produce an object which the LassoApp system must then transform into a format suitable for sending back to the client. Each resource is associated with a content type. This association is done either explicitly using the resource file's name, or by relying on the default content type, which is text/html.

Content Representations

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.

Purpose

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.

Constructing a LassoApp

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-development LassoApp. We aim to remove this restriction in a future release. File content can be modified without any such restrictions.

Serving Simple Content

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.

Serving Processed Content

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-going content type of processed content is very important. The content type determines any modifications or special handling that the data will receive before it is ultimately converted into a string of bytes and sent to the client. By default, the content type for a .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

Explicit Content Types

The out-going content type for a source file can be indicated in the file's name by placing the content type's file extension within square brackets. These files will be executed and the resulting value will be returned to the client using the indicated content type. The following shows some valid file names.

  /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  

Primary & Secondary Processing

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.

Example File users.lasso

/** contents of users.lasso **/

/* return an array of users */
return array(user('Stephen', 'J', 'Gould'), 
        user('Francis', 'Crick'), 
        user('Massimo', 'Pigliucci'))

Example File users[html].lasso

<!-- 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>'
  ^}

Example File users[xml].lasso

<!-- 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>

Customizing Installation

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.

Customizing Initialization

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. Re-defining a method can have an impact on performance, potentially leading to bottle-necks in your application. However, during application development, re-defining a method is a common occurance while source code is frequently modified. In this case, definitions can be placed in non-init files (i.e. a regular file) and included in the _init files using lassoapp_include. This lets the definition be loaded at startup while also letting the developer execute the file "manually" as it is updated during development.

Ignored Files

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:

  • Files or directories whose names begin with a period "."
  • Files or directories whose names begin with a hyphen "-"
  • Files or directories whose names begin with two underscores "__"

All other file names are permitted without restriction.

LassoApp Links

When creating a LassoApp, it is important to not hard-code paths to files within the app. Because the files within a LassoApp are not real files, Lasso Server will need to alter paths used in HTML links to be able to access the file data. The lassoapp_link method must be used for all intra-app file links.

To illustrate, consider a LassoApp which contained an image file called icon.png within an images sub-directory. In order to display the image, the lassoapp_link method would be used to alter the path, at runtime, to point to the true location of the file data. The following shows how lassoapp_link would be used to display the image. The example assumes that the link is being embedded in an HTML img tag.

<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.

LassoApp Includes

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'

Packaging a LassoApp

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.

A Directory

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-is. Of course, using this method, all the source code for the application is accessible by the user. Generally, this packaging method would be used by an in-house application where source code availability is not a concern and the LassoApp is installed manually on a server by copying the LassoApp directory.

A Zip File

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-zipping the file in-memory and serving its contents. LassoApps zipped in this manner provide easy download and distribution while still making the source-code for the application accessible. Zipped LassoApps must have a .zip file extension.

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-directories, while the "q" option simply indicates that zip should do its job quietly (by default, zip outputs verbose information on its activities).

A Compiled Binary

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-specific executable code, a binary compiled for OS X, for example, will not run on CentOS.

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.

Server Configuration

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. > Home

 

 

©LassoSoft Inc 2015 | Web Development by Treefrog Inc | PrivacyLegal terms and Shipping | Contact LassoSoft