Introduction

Welcome to the EASE Reference Guide. This document covers the syntax and use of EASE. For an introduction to EASE with "How To" documents, please visit the EASE Blog.

EASE is a tag language that is used to enhance HTML by allowing simple tags that are processed by the EASE Framework at request time. EASE can process data in Google Sheets and SQL Databases. EASE tags can generate dynamic HTML interfaces to securely interact with any stored data.

Conventions Used in this Document

The following conventions are used in describing the syntax:

Bold = Command keyword

italic = variable name, table name, text, commands, etc...

command(s); = Command phrase can be repeated, each delimited with ;

[ ] = Optional (when used with a single value)

[ A | B ] = Choice, delimited with |

EASE Examples are shown as:

<# EASE Example #>

EASE Tags

EASE is written in tags. When the EASE Framework parses text for EASE, it is looking for the opening and closing tag pair, where <# denotes the open of an EASE tag and #> denotes the close.

Example:

<# include "header.espx" #>

Tags start with a keyword.

Examples:

<# include "header.espx" #>

<# if … #>

<# set … #>

<# start … #>

There are several conventions that should be noted in describing EASE:

<# #>: Tag. A basic structure of EASE, with an open tag and close tag

Command: an EASE statement within a Tag, terminated with a semi-colon ;

EASE Block: an EASE Tag with multiple semi-colon delimited Commands

EASE Template: a paired <# start … #> , <# end … #> tag

EASE Commands

An EASE Command is a statement with a specific function. For example, “set, create, print, include” are all examples of EASE Commands. Commands are terminated with a semi-colon to allow for a Block of Commands in a single EASE tag, but there are some cases where a terminating semi-colon is not required.

Example:

<# include "header.espx" #>

EASE Blocks

Multiple Commands in a single EASE tag. Some commands are dependent on the first tag in the block.

Example: EASE Block with multiple Commands:

<#

set three to 1 + 2;

set one to 2 - 1;

set six to <#[three]#> * 2;

set four to (<#[six]#> / 2) + <#[one]#>;

#>

List, Checklist Form, and Form Templates

Templates are defined with a pair of start and end tags. List and Checklist Form templates are nested, and have a specific function. Templates are available for: Header, Row, Footer, and No Results.

Example: Templates in an EASE List.

<# start list ... #>

<# start header #>

header template content goes here

<# end header #>

<# start row #>

row template content goes here. reference a row value: <# name #>

<# end row #>

<# start footer #>

footer template content goes here

<# end footer #>

<# start no results #>

no results template content goes here

<# end no results #>

<# end list #>

How EASE Pages are Generated

EASE is a scripting language that is used to enhance HTML markup. While EASE does many things that would generally be implemented in a web app that utilizes a procedural or object-oriented programming language, it is not a programming language in the classical sense. For example, you can’t define functions (which is lower level procedural programming). EASE simply provides new tags that are pre-processed by the EASE framework and then by HTML to accomplish the same tasks.

First, you start by writing a file containing EASE (we use the .espx extension and call them ESPX files). This file has the necessary EASE tags to access your data and HTML tags to format your data. (Note, in WordPress, EASE can also be embedded in pages.)

Next, we process ESPX files at request time with the EASE Framework. At this point, when reading your data with the EASE tags, we render your HTML and display it in the browser.

.espx file → EASE+Data → HTML+JavaScript → Browser

Technically speaking, this is server-side processing; all the work is being done on the server, and then rendered in HTML for display.

Let’s look at a simple EASE app in action. In our example we want to produce a simple list from a spreadsheet with the URL call: /?page=example&orders=100

The EASE Page would be written like this:

<# start list for contact;

include when contact.order >= "<#[url.orders]#>";

#>

<# start header #>

<#

set counter to 0;

set counter to <# counter #> + <#[value]#>;

print "Counter = <# counter #>";

#>

<table border="1">

<tr>

<td>Name</td>

<td>Order</td>

</tr>

<# end header #>

<: List each row in the returned results :>

<# start row #>

<tr>

<td><# contact.name #></td>

<td><# contact.order #></td>

</tr>

<# end row #>

<#: Footer :#>

<# start footer #>

</table>

<# end footer #>

It would be pre-processed to look something like this (This is a logical view, not actual)

<# start list for contact;

include when contact.order >= 100;

#>

<#: Header :#>

<#

set counter to 0;

set counter to 0 + 100;

print "Counter = 100";

#>

<table border="1">

<tr>

<td>Name</td>

<td>Order</td>

</tr>

<#: List each row in the returned results :#>

<tr>

<td>Bob</td>

<td>150</td>

</tr>

<tr>

<td>Jane</td>

<td>258</td>

</tr>

<#: Footer :#>

</table>

The final output would look like this:

Counter = 100

Name

Order

Bob

150

Jane

258

Variables

EASE variables can be traditional stored values, but they are also used in forms and lists to reference values from Google Sheets or SQL Databases, as well as system constants.

A variable can have any name, but some have specific structure. The most commonly used variables are: sql_table_name.column, row.column,any_name.name, and any_name. Where table_name and row.column are naming conventions used with SQL Database tables and sheets and the any_name variables are user defined.

Variables have scope of either session, page or local. Session variables are available across all pages in your app. Page variables are local to the ESPX page (cross EASE Blocks and Functions) and inline variables are local to a EASE Block. Generally, system variables are session variables. Page variables are user defined or URL parameters and inline variables are spreadsheet, SQL Database, form or user set variables.

SESSION and PAGE (Cross blocks) VARIABLES USE <#[ and ]#> tags

LOCAL (in a block) VARIABLES USE <# and #> tags

Session variables are bracketed by <#[ and ]#>. Examples are session and cookie variables, and variables created with the "apply" function.

Page variables are also are bracketed by <#[ and ]#> when referenced. Page variables are also created with the Set function. URL parameters are page variables.

Local variables are bracketed by <# and #> and created with the set tag. Or, they are created inline within list and form blocks which reference spreadsheets or SQL Database values.

There are six basic types of variable tags that are defined by how their values are generated:

Settable variables. Variables can be defined dynamically for numbers and strings. They can also be defined with the "Set" function and can be local or page variables.

Request variables. These are values that are passed as part of a URL or POST data and are system-generated as page variables (only for that page)

SQL Database variables are used for lists and forms and are defined by the SQL Database being referenced (in list or form blocks). SQL Database variables are generally local variables.

Spreadsheet variables, used for lists and forms, are system defined. Spreadsheet variables are local variables.

System Value variables are predefined names for system values. System variables are generally session variables, but some blocks have local values defined.

Cookies and Session variables are used to define session or cookie variables. Sessions & cookies expire length are defined as part of the Google App Engine setup.

There are three basic rules for using variables:

When a local variable with a value is being used in an expression, HTML or query, it is bracketed by the open "<#" and close tag "#>". Example:

<# set shipping.name to "<#customer.name#>"; #>

When a global variable with a value is being used in an expression, HTML or query, it is bracketed by the open "<#[" and close tag "]#>". Example:

<# set shipping.date to "<#[system.date]#>"; #>

When a variable is being defined, then it does not need to be in quotes or bracketed by the EASE open and closed tags.

The value being set in a Set tag (defined)

Spreadsheet or SQL Database variables in (constant)

<#

set cart_amount.value to "100";

set cart_amount.value to 100;

#>

Example: Google Sheet variables in filter comparison expressions

<# start list for googlespreadsheet "Inventory";

include all columns from "Sheet1" where row.d == "<#[url.fruit]#>";

#>

Example: Used as a variable

<# start row #>

<tr>

<td><# row.a #></td>

<td><# row.b #></td>

<td><# row.c #></td>

</tr>

<# end row #>

Example: Assigning a fixed string to a variable

<# set cart_amount.value to "100"; #>

Example: Assigning a variable string to a variable

<# set amount_tax.value to <# cart_amount.value #> * "1.0925"; #>

Example: SQL Database

<# start list for contact;

include when contact.name == "<#[url.name]#>";

#>

<# start header #>

<table border="1">

<# end header #>

<#: List each row in the returned results :#>

<# start row #>

<tr>

<td><# contact.name #></td>

<td><# contact.email #></td>

<td><# contact.phone #></td>

</tr>

<# end row #>

<#: Footer :#>

<# start footer #>

</table>

<# end footer #>

Other Rules

Request variables are bracketed by the tag open "<#[" and close "]#>" (Request variables are page in scope) <#[url.get_var]#> <#[request.post_var]#>

When column or table variables are used in “where” clauses, then the EASE Start and End Tags are not required

EASE variables are injected into the expressions with their current value and should always be set between quotes:

Example: Assigning a quoted string to a variable

<#

set var1.value to "String.....";

set var2.value to "<# var1.value #>";

#>

var1: <# var1.value #> = var2: <# var2.value #>

Example: Number can be optionally quoted:

<#

set var1.value to 10;

set var2.value to <#var1.value#> + "100";

#>

var1: <# var1.value #> <br> var2: <# var2.value #>

Settable Variables

EASE Variables can be defined programmatically and are created and assigned using the "set" command. EASE variables defined with the set command always have the user-defined names.

Example: var1, inventory, and var3 are all user defined names

<#

set var1.address to "String.....";

set inventory to "10";

set var3.address to "<# var1.address #>";

#>

Inject Request Variables

Request and URL variables are defined by the EASE Framework at request time. Request and URL variables are page variables; that is, they are only defined for the life of the page.

Example: A URL of: /?page=deletecontact&delete=true&id=343232

<# if "<#[url.delete]#>" == "true" #>

<# delete record for "contact.<#[url.id]#>"; #>

Current Page: <#[url.page]#>

<# end if #>

Note: Since URL parameters are global tags they need an open tag <#[ and close tag ]#>. URL parameters can be used outside of EASE tags. In the above example <#[url.page]#> would return "deletecontact"

Spreadsheet Variable Names

Google Sheet variables are defined by absolute address, with the "row" constant name or the column name (as defined by the column text in row 1). Row and column names are restricted for use only in lists and form blocks.

Absolute: Absolute address of cells is done by the columns and row number. If the Cell is Column B and Row 2, the Cell would be addressed as <# b.2 #>.

Absolute address can only be used in a header template.

Row: The current row is addressed with the variable "row" followed by the column letter. For example, <# row.b #>.

Column Name: The current row can be addressed by the column name, as the column is defined in the first row of the spreadsheet. For example, <# phone #>.

Row and name variables can only be used in the "start row" or "start form" block.

General Rules

When in a list or form block, spreadsheet variables can be used in any function that allows for an EASE Command (Set, If, ...)

Example: Address values by column letter for each row in a List Row Template

<# start row #>

<tr>

<td><# row.a #></td>

<td><# row.b #></td>

<td><# row.c #></td>

</tr>

<# end row #>

Example: Address values by column header for each row in a List Row Template. The column header is set in the first row of the sheet.

<# start row #>

<tr>

<td><# name #></td>

<td><# address #></td>

<td><# email #></td>

</tr>

<# end row #>

Example: Filtering an EASE List

<# start list for Google Sheet "test";

include all columns from "Sheet1"

where row.d="<#[url.fruit]#>" and row.e="<#[url.color]#>";

#>

SQL Database

SQL Database variables can be used in any start form or start list template.

SQL Database variables are addressed by the table name and the column name. For example, an entity link named "contact" with a "name" property would be addressed as <# contact.name #>

General Rules

When in a list or form block, SQL Database variables can be used in any function that allows for an expression (set, if, ...)

When a SQL Database variable is used in a tag, (between the open/close <# #>), open/close tags are not required except as part of an expression in a set.

Start list as "sdfsdfsdf"

Example:

<# start list for contacts;

include when contacts.type is "<#[url.contact_type]#>";

sort by name;

#>

<# start header #>

<table>

<tr>

<th>Name</th>

<th>Email</th>

<th>Phone</th>

</tr>

<# end header #>

<# start row #>

<tr>

<td><# name as html #></td>

<td><# email as html #></td>

<td><# phone as html #></td>

</tr>

<# end row #>

<# start footer #>

</table>

<# end footer #>

<# no results #>

No Contacts

<# end no results #>

<# end list #>

Example 2:

<# start list for articles;

include when articles.headline = "<#[url.search]#>" ;

#>

Injecting Variables in Different Contexts

Variables can be defined in different contexts which can control how they are used or formatted. For example, date or timestamp contexts can allow for different date/time calculations.

Global Variable Syntax:

<#[variable_nameascontext ]#>

Local Variable Syntax:

<#variable_nameascontext #>

Example:

<# invoice_total as Dollars #>

Context

Description / Output Format

as [ Dollar | Dollars | USD | $ ]

$ 4,423.44

as [ Euro | Euros | EUR | € ]

€ 3.332,43

as [ HTML | web | webpage | websafe ]

Converts HTML control characters into their HTML encodings, and converts new-line characters into HTML <br> tags. Any user provided data that is intended to be displayed as-is in an HTML document should use this context to avoid HTML/CSS/JavaScript injection.

Example: PG&E → PG&amp;E

as [ URL | URI ]

Convert URL control characters into their URL encodings. Any variable injected into a URL query param that may contain URL control characters should use this context to avoid URL corruption.

Example: PG&E → PG%26E

as link

For using a variable in the context of a URL being used to link an HTML element to a HREF. this has the same effect as "as URL as HTML".

Example: <PG&E> → &lt;PG%26E&gt;

as [ number | numberic |

decimal | float | long ]

strips a variable of everything except 0-9, the negation sign (-), and the decimal separator (.)

as [ integer | int ]

converts a variable into a positive or negative integer value by stripping non numeric characters. default is 0.

as minutes

converts a string in the format h:mm:ss to total number of minutes

as hours

converts a string in the format h:mm:ss to total number of hours

as day

converts the string into a timestamp, then returns the integer day of month for the date

as month

converts the string into a timestamp, then returns the integer month of year for the date

as year

converts the string into a timestamp, then returns the year for the date

as timestamp

converts date values into total number of seconds since jan 1st 1970 (unix timestamp). both of these formats are supported: "09/19/2013 8:30 AM", "1979-01-17 07:43:34".

Conditional Text With Variable Injection

<# if "<#[url.inject]#>" == "yes" #><#[system.domain]#> - this is injected text<br />the system time is <#[system.time]#><# end if #>

<# set session.blah to "SET BY EASE <#[system.time]#> <#[url.add_to_blah]#>"; #>

System Constants

EASE has a number of global system constants for date, time and current application domain. System constants are always bracketed by EASE tags and can be used anywhere on the page.

System constants can also be block specific (for example in row, and footer blocks.)

Global System Constants:

Name

Tag

Example

Sortable Date with 24H Time

<#[system.date_time_short]#>

2013-07-29 18:23:17

Floating Point Seconds since Unix Epoch with fractional decimals

<#[system.timestamp_float]#>

<#[system.timestamp_long]#>

1396045934.1625

Whole Seconds since Unix Epoch

<#[system.timestamp]#>

1396045934

12H Time with Timezone

<#[system.time]#>

10:32:14 PM UTC

24H Time

<#[system.time_short]#>

22:32:14

Date with 12H Time with Timezone

<#[system.date_time]#>

2014-03-28 10:32:14 PM UTC

Sortable Date

<#[system.date]#>

2014-03-28

2 digit Month number

<#[system.month]#>

07

Month Name

<#[system.month_name]#>

July

3 Letter Month Name

<#[system.month_name_short]#>

<#[system.month_short]#>

Jul

2 digit Day of the month number

<#[system.day]#>

28

3 Letter Day of the week

<#[system.day_short]#>

Mon

Year

<#[system.year]#>

2013

Domain

<#[system.domain]#>

www.cloudward.com

EASE Page

<#[system.page]#>

index

Host name (Domain with optional Port)

<#[system.host]#>

localhost:11080

URL of the Host

<#[system.host_url]#>

http://www.cloudward.com

Secure URL for the Host

<#[system.secure_host_url]#>

https://www.cloudward.com

Session ID for current user

<#[system.session_id]#>

[UUID]

Referring URL

Note: this value will ensure an “?” so “&” can always be used to append values

<#[system.referrer]#>

https://www.google.com/?q=hi

Referring Host

<#[system.referring_host]#>

www.google.com

Referring Host URL

<#[system.referring_host_url]#>

https://www.google.com

Secure URL for the Referring Host

<#[system.secure_referring_host_url]#>

https://www.google.com

Secure URL for the Referring Page

<#[system.secure_referring_page_url]#>

https://www.google.com/mail

Referring Protocol Scheme

<#[system.referring_scheme]#>

https

Referring URL Query

<#[system.referring_query]#>

var=value&var2=value2

Remote IP Address

<#[system.remote_addr]#>

192.168.0.1

EASE Framework Platform Type

<#[system.core]#>

PHP

Request URI

<#[system.request]#>

/my_page

Example: Injecting Global System Constants using various syntaxes

<h2>System Constants</h2>

<ul>

<li>system.date_time_short: <#[system.date_time_short]#></li>

<li>system.date: <#[system.date]#></li>

<li>system.month: <#[ system . month ]#></li>

<li>system.month_name: <# [system.month_name] #></li>

<li>system.month_name_short: <# [ system.month_name_short ] #></li>

<li>system.day: <# [system.day] #></li>

<li>system.day_short: <#system.day_short#></li>

<li>system.year: <# system.year #></li>

<li>system.domain: <# system . domain #></li>

</ul>

Buckets

EASE Buckets are variables using period (.) delimiters in variable names. Buckets enable sending lists of data records to external APIs such as Cloudward Billing. The Print Bucket command enables dumping the Bucket values in HTML as a nested list of keys and values. The Loop command enables processing every value in the Bucket.

Example: Set values in a Bucket, Print a Bucket directly and to a Variable, Empty a Bucket

<#

// set nested values in the bucket

set Payment.items.0.Name to "Test Item";

set Payment.items.0.Price to "$ 9.95";

set Payment.items.1.Name to "Another Test Item";

set Payment.items.1.Price to "$ 19.95";

// print the bucket directly as HTML

print bucket Payment;

// generate the raw text of the print bucket command and save it to an EASE variable

Expressions

Expressions are used in Set comments as mathematical expressions. They are also used as logical and comparison expressions in Include directives for Forms and Lists, and all If/Else Conditionals. Expressions can be terminated with a Context stack for transforming values, such as “as dollars” which would turn the value 4010.1285 into $ 4,010.13.

Example:

<# set value to 4010.1285 as dollars; #>

Logical Expression

Logical expressions are used in “where”, “include” and “if” functions. Logical expressions are used to test two comparison expressions or can be the result of a single comparison expression.

Logical expressions use the following

Name / Symbol

Example

And - both comparison expressions must be true

contact.name == "<#[url.name]#>" and contact.Status == "new"

Or - either comparison expression bust be true

inventory.count == "0" or inventory.status == "Out of Stock"

comparison expression

A logical expression can be a single comparison expression

"<#[url.name]#>" == "new"

Comparison Expressions

Returns true or false.

Name / Symbol

Example

equal "=" "==" "===" "is"

<#[url.edit]#> == "true"

Greater than "<"

inventory.count > "0"

Less than "<"

row.c < "23"

Greater than or equal ">="

row.d >= "10"

Less than or equal "<="

order.quantity <= "10"

Not equal "!=" "!==" "<>" "is not"

order.status != "New"

Regular Expression Filters (SQL Database Only)

It is possible to use regular expression filters in a SQL Database List tag as part of the “include”. For examples of regular expressions see:

set time.hours to <# time.end_time as timestamp #> - <# time.start_time as timestamp #> as time "h:mm:ss";

set time.status to "clocked out";

#>

Linking and Addressing ESPX pages

When addressing a page in an HREF, EASE statement or Link , the "/?page=" statement is usually used as part of the URL.

Home page

EASE Home pages are stored in files named index.espx. Requests that don’t include a filename will default to look for an index.espx file in the requested directory. Bare requests for the domain would look for an index.espx files in the Application Root directory:

www.easestarterapp.com

Pages

Linking to a page in the root directory: (all of these are equivalent)

<a href="/store">store</a>

<a href="/store.espx">store</a>

<a href="/?page=store">store</a>

Using the full URL: (all of these are equivalent)

<a href="//www.easestarterapp.com/store">store</a>

<a href="//www.easestarterapp.com/store.espx">store</a>

<a href="//www.easestarterapp.com/?page=store">store</a>

Subdirectory

Is referenced by:

index file in the subdirectory

Subdirectory link with href='/subdirectory/'

Subdirectory link with href='/?page=subdirectory/'

Subdirectory link with href='/?page=subdirectory/index'

Subdirectory link with href='/?page=subdirectory/index.espx'

A file in the subdirectory is referenced by:

Subfile link with href='/subdirectory/subfile'

Subfile link with href='/subdirectory/subfile.espx'

Subfile link with href='/?page=subdirectory/subfile'

Wordpress

In Wordpress, ESPX pages are installed as WordPress pages. They are linked via the WordPress perma-link URL.

Lists

EASE Lists are used to retrieve, process, and display data from Google Sheets, SQL Database tables, and Google Drive Folders. EASE Lists differ in how they operate with these different sources of data, but the majority of features apply to any data source. For SQL Database backed Lists, the row values will be named according to the column names from the SQL table. For Google Sheet backed Lists, the row values will be named according the value in the 1st row of each of each column, as well as the column letter. Rows from Google Sheets with data in columns that don’t have a value set in row 1 will not include the data for the missing column. For Google Drive Folder Lists, the row values returned include: id, uuid, description, extension, size, icon_url, last_modified_by_username, type, created_on, updated_on, filename, name, drive_url, thumbnail_url, web_url, download_url, drive_download_url, alternate_url, kind, image_height, image_width, title.

First, EASE is a scripting language used to enhance HTML markup. That is, EASE provides new tags that are processed by the EASE framework at request time to do the various List operations.

Be sure you have read the blog "How EASE Works" before continuing on with Lists.

Lists are created as a Template that represent how the list will be rendered. The List template has a header, rows, and a footer. In all, there are five sets of Templates that belong to lists. These are:

Start List: starts the list process, determines the type of list and any query qualifications, and specifies other actions that define what the list will look like

Header: the block of HTML code displayed before the rows

Row: the block of HTML displayed for each row in the returned list

No Results: a block of HTML if no rows are to be displayed

Footer: the block of HTML code displayed after all the rows are processed

Start List Block

Used for: SQL Database; Google Sheets

The Start List Block is used to open a list template. It is used to define the data source: either a SQL Database Table name or a Google Sheet. The list template is closed with an End List tag.

Include When

The "include when" for SQL Database provides qualifications for entities returned from the table name.

Syntax:

include [ when | where ]comparison_expression;

A comparison expression terminated with "if set" will only be applied if the second operand has a value assigned that isn’t only whitespace.

Example: Filter by the SKU value in the URL query string, but only if a SKU value was provided

<# start list for orders;

include when sku is "<#[url.sku]#>" if set;

set overall_total to total of orders.total;

#>

Example: look for payments with the value "Debit"

<# start list for Google Sheet "Test Spreadsheet";

include when payment method is "Debit";

#>

Example: search articles for entities with a type of "docx"

<# start list for articles;

include when articles.type == "docx" ;

#>

Example: search contacts for entities with a name of "Bill" that has a status of "new"

<#

start list for contact;

include when contact.name == "Bill" and contact.status=="new";

#>

Example: Show all Items that are linked to a Category from a comma separated list if provided. If the category_list value in the URL was set to “new,featured”, then all items that were categorized as “new” or “featured” will be included. Items that are both “new” and “featured” will only be shown once

<# start list for items; must relate id to item_categorizations.item_id; must relate item_categorizations.category_id to categories.id; include when categories.name in "<#[url.category_list]#>" if set; show unique items; order by name;#>

Sorting / Ordering

Used for: SQL Database, Google Sheets

Sort a returned list from a SQL Database by table name field in the order selected.

Relate / Join

Used for: SQL Database

Joins two tables together. The tables are joined by matching attributes, i.e. where a column from the list table matches the joined table. When using the "must" keyword, only items that have a match in the second table will be included, otherwise all items in the first table will be included even if they don’t have a match.

<# start list for items; must relate id to item_categorizations.item_id; must relate item_categorizations.category_id to categories.id; include when categories.name in "<#[url.category_list]#>" if set; show unique items; order by name;#>

Include Columns / Exclude Columns

Used for: SQL Database

The "include columns" and “exclude columns” directives allow you to limit the amount of data that is queried and returned from the database. By default EASE will make all column data available, so if you have a table with a field that may contain large amounts of data, then exclude that column in Lists that won’t reference that value. If the List will only reference a few columns, you could add a List Directive to only include those columns.

Note: these optimizations won’t have much effect if your dataset is small, but any App processing millions of records with large amounts of data will likely need to make use of these directives.

Include Syntax:

include columns column(s,) ;

Exclude Syntax:

exclude columns column(s,) ;

Example: Process all Orders using a List to sum an overall total. No columns other than “total” will be referenced, so only include that column.

<# start list for orders;

include columns total;

set overall_total to total of orders.total;

#>

Show # Rows Per Page

Used for: SQL Database, Google Sheets

Set paging for a list. This displays both page numbers on top and/or bottom of a list. Hide Pager command can turn paging on/off for the "top" and "bottom" pagers, or "both".

Syntax for SQL Database:

show number[ rows | sql_table_name ] per page;

Note: sql_table_name is provided when multiple tables are related together and you want to show all related items for a certain number of grouped items per page.

Syntax for Google Sheet:

show number rows per page;

Example: Show 20 rows on each page.

<# start list for articles;

show 20 rows per page;

#>

Example: Show 3 Offices per page, with every Employee assigned to that Office

<# start list for offices; relate name to employees.office; order by offices.name, offices.uuid, employees.name; show 3 offices per page;#>

Header Template

The header block is to used to format the top part of a list result from a SQL Database or Sheet query.

Syntax:

<# start header #> … <# end header #>

Example: start the header as a table, with headings in the first row

<# start header #>

<table border='1' cellpadding='2' cellspacing='0'>

<tr style='font-size:11pt;'>

<th>ID</th>

<th>Time</th>

<th>Type</th>

<th>Customer Name</th>

<th>Total</th>

<th>Payment<br />Method</th>

<th>Notes</th>

<th>Rush?</th>

<th>Action</th>

</tr>

<# end header #>

Row Template

Used for: SQL Database, Google Sheets.

The row template is used to display the results for each row of the data returned by the List defined in the <# start list … #> block. When used with HTML table statements, the <table> would be in the Header Tempate, and </table> in the Footer Template.

Checklist Forms

Used for: SQL Database

Checklist Forms are a special case form that is a blend of a form and a list. The checklist form allows using list templates to display a list of records, and uses checkbox inputs to allow for items in the list to be selected.

The following blocks, commands, form actions and input types are allowed:

Start Checklist Form: starts the list process, determines the type of list and any query qualifications, and specifies other actions that define what the list will look like.

Start Row: the block of HTML displayed for each row in the returned list.

Valid Input types?

checkbox

button

No results: a block of HTML if no rows are to be displayed

Start Footer: the block of HTML code displayed after all the rows are processed.

Syntax:

<# start checklist form for sql_table_name [record_id];

[checklist_form_directives(s) ; ]

#>

Example: Checklist of “Articles” for flagging as “reviewed” or “rejected”

<# start checklist form for articles; include when status is not "reviewed" and status is not "rejected"; when reviewed call confirm('Mark checked items as reviewed?'); when rejected call confirm('Mark checked items as rejected?'); when reviewed and checked set status to "reviewed"; when rejected and checked set status to "rejected"; when done redirect to "/articles";#>

Checklist Form Actions

Used for: Checklist Forms. Similar to "when" directives used for other form actions. It also has the condition for checked and unchecked for checklist items.

Syntax:

when form_action[ and [ checked | unchecked ]]

[ set command | redirect command | call javascript_function ] ;

Example: List of Orders with checkboxes to mark items as Shipped

<# start checklist form for orders; include when status is not "Shipped"; relate sku to products; when shipped call confirm('Mark checked items as Shipped?'); when shipped and checked set status to "Shipped"; when done redirect to "/orders_shipped_checklist";#>

Example: List of Articles with checkboxes to mark items as Reviewed or Rejected

<# start checklist form for articles; include when status is not "reviewed" and status is not "rejected"; when reviewed call confirm('Mark checked items as reviewed?'); when rejected call confirm('Mark checked items as rejected?'); when reviewed and checked set status to "reviewed"; when rejected and checked set status to "rejected"; when done redirect to "/articles";#>

Forms

EASE provides the ability to create forms that use HTML form commands and has the ability to create, update or delete records from SQL Database or Sheets.

For experienced HTML programmers, the first thing to note is that EASE "replaces" the HTML form actions that would normally be used to create or update a record in a database or add a row to a spreadsheet. Normally, this form action would be a custom PHP page with these database or API operation calls. WIth EASE, simple form actions like “create”, “update” and “delete” can be used to perform database operations. On top of that, anytime the form changes, EASE takes into account the changes and does any of the db schema updates for you.

Basic structure of a Form Template has four parts:

<# Start form for ..... #>, which references a Google Sheet or SQL Database table and has a number of directives for setting defaults, or actions

The HTML form with input type replaced with EASE Variables

Form Action

<# end form #>

Start Form for SQL Database

Used for: SQL Database

Start form defines how the form is to operate. i.e. what actions to take with the "button" input type (updating, deleting and adding a record).

Where name is the table name, and "record id" is the uuid value for the record that can be updated by the form. The record.id is a defined column in a SQL Database table automatically populated for each record created.

When creating a SQL Database record. The table three attributes automatically auto filled with each new record:

"id" which is auto filled with a UUID that is guaranteed to be unique

"instance_id" is also set with an integer number starting from 1

"created_on" is automatically set on creation

"updated_on" is automatically set with every update

Example 1: This example, named "form_with_input_validations" opens a table in the SQL Database called "validations" and allows for the creation of a new record or the updating or deletion of a record. "form.id" is the UUID of the record being created and passed back into the same page during the "done" form action for edit.

<# start form for validations <#[url.edit]#>; when deleting call confirm('Confirm Delete?'); when deleting redirect to "/form_with_input_validations"; when done redirect to "/form_with_input_validations?edit=<# form.id #>";#>

619485c236c5453262535fc1c04ad03a is the record ID value from the contact record. (contact.id). Every spreadsheet row has an “EASE ROW ID” column that is maintained by EASE. When the record ID is blank or “0”, a new row will be inserted into the sheet.

For a Google Sheet, the start code to add a sheet would be:

<# start form for googlesheet 0AjfXurRV-PuudE5vZnPxUy0xMlg3HnNPVzA4b01XOHc;

save to "Sheet1";

#>

In this case, we are using the googlesheet attribute with the google ID for the spreadsheet (found as part of the URL in the Google Sheet) and we are saving new data to sheet1.

Start Form for Action Only

The Google Sheet will be referenced by either ID or double-quoted name.

Syntax:

<# start form; [form_directive(s) ; ] #>

Example: Action Form for validating a hashed password

<# set session.auth to "not validated"; #><# set hashed_password to "blah" as hash salted by "my salt"; #>

<# start form for googlesheet 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

when loading set row.a to "New";

save to "Sheet1";

#>

Example:

<# start form for googlesheet 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

when loading redirect to "/?page=home";

save to "Sheet1";

#>

Example:

<# start form for contact <#[url.edit]#>;

//

// Set the table contact source, status to their static values

// Note: contact.id is auto created

//

when creating set contact.source to "user_form";

when creating set contact.status to "new";

when updating set contact.status to "updated";

//

// When a create, update or delete action is encountered, redirect

// the appropriate confirmation page.

//

when creating redirect to "/?page=blog_list_dstore";

when updating redirect to "/?page=blog_list_dstore";

when deleting redirect to "/?page=blog_list_dstore";

#>

Example: Form Action to Call javascript function "confirm"

<# start form for articles <#[url.edit]#>; when creating set status to "new"; when creating set cookie.blah to "whoa... cookie <# form.id #>"; when updating call confirm('Confirm Update?'); when deleting call confirm('Confirm Delete?'); when creating redirect to "/articles?index=last"; when done redirect to "/articles";#>

Conditional Form Actions

Used for: SQL Database

Used to define conditions to trigger a form action based on data submitted with the form.

Note: conditional_expressionis a comparison of double-quoted strings. ( Paren ) nestingand all standard logical negators and comparators are supported as well as nested “and” and “or” groupings.

Example: When updating a User’s hashed password, hash the new password and store it only if it’s different than the existing stored hashed password.

<# start form for users_with_hashed_password <#[url.edit]#>; when creating set password to "<# form.password as hash salted by form.id #>"; when updating and ("<# form.password #>"!="<# password #>") set password to "<# form.password as hash salted by form.id #>"; when deleting call confirm('Confirm Delete?'); when done redirect to "/users_with_hashed_password?index=<# form.id #>";#>

Save To

Used for: Google Sheets, SQL Database

Used for what sheet to use, defaults to the first sheet, if the named sheet does not exist, will create a new sheet and create the column headers

Syntax:

save to " sheet_name " ;

Example: Save to a worksheet named "Boston"

<# start form for googlespreadsheet "inventory";

when loading redirect to "/?page=home";

save to "Boston";

#>

Set HTML Form Attributes

Used for: Google Sheets, SQL Database

Used to set custom attributes for the HTML Form tag that will be generated for the EASE Form

Syntax:

set form. attribute_name to " text" ;

Example: Set CSS Style for the Form

<# start form for googlespreadsheet "inventory";

set form.style to "margin:20px; border:1px solid black;";

#>

Input Variables, Preset and Field Validations

Used for: Google Sheets, SQL Database

These are the input types supported. The General syntax:

Syntax:

<input [ type="input_type" ] <# ease_variable #> [ / ]>

Note: All HTML 5 Form Input attributes are supported, such as “required”. A preset value for the input can be defined using the “value” attribute. The default type is “text”. “unique” is also a supported attribute that will ensure the value for the field is unique in an SQL Table.

Radio Input Type

<input type="radio" value="x" <# variable #> />

<table>

<tr>

<td></td>

<td>Yes</td>

<td>No</td>

</tr>

<tr>

<td width="550">

Is the EASE language something you would use to enhance your WordPress site?

Conditional EASE Templates (If - Else If - Else)

Where command is one of the valid EASE Commands. Note, HTML can also be inserted in if-then-else statements. If-then-else can also have multiple "elseif" blocks.

logical_expression is a comparison of “ double-quoted “ values. ( paren ) nesting and all standard logical comparators and negators are supported, as well as the text comparator “is”, and the text negator “not”.

Example: Conditional List of “Orders”:

<# if "<#[url.list]#>"=="yes" #> <# start list for orders; include when sku is "<#[url.sku]#>" if set; set overall_total to total of total; #> ... <# end list #><# end if #>

Example: Conditionally Set Cookies

<# if "<#[url.red]#>" == "on" #>

<#

set cookie.mother to "redirecting ";

set session.hello to "this page redirects set by session variable...";

redirect to "/?page=1ifthen_redirect";

#>

<# else #>

<#

set session.hello to "It did not redirect ";

set cookie.mother to "not redirecting ";

#>

<# end if #>

Set

The Set command is to used to define the value of a field where the field can be a number of variable types based upon where the set value is located in a block or template.

Syntax:

set fieldto arithmetic_expression[ as context] ;

Can be defined in "context" (see: Injecting Variables in Different Contexts)

Example: Arithmetic Expressions

<#

set val1 to "2";set val2 to 3;set val3 to 4;set result to (<#[val1]#> + <#[val2]#>) * <#[val3]#> as dollars;

#>

<#[result]#> would then later inject the value: $ 20.00

Example: Setting Cookie and Session values:

<#

set cookie.blah to "bloo";

set session.username to "<#[url.username]#>";

#>

Example: Using Timestamps with Time Context

<#

// calculate time difference in hoursset var.start_time to "09/19/2013 8:30 AM";set var.end_time to "09/19/2013 6:30 PM";set calc.difference to <#[var.end_time as timestamp]#> - <#[var.start_time as timestamp]#>;set calc.output to <#[calc.difference as time "h:mm:ss"]#>;

#>

Set to Total of

Used for: SQL Database, Google Sheets

To set the total value of a list command

Syntax:

set field to total of field ;

Example: Sum all “total” fields to calculate overall total

<# start footer #>

<#

set var12.value to total of <# blah.total #>;

round var12.value to 2 decimals;

#>

<# end footer #>

Replace

The Replace command is to used to alter a value, finding and replacing a string or pattern with another string.

String Replacement Syntax:

replace [ case insensitive ] " find " in fieldwith " replace " ;

Regular Expression Pattern Replacement Syntax:

replace [ case insensitive ] " pattern " in fieldwith " replace " ;

Example: String Replacement

<#set my_var to "the quick brown fox jumps over the lazy dog";replace "brown" in my_var with "green";replace case insensitive "DOG" in my_var with "cat";#>

<#[my_var]#> would then have the value: the quick green fox jumps over the lazy cat

Example: Regular Expression Pattern Replacement

<#set my_var to "the quick brown fox jumps over the lazy dog";replace pattern "(brown|lazy)" in my_var with "nice";#>

<#[my_var]#> would then have the value: the quick nice fox jumps over the nice dog

<# replace_var #> would then have the value of the headline with any instance of “test” replaced with “pass”

Record Commands

Used to create, update, clone, and delete records for Google Sheets and SQL Database Tables.

Create Record

Used for: SQL Database, Google Sheet

Used to create a new record for Google Sheets and SQL Database Tables.

SQL Database Syntax:

create new record for sql_table_name

[ reference as " alias "] ;

[create_record_directive(s) ; ]

Google Sheet Syntax:

create new record for spreadsheet

[ " spreadsheet_name " |spreadsheet_id ]

[ " worksheet_name " ]

[ reference as " alias " ] ;

[create_record_directive(s) ; ]

Example: Create a record for table "sql_table_name", referencing the record using an alias.

<# create new record for "sql_table_name" reference as "var1";

set var1.status to "new";

set var1.name to "<#[url.name]#>";

set var1.note to "<#[url.note]#>";

set var1.qty to "<#[url.qty]#>";

set var1.each to "<#[url.each]#>";

#>

Example: Add a record to the Google Sheet "Payment"

<# create new record for spreadsheet "Payment"; set Time to "<#[system.date_time_short]#>"; set Customer Name to "Testla Testopolis"; set Total to "$29.95"; set Payment Method to "Credit"; set Type to "Web Order"; set Notes to "Added with EASE - CREATE NEW RECORD";#>

Update Record

Used for: SQL Database, Google Sheet

Used to update a record for a Google Sheet or SQL Database Table. The record is referenced by the record ID. Each record in a SQL Database table has a record.uuid (aliased as "id"). Each row in a Google Sheet has a header column “EASE Row ID” that defaults to column T, but can be located in any column.

Syntax for SQL Database Table:

update record for " sql_table_name. record_id "

[ reference as " alias " ];

[update_record_directive(s) ; ]

Syntax for Google Sheet:

update record for googlesheet

[ " googlesheet_name " | googlesheet_id ]

[ " worksheet_name " ]

row_id

[[ reference ] as " alias " ] ;

[update_record_directive(s) ; ]

Example: Update a contact record for an SQL Database Table

<# update record for "contact.<#[url.edit]#>" reference as "var2";

set var2.status to "new";

set var2.name to "<#[url.name]#>";

set var2.note to "<#[url.note]#>";

set var2.qty to "<#[url.qty]#>";

set var2.each to "<#[url.each]#>";

#>

Example: Loop through all of the records in the invoice SQL Database Table, then update the records with a new status, and calculate tax and total.

Clone Record

Example: Clone a record for table "invoices" using the record ID provided in the URL. The new record will automatically be applied as “new_invoice”

<# clone invoices.<#[url.id]#> as "new_invoice"; #>

Delete Record

Used for: Google Sheet, SQL Database

Used to delete records from Google Sheets and SQL Database Tables. The record is referenced by ID (for example, <# orders.id #>). Each record in a SQL Database table has a record.uuid (aliased as “id”).

Redirect

The Redirect command is used to redirect the page to another page. This can be done conditionally.

Syntax:

redirect to " url ";

Example:

<# redirect to "/?page=_logon"; #>

Include

Used to pull in EASE code from a file, and process it. The included file content will replace the include tag. Header and Footer files are not pulled in when including ESPX files.

Syntax:

include " filepath " [ ; ]

Note: The semi-colon is only optional when the EASE Tag contains only the include command.

Example:

<# include "wp_header.espx" #>

Include Google Doc

Used to pull in page content from a Google Doc, and optionally process it as EASE. The included content will replace the include tag.

Syntax:

include [ processed | raw ] [ and … ] google doc

[ " googledoc_name " |googledoc_id ] [ ; ]

Note: The semi-colon is only optional when the EASE Tag contains only the include command. If the “processed” flag is omitted, the Google Doc content will not be processed as EASE. If the “raw” flag is set, the Google Doc will be returned exactly as Google provides it; otherwise, it will be stripped of its HTML container, and the CSS will be localized and tracking links routed through google.com will be converted to direct links.

Some additional tags are supported solely when processing a Google Doc as EASE, such as <# youtube … youtube #> which will swap out the word “youtube” for “iframe” and ensure everything in between is formatted as a valid HTML iframe tag.

Example: Process a Google Doc as EASE

<# include processed googledoc "Website Info" #>

Header and Footer files

The EASE Framework automatically looks for files named header.espx and footer.espx in the same directory as the ESPX file corresponding to the requested URL.

Header content is prepended to the requested ESPX file content, and the Footer content is appended to the requested ESPX file content before processing begins.

Header and Footer files are not pulled in when ESPX files are included from EASE.

Apply

Used for: SQL Database

Loads all values from an SQL Database record into global EASE variables.

Syntax:

apply table.record_id as "alias ";

Example:

<# apply orders.<#[cookie.orderid]#> as "order"; #>

<# apply articles.<#[url.id]#> as "story"; #>

<h1><#[story.headline]#></h1>

<p><#[story.body]#></p>

<p><#[story.id]#></p>

<p><a href="/?page=article_list">Home</a></p>

If a record ID is not provided provided, the record created earliest will be applied. If an alias is not provided, the record will be applied as the table name.

Syntax:

apply sql_table_name[ as " alias " ] ;

Example:

<# apply webstyle; #>

EASE Comments

Comments allow for describing EASE code, and will be stripped on the server side and not delivered to the user.

There are two forms: single line comments and multi-line comments. These must be between EASE open and close tags.

multi-line Syntax: <#:

multi-line comment …

multi-line comment …

:#>

single line Syntax: <#

// single-line comment

command(s); // single-line comment

#>

Example: Multi-line comment

<#:

this is amultiline comment

print "this should also not be printed";

:#>

Example: Single line comment:

<#

// This is a single line comment

#>

Print

Printing allows for outputting a string of text, that can be optionally contexted (see: Injecting Variables in Different Contexts).

If your page outputs to an HTML web page, and you want user data to show as-is and not rendered as HTML, then use the HTML context to avoid cross-site scripting attacks, or other HTML injection that may break your page formatting.

Syntax:

print " text "[ as context ] ;

Example: Print string to be rendered as HTML by the browser

<# print "This was printed by <b>EASE</b>"; #>

Generates this output:

This was printed by <b>EASE</b>

Which is rendered in the browser as:

This was printed by EASE

Example: Print string to be shown as-is, using the HTML Context

<# print "this was printed by <b>EASE</b>" as html; #>

Generates this output:

This was printed by &lt;b&gt;EASE&lt;/b&gt;

Which is rendered in the browser as the original string:

This was printed by <b>EASE</b>

Note: If User provided data is injected directly into an HTML page, HTML and JavaScript Injection is possible. Such as a User that claimed their name was <script>alert(‘hi’);</script>.... if you inject that value as <#[user.name]#>, you would likely see an alert from your browser. A malicious user could add other javascript to deface the page or steal data. Using the HTML context when injecting the variable <#[user.name as html]#> eliminates this risk, and will render the User Name exactly as it was provided.

Sending E-Mail

The “Send Mail” command is used to send email messages. “Send Mail” is a block command that requires subsequent commands to set E-Mail parameters such as “To” and “Subject”.

Additional values generated and set for the file to reference a public web URL to access the file directly, and a Google Drive URL that is only accessible by Google users who have access to edit files in the Google Drive Folder. In the example above, the file was saved to the variable “file”, so there will be these 2 additional values set:

file_drive_web_url: the public web URL to download the file from Google Drive

file_drive_url: the private URL to edit the file on Google Drive

Example: Using a form, get the ID of a folder, and then pick a file to upload, or select an existing URL and then insert it into the files table. The dialog like this:

<# set var.folder_id to public folder id by name "EASE-BAT File Uploads"; #>

<# start form for files <#[url.edit]#>; when deleting call confirm('Confirm Delete?'); when done redirect to "/files";#>

Get a Google Drive folder ID by name. If the folder doesn’t exist, it will be created automatically, and the new ID returned and set to the variable name provided.

Syntax:

setvariableto public folder id by name"text… ";

Example:

<# set new_folder_id to public folder id by name "<# system.time #> my new EASE folder"; #>

Access Restrictions

There are two commands to manage access restrictions; the first is to test for security group membership and redirect the user to an authentication page if access was not granted. The second command grants access to a security group.

The restrict command sets a session value for the variable_name referenced (in our example "members"). If this value is not set in your session using "grant", then you get redirected to the "using" page (in our example, "member_logon".)

Syntax:

restrict access to security_group using authentication_page [ ; ]

Example: Test if the current page has "member" access. Redirect to member_logon if the access was not granted.

<# restrict access to members using member_logon #>

To grant membership to a security group, use the “Grant Access” command.

Syntax:

grant access to security_group [ ; ]

Example: Ensure the current user is in the security group "members".

<# grant access to members #>

Note: The semi-colon is only optional when the EASE Tag contains only the single command.