FlightPath.txt

Summary
FlightPath.txt
FlightPath OverviewMyna FlightPath is a Model-View-Controller(MVC) web application framework inspired by CakePHP, CFWheels and Ruby On Rails.
GlossaryTerms used when talking about Myna FlightPath Applications
Getting StartedTo create a FlightPath template, navigate to the Myna Administrator and select “Add/Update FlightPath App”, and enter a path and folder name, relative to the Myna web root.
FlightPath ConfigFlightPath configuration is stored in the “config” property of $application.
BehaviorsBehaviors are functions that are applied to the current object.
ElementsAn element file is a specialized view (see: Views) that is intended to contain a fragment of output (usually HTML) that can be used in a view
LayoutsA layout file is a specialized view (see: Views) that is intended to wrap content before sending it to the browser.
ModulesModules are self-contained FlightPath applications that can be embedded in other applications.
RoutesRoutes are URL patterns that can be mapped to controllers and actions.
ViewsView Templates are .ejs templates used to render the result of an action.

FlightPath Overview

Myna FlightPath is a Model-View-Controller(MVC) web application framework inspired by CakePHP, CFWheels and Ruby On Rails.

Before you begin

Myna FlightPath is an application template that implements much of the infrastructure web developers typically have to create to start working on a web application.  This allows you to write your business logic as plain JavaScript functions, your displays as EJS templates, and have your data objects automatically generated from the database, nearly eliminating the need to write SQL.

FlightPath Features

MVC frameworkStrong separation of data, business logic and display.Each of these can be manipulated independent of the others.
Automatic model generationIf your application has a single datasource, FlightPath will create models for that datasource automatically, just when needed.  FlightPath will also analyze foreign key relationships and create related models.  Data type constraints are also analyzed and become validators.  See: Model
URL “routes”It is possible with FlightPath to map virtually any URL to an action.  “appdir/book/get/12”, “appdir/mypage.html”, “appdir/index.sjs?controller=test&action=run” are all valid URLs.  An action can even have multiple routes assigned to it.
Ext.Direct supportFlightPath provides a builtin-in controller to handle Ext.Direct API calls.  See: Controller: Direct
Authentication and authorizationFlightPath comes with an optional permissions behavior that can secure individual controllers or whole applications.  See: Behavior: MynaAuth

Glossary

Terms used when talking about Myna FlightPath Applications

Terms

$flashGlobal temporary message store.  Intended for displaying messages to the user regardless of which action will be next loaded.  Used by $FP.redirectTo and the default Layout.  See: $flash
$FPGlobal FlightPath object that contains functions accessible from everywhere in a FlightPath application.  See: $FP
ActionA function on a Controller that takes input from a web request, sets data on the controller instance, and picks a View to render the data back to the browser.
beanAn instance of a beanClass.  Represents a single object from a Model data store.
beanClassA class associated with a Model that represents a “row” of data from that model.  This class contains functions for getting and setting values, validating values, field metadata, etc.  Also contains liks to related beans from related <models>
BehaviorA mixin class that overrides, alters, or appends functionality to a class.  Behaviors can be applied to either Controllers or Models.  See: Behaviors
camelCasename format where all words are lower case, first letter of each word after the first capitalized, with no separation. ex: employeeAction
ControllerRefers to either a Controller class or instance.  Controllers contain Actions manage Layouts, an contain Behaviors, and Filters
ElementSpecialized View template for containing output snippets to be included in a View
FilterA function applied in the init() function of a Controller to be executed before or after an Action.  This can be used to alter how actions are performed without changing the actions themselves.  For example authentication and permissions checks can be performed in filters and certain actions can be denied or audited.  See: Controller.addFilter
file_casea name format where all words are lower case, and separated by underbars(_). ex: employee_action
HelpersHelpers are function libraries used inside of Views and Actions for repetitive tasks, usually related to generating output.  See: $FP.helpers.Html
LayoutSpecialized View template set in a Controller to wrap content created by an Action, See: Layouts
ModelRefers to either a Model class or instance.  Models in FlightPath are static singletons (Only one instance per request).  Model Functions can return one or more beanClass instances that contain the actual model data
ProperCasename format where all words are lower case, first letter capitalized with no separation. ex: EmployeeAction
RouteA URL pattern that maps to a controller an d action.  A FlightPath application can support multiple routes.  See: Routes
url-casea name format where all words are lower case, and separated by underbars(_) or dashs(-). ex: employee-action, employee_action
ViewAn .ejs template intended to be sent to the browser.  There are also specialized views: Layouts and Elements

Getting Started

To create a FlightPath template, navigate to the Myna Administrator and select “Add/Update FlightPath App”, and enter a path and folder name, relative to the Myna web root.  If this directory does not exist, it will be created.  Once The FlightPath template has been unpacked you will see a directory structure like this:

+-application.sjs
+-app/
+...
+-framework/
+...

The “framework” folder contains the FlightPath framework code.  These files will be overwritten future uses of the “Add/Update FlightPath App” feature.  Here you will find built-in controllers and behaviors such as Controller: Direct and Behavior: MynaAuth.  You should not modify any files in this folder.

”application.sjs” is a standard Myna application definition (See: $application), With custom “config” section specific to FlightPath (See: FlightPath Config)

The “app” folder contains your application.  These files will not be altered by future uses of the “Add/Update FlightPath App” feature.

+-app/
+-behaviors/
| +-controllers/
| \-models/
+-controllers/
| \-global.sjs
+-models/
| \-global.sjs
+-modules/
+-static/
\-views/
+-elements/
+-home.ejs
+-layouts/
| \-default.ejs
\-themes/

”app” sub-folders

behaviorsStores Controller behaviors in the “controllers” folder and Model behaviors in the “model” folder.  See Behaviors
controllersStores Controller files.  File names should be lower case with underbars (_) between words and “_controller” on the end, e.g.  MyItem becomes my_item_controller.sjs.  The global.sjs file is included before every controller file.  Use this file for global initialization and/or to add common functions to all controllers.  The init() in the global.sjs file is executed before the controller’s init()
modelsStores Model files.  File names should be lower case with underbars (_) between words and “_model” on the end, e.g.  MyItem becomes my_item_model.sjs.  The global.sjs file is included before every model file.  Use this file for global initialization and/or to add common functions to all models.  The init() in the global.sjs file is executed before the model’s init()
modulesModules are self-contained FlightPath applications that can be embedded in other applications.  These controllers, models and views can be accessed as if they were in the main application.  See: Modules
staticThis folder contains static content that will not be interpreted as Myna or FlightPath code.  These files are accessed via http://server.tld/appname/static/filename This is a good place for images, client-side JavaScript files and css files
viewsThis folder contains a sub-folder for each controller that has views.  For example the view for the Main controller’s index() action would be views/main/index.ejs
views/home.ejsdefault page loaded if no homeRoute is defined (see: FlightPath Config)
views/elementsThis folder contains any Elements defined for the app
views/layoutsThis folder contains any Layouts defined for the app, including the global layout.  This folder may also contain sub-folders by controller name.
views/layoutsreserved for future use

Hello World!

First, let’s edit our application.sjs file and disable our default datasource, for now

// in application.sjs
...
config:{
ds:{
//"default":"flight_path_app"
},
...

You should probably edit the appname and other metadata properties while you are here

Let’s create a Main controller and an index() action

// in app/controllers/main_controller.sjs

function index(){
this.renderContent("Hello World!")
}

You can now access this via /yourapp/

This works because the default route (See: FlightPath Config) is set to Main.index.  The full URL would be /yourapp/main/index

This is fine for a single line of text, but it is not very flexible for HTML.  Lets add a view:

// in app/controllers/main_controller.sjs

function index(){
this.set("text","Hello World!");
}
<%-- in app/views/main/main_index.ejs --%>
<h1><%=text%></h1>

In our controller we set some data that then appears as a global variable in our view.  If you view source on this page you’ll see something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="description" content="" />
<meta name="keywords" content="" />
<title>Main.index</title>
<link rel="shortcut icon" href="/dev/favicon.ico" >
<script type="text/javascript" src="/dev/shared/js/libOO/client.sjs"></script>
</head>
<body>
<div class="flash_message_container">
</div>
<h1>Hello World!</h1>
</body>
</html>

All that extra HTML wrapping your view is coming from the default layout in app/views/layouts/default.ejs.  Unless you make a call to Controller.setLayout all views in your app will be wrapped in this layout.  You can manipulate the metadata in this layout by setting properties on Controller.$page.  Let’s set a title for our page.

// in app/controllers/main_controller.sjs

function index(){
this.$page.title = "Howdy"
this.set("text","Hello World!");
}

Working with databases

That’s entertaining, but it would be nice to work with some actual data.  Let’s create a database to work with

// in application.sjs
...
config:{
ds:{
"default":"fp_app"
}
...
}
...
onRequestStart:function(){ // run directly before requested file
if (!Myna.Admin.ds.exists("fp_app")){
Myna.Admin.ds.createLocalDatabase("fp_app")
var db = new Myna.Database("fp_app");
db.getTable("authors").create({
recreate:true,
columns:[{
name:"id",
isPrimaryKey:true,
type:"VARCHAR",
maxLength:255,
allowNull:false,
},{
name:"name",
type:"VARCHAR",
maxLength:255,

}]
});

db.getTable("posts").create({
recreate:true,
columns:[{
name:"id",
isPrimaryKey:true,
type:"VARCHAR",
maxLength:255,
allowNull:false,
},{
name:"slug",
type:"VARCHAR",
maxLength:255,

},{
name:"created",
type:"DATE",
},{
name:"author_id",
type:"VARCHAR",
maxLength:255,
references:{
table:"authors",
column:"id",
onDelete:"cascade",
onUpdate:"cascade",
}
}]
});

db.getTable("post_contents").create({
recreate:true,
columns:[{
name:"id",
isPrimaryKey:true,
type:"VARCHAR",
maxLength:255,
allowNull:false,
},{
name:"post_id",
type:"VARCHAR",
maxLength:255,
references:{
table:"posts",
column:"id",
onDelete:"cascade",
onUpdate:"cascade",
}
},{
name:"content",
type:"TEXT"
}]
});

db.getTable("tags").create({
recreate:true,
columns:[{
name:"id",
isPrimaryKey:true,
type:"VARCHAR",
maxLength:255,
allowNull:false,
},{
name:"tag_name",
type:"VARCHAR",
maxLength:255,
}]
});

db.getTable("posts_tags").create({
recreate:true,
columns:[{
name:"post_id",
type:"VARCHAR",
maxLength:255,
allowNull:false,
},{
name:"tag_id",
type:"VARCHAR",
maxLength:255,
allowNull:false,
}]
});



}

var frameworkFolder=this.config.frameworkFolder||this.dir + "framework"
Myna.include(frameworkFolder+"/FlightPath.sjs",{}).init().handleRequest();
}
...

This creates a local database with some example tables for a blog application.  Have a look at Myna.Admin, Myna.Database and Myna.Table for more details.  If you were including this in a real application, you might limit it to development environments or at least move it to onApplicationStart which runs less often.

Notice that the names are plural, and the primary and foreign keys are defined.  This is important for the Models to properly auto generate (See: Model.Model Conventions).

Creating a post editor

Lets create a way to edit our posts.

//in app/controllers/post_controller.sjs
function edit(params){
// Generate ID for new record if none-supplied. That way ID will be in
// the URL and refreshing the page won't create a new record
if (!params.id){
$FP.redirectTo({
id:this.model.genKey()
})
}

// only get here if not re-directed
this.set("bean",this.model.get(params));
}

Here we’re creating an “edit” action that can be used for both new posts and existing posts.  New posts will generate a unique key that will be used when the post is saved.  If you looks at ManagerObject.genKey, you will see that for tables with a varchar primary key, the default key generator outputs UUID’s.  This can be overridden in Model definitions.  See $FP.redirectTo for how redirects work.

Finally, we set a local “bean” property with the result of “this.model.get(params)” (See: Model.get).  This creates a temporary bean that contains either the data of an existing bean, or the default values for a new bean

Now we need a view to display it

<%-- in app/views/post/post_edit.ejs --%>

<form action="<%=Html.url({action:"save",id:bean.id})%>" method="post">
<table width="100%" height="1" cellpadding="0" cellspacing="0" border="0" >
<tr>
<th ><%=bean.getLabel("id")%>:</th><td><%=bean.id%>, <%=bean.getLabel("created")%>: <%=bean.get_created()%><td>
</tr>
<tr>
<th><%=bean.getLabel("slug")%>:</th>
<td><input name="slug" value="<%=String(bean.get_slug()||"")%>"><td>
</tr>
<tr>
<th><%=bean.Author().getLabel("name")%>:</th>
<td><input name="Author.name" value="<%=String(bean.Author().name||"")%>"><td>
</tr>
<tr>
<th colspan="2" align="left"><%=bean.PostContent().getLabel("content")%>:</th>
</tr>
<tr>
<td colspan="2" align="left">
<textarea cols="70" rows="50" name="PostContent.content"><%=String(bean.PostContent().content||"")%></textarea>
<td>
</tr>
<tr>
<td colspan="2" align="right">
<button type="submit">Save</button>
</td>
</tr>
</table>
</form>

Note the form action.  Here we are using the Html helper (see: $FP.helpers.Html) to make a URL for our “save” action.  Next, note that the “bean” property we set in the action is now a global variable in the view (See: Views).  We’re using <Model.beanClass.getLabel> to get a label for each field.  This allows for centralized field name definition in Model files, and potentially even international language translation.

The bean’s getters (get_created, get_slug, etc) will return either the current value or the default value defined in the Model file, depending on whether this is a new or an existing record.

Notice the line containing “bean.Author()”.  This is accessing the related parent author bean.  Myna knows that Posts belongTo Authors because of the foreign key defined on the posts table.  If this is a new post then there will not be an associated parent Author record.  In this case a new parent record will be created.  Normally you would probably want to have a <select> here and have a separate Author controller manage Author records.  On the next line, notice that the name for the input field is “Author.name”.  Myna recognizes structure and array notation in query variables and attempts to reconstruct complex objects from them (See: $req.data and Object.setByPath) This means that the “params” object passed the “save” action will have an Author object with a “name” property.  Because the Post model knows that it belongsTo Author, it will automatically create or load the related Author record and set its “name” property.  More on that when we get to save()

Notice that we are doing something similar with PostContent.  Because the post_contents table has a foreign key to posts, the Post model knows it potentially has a “hasMany” or “hasOne” relationship with post_contents.  By using “PostContent.content” we are using the “hasOne” relationship to create a content row and associate it with this post.

Ok, now we need to write a “save” action

// in app/controllers/post_controller.sjs
...
function save(params){
var bean = this.model.get(params);
var validation = bean.save();

if (validation.success) {
$FP.redirectTo({
action:"index",
success:"Record Saved."
})
} else {
$FP.redirectTo({
action:"edit",
id:bean.id,
error:validation
})
}
}

Here we create a temporary bean via Model.get and the attempt to save it via <Model.beanClass.save>, which returns a Myna.ValidationResult.  If successful we redirect to the index page, otherwise back to the edit page.  The extra parameters to redirectTo (“success” and “error”) are converted into $flash messages and displayed via the default layout

All that is left now is to make the index page to display our posts

// in app/controllers/post_controller.sjs
...
function index(params){
//this will pass paging info from params to the underlying query
params.setDefaultProperties({
page:1,
pageSize:25
})
this.set("rows",this.model.findBeans({},params))
}
<%-- in app/views/post/post_index.ejs --%>

<%=Html.link({
action:"edit",
text:"Add Post"
})%>
<table width="100%" height="1" cellpadding="0" cellspacing="0" border="0" >
<tr>
<th><%=$controller.model.getLabel("id")%></th>
<th><%=$controller.model.getLabel("slug")%></th>
<th><%=$controller.model.getLabel("created")%></th>
<th><%=$controller.model.Author.getLabel("name")%></th>
</tr>
<@loop array="rows" element="bean" index="i">
<tr>
<td>
<%=Html.link({
action:"edit",
id:bean.id,
text:bean.id
})%>
</td>
<td><%=bean.get_slug()%></td>
<td><%=bean.get_created().format("m/d/Y H:i:s")%></td>
<td><%=bean.Author().get_name()%></td>
</tr>
</@loop>
</table>
<table width="100%" height="1" cellpadding="0" cellspacing="0" border="0" >
<tr>
<td nowrap>
<@if $params.page != 1>
<%=Html.link({
params:{
page:parseInt($params.page)-1
},
text:"&lt;&lt; previous page"
})%>
</@if>
</td>
<td width="100%">&nbsp;</td>
<td nowrap>
<@if rows.length == $params.pageSize>
<%=Html.link({
params:{
page:parseInt($params.page)+1
},
text:"next page >>"
})%>
</@if>
</td>
</tr>
</table>

Now we can page through our results and add new posts.

Next Steps

FlightPath Config

FlightPath configuration is stored in the “config” property of $application.

Here is the default FlightPath config

//--------- FlightPath config -----------------------------------------
config:{
ds:{
"default":"flight_path_app"
},
homeRoute:{
controller:"Main",
action:"index"
},
routes:[{
name:"pages",
pattern:"page/$page*",
controller:"page",
action:"display",
page:"$page"
},{
name:"default",
pattern:"$controller/$action/$id/$restParams*",
controller:"$controller",
action:"$action",
id:"$id"
restParams:"$restParams"
}],
//frameworkFolder:"file:/home/mark/myna/web/shared/js/FlightPath/framework",
MyCustomProperty:"woot!"
},

”ds”

This structure lists data sources and their manager aliases, where the property is the alias, and the value is the DS name.  Normally you only need the default data source.  However, if you need access to models from multiple data sources, list them here.  Note that you also need to set the manager property of the model to match the manager alias defined here, for any models beyond the default model/DS

”homeRoute”

Defines the default route the will be executed when no url is provided, i.e.  “http/server.tld/appname/”.  This structure should include everything that should be passed as “params” to the action

”routes”

Defines what routes are available in this app.  See: Routes

”frameworkFolder”

Defaults to “framework”.  This is the MynaPath to where the framework folder is located.  Setting this to a central location will allow all FlightPath apps to share these files and be upgraded at once.  Using the example path of “file:/home- /mark- /myna- /web- /shared- /js- /FlightPath- /framework” will cause the app to always use the version of the FlightPath framework included with the server.  When Myna is upgraded, this folder is as well.

”MyCustomProperty”

All properties in the config will be applied to $FP and are available there from any model, controller or view

Behaviors

Behaviors are functions that are applied to the current object.

Behaviors can be applied to either models or controllers to modify their functionality.  If you want to add a set of functions multiple controllers or models behaviors are a good mechanism.

  • Built-in controller behaviors are stored in framework/behaviors/controllers/<behavior name>.sjs
  • Custom controller behaviors are stored in app/behaviors/controllers/<behavior name>.sjs
  • Built-in model behaviors are stored in framework/behaviors/models/<behavior name>.sjs
  • Custom model behaviors are stored in app/behaviors/models/<behavior name>.sjs

In the case of a name conflict, custom behaviors hide built-in behaviors

Example

//in some_controller.sjs
function init(){
// loads the built-in PDF andJSON filters
// Each of these has an "init" function that adds the appropriate
// before and after filters
this.applyBehavior([
"FormatPdf",
"FormatJson"
]);

//loads a single behavior with options
this.applyBehavior("MynaAuth",{
whitelist:[
"Main.index",
"Main.logout"
],
redirectParams:{
message: "Enter your AD domain credentials",
providers:["ldap_ad"]
}
});
}

See

Elements

An element file is a specialized view (see: Views) that is intended to contain a fragment of output (usually HTML) that can be used in a view

Element Locations

  • app/views/elements/<name>.ejs,
  • app/views/elements/<controller name>/<name>.ejs
//in app/views/test/index.ejs

<%=getElement("shared/common_commonlinks.ejs")%>
<%=getElement()%>

See

Layouts

A layout file is a specialized view (see: Views) that is intended to wrap content before sending it to the browser.

Layout Locations

Global Defaultapp/views/layouts/default.ejs
Controller Defaultapp/views/layouts/<controller name>/default.ejs
General Layoutsapp/views/layouts/<layout name>.ejs

General layouts are stored in app/views/layouts/<layout name>.ejs.  The global default layout is stioreController default layouts are store Layouts are applied by calling Controller.addLayout or Controller.setLayout

Layouts can wrap other layouts.  For example the global default layout wraps the controller Layouts are layered like so:

/app/views/layouts/default.ejs wraps
/app/views/layouts/controllername/default.ejs wraps
/app/views/controllername/actionname.ejs

Calling this function adds additional layouts that wrap the view, like so

    function init(){
this.addLayout("mylayout1")
this.addLayout("otherController/mylayout2.ejs")
}

//results in
/app/views/layouts/default.ejs wraps
/app/views/layouts/controllername/default.ejs wraps
/app/views/layouts/mylayout1.ejs wraps
/app/views/layouts/otherController/mylayout2.ejs wraps
/app/views/controllername/actionname.ejs

Modules

Modules are self-contained FlightPath applications that can be embedded in other applications.  These controllers, models and views can be accessed as if they were in the main application.

A module can be created from a FlightPath application by copying its “app” folder to the new application’s “app/modules” folder and then renaming it to the module name.  Then all folders except “models”, “controllers” and “views” should be removed.  Local models, controllers and views are always found before module models, controllers and views, so published modules should have names that are unique for these objects.

Routes

Routes are URL patterns that can be mapped to controllers and actions.  Routes are defined in the config section of the application.sjs for your app (See: FlightPath Config).  An incoming URL is matched against the routes array from top to bottom, exiting early if a match is found

Route Parameters

namename of the route.  This is used by $FP.helpers.Html.url and $FP.helpers.Html.link to create URL’s that match a particular route.
patternString.  Pattern to match. see Pattern Definitions below
controllerString.  Either the URL name of a controller or the placeholder variable that should contain the controller name
actionString.  Either the URL name of an action or the placeholder variable that should contain the action name
idOptional String.  Either a hard-coded id value or the placeholder variable that should contain the id
<other>Optional any other properties will become parameters to the action.  Value can be a literal or a placeholder variable

Pattern Definitions

Patterns are a series of tokens separated by slashes(/). tokens can be:

String literals”page”,
Variable placeholders”$page”
Globbing variable placeholders (must be last token)”$page*”
Regular expressions”rpt\\d+\\.\\w{3}”
Regular expression variable placeholders”$report(rpt\\d+\\.\\w{3})”
Request method prefix (only before first token)”[GET]<first token>/<next token...>”
Request method prefix variable placeholder (before first token)”[$method]<first token>/<next token...>”

Examples

The URL is examined from left to right matching URL tokens to route tokens.

Literal tokens are matched as if they were lower case

name:"home",
pattern:"index.html",
controller:"main",
action:"index"
/*
"server.tld/<appname>/index.html"
controller:"main",
action:"index"
*/

Variable placeholders start with $ and can only consist of letters, numbers and the underbar (_).  Variable placeholders capture the token in the URL at the position where they appear and assign that value to the route property that has the same value as the placeholder.

name:"emp",
pattern:"emp/$empnum",
controller:"emp",
action:"display",
id:"$empnum"
/*
"server.tld/<appname>/emp/22045563"
controller:"emp",
action:"display",
id:"22045563"
*/

Globbing variable placeholders capture the rest of the URL, including slashes(/)

name:"pages",
pattern:"page/$page*",
controller:"page",
action:"display",
page:"$page"
/*
"server.tld/<appname>/page/archive/2011/dec/christmas-party"
controller:"page",
action:"display",
page:"archive/2011/dec/christmas-party"
*/

Regular expressions need to be matched but don’t capture.  Note that they still only match one token

name:"deleted",
pattern:"oldstuff/.*",
controller:"deleted",
action:"error-deleted-content",
/*
"server.tld/<appname>/oldstuff/some-random-file.xls"
controller:"deleted",
action:"error-deleted-content",
*/

Regular expression variable placeholders capture the matched token

name:"reports",
pattern:"reports/$report(rpt\\d+\\.\\w{3})",
controller:"report",
action:"generate_report",
id:"$report"
/*
"server.tld/<appname>/reports/rpt12345.doc"
controller:"page",
action:"generate_report",
report:"rpt12345.doc"
*/

The Request method prefix can be used to test or capture the method used to submit the web request (GET,POST,PUT,DELETE,HEAD).  This can be a literal or a variable placeholder.

name:"default",
pattern:"[$method]$controller/$action/$id/$rest*",
controller:"$controller",
action:"$action",
id:"$id",
method::"$method",
extraPath:"$rest"

/*
"server.tld/<appname>/emp/get/22012/pdf"
controller:"emp",
action:"get",
id:"22012",
method:"GET"
extraPath:"pdf"
*/

Views

View Templates are .ejs templates used to render the result of an action.  They are stored in app/views.  Normally views are loaded automatically for a given controller and action by looking in app/views/<controller name>/<controller_name>_<action_name>.ejs.  Views can also be directly rendered via Controller.render

There are also two specialized kinds of view files: Layouts and Elements.  Generally Layouts wrap view templates, and view templates include Elements

Views Layouts and Elements have access to several global properties

View Properties

$controllerA reference to the controller that called this view
$modelA reference to this controllers default model, may be null
$paramsA reference to the params of the most recent action
$pageA reference to this controller’s Controller.$page property
getElementA reference to <getElement>
[data properties]All of the calling controller’s Controller.data properties are available as global variables
[$FP.helpers classes]”Html” refers to $FP.helpers.Html, etc

.

View Templates are .ejs templates used to render the result of an action.
Data Modeling base class.
Framework controller class for working with Ext.Direct
Applies action.controller based authentication and rights checking to controllers.
function redirectTo(options)
redirects the browser to another controller/action, cancels further processing.
A session-scoped object for passing messages to views.
Core framework instance for Myna FlightPath
Behaviors are functions that are applied to the current object.
In FlightPath, controllers (the C in MVC) are represented by the Controller class.
Controller.prototype.addFilter = function addFilter(filter,
options)
Adds an action filter
A model’s bean class
Routes are URL patterns that can be mapped to controllers and actions.
A layout file is a specialized view (see: Views) that is intended to wrap content before sending it to the browser.
An element file is a specialized view (see: Views) that is intended to contain a fragment of output (usually HTML) that can be used in a view
Global object for defining and managing a Myna application.
FlightPath configuration is stored in the “config” property of $application.
Modules are self-contained FlightPath applications that can be embedded in other applications.
Controller.prototype.setLayout = function setLayout(layout)
Sets a single layout layer to this this request, clearing any existing layouts
$page metadata object
API for Administrative functions
Provides database metadata and manages Myna.Table objects
Create modify and delete SQL tables
generates a primary key value
get:function get(values)
returns either an instance of an existing bean or the result of getNew
Stores parameters to the request.
Object.prototype.setByPath=function (path,
value)
sets a property or nested object property of this object
Stores the results of one or more validation operations
Applies filters that will automatically convert action returns into JSON responses
Applies filters that will automatically convert views into PDF documents
A MynaPath is a file URI String with certain automatic translations.
Controller.prototype.applyBehavior = function applyBehavior(name,
options)
loads a behavior and applies it to this object
applyBehavior:function applyBehavior(name)
loads a behavior and applies it to this object
Controller.prototype.getElement = function renderElement(element,
options)
renders an HTML template returns the content as a string
Controller.prototype.addLayout = function addLayout(layout)
adds a layout layer to this this request
function url(options)
Returns a URL for a specified controller and action
function link(options)
Returns an HTML link for a specified controller and action
Controller.prototype.render = function render(options)
renders a view
local request-specific data to be passed to views