EASE Reference Guide

EASE Reference Guide

Version 3.2.0

Table of Contents

Introduction

Conventions Used in this Document

EASE Tags

EASE Commands

EASE Block

List, Checklist Form, and Form Templates

How EASE Pages are Generated

Variables

Settable Variables

Inject Request Variables

Spreadsheet Variable Names

SQL Database

Injecting Variables in Different Contexts

Conditional Text With Variable Injection

System Constants

Session & Cookies

Expressions

Logical Expression

Comparison Expressions

Regular Expression Filters (SQL Database Only)

Arithmetic Expressions

Timestamp Calculations

Linking and Addressing ESPX pages

Lists

Start List Block

List Directives

Include

Include When

Sorting / Ordering

Relate / Join

Show Unique

Show # Rows Per Page

Show / Hide Pager

Header Template

Row Template

Footer Template

No Results

Tips for Using Lists

Using Set In Lists

Checklist Forms

Checklist Form Actions

Forms

Start Form for SQL Database

Start Form for Google Sheet

Form Directives

Form Actions

Conditional Form Actions

Save to

Set HTML Form Attributes

Input Variables, Preset and Field Validations

Radio Input Type

Checkbox Input Type

Email Input Type

Text Input Type

Text Input Type with Pattern

HTML 5 Validated Input Types

TextArea

Form Selectors

Form Actions

Form Coding Examples

EASE list saved to an EASE variable, used in HTML Select form element

Commands

If - ElseIf - Else (Conditional EASE Blocks)

Set

Set to Total of

Record Operations

Create Record

Update

Clone Record

Delete Record

Redirect

Include

Include Google Doc

Header and Footer files

Apply

EASE Comments

Print

Sending E-Mail

Round to

Upload file to Google Drive

Create New Google Drive Folder, or get existing Google Drive Folder ID

Access Restrictions

Importing and Exporting between SQL Database and Google Sheet


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 … #>

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

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 Block


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 create loop structures or 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.

First, you start by writing a file containing EASE (we use the .espx extension and call them ESPX files). This file has the necessary directives 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:

There are three basic rules for using variables:

  1. 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#>"; #>

  1. 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 shippingdate to "<#[system.date]#>"; #>

  1. When a variable is being defined, then it does not need to be in quotes or bracketed by the EASE open and closed tags.
  1. The value being set in a Set tag (defined)
  2. 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

  1. Request variables are bracketed by the tag open "<#[" and  close "]#>"  (Request variables are page in scope) <#[url.get_var]#> <#[request.post_var]#>
  2. When column or table variables are used in “where” clauses, then the EASE Start and End Tags are not required
  3. 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]#>

}

#>

   

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

Example:  Directly address any spreadsheet cell value in a List Header Template

<# start header #>

<table border="1">

    <tr>

        <th><# a.1 #></th>

        <th><# b.1 #></th>

        <th><# c.1 #></th>

    </tr>

<# end header #>

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

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 Syntas:

<#[ variable_name as context ]#>

Local Variable Syntas:

<# variable_name as context #>

Example:

<# invoice_total as Dollars #>

Context

Description / Output Format

as [ Dollars | USD ]

 $ 4,423.44

as [ Euros | EUR ]

€ 3.332,43

as [ HTML | web | webpage | websafe ]

For using a variable in the context of HTML… converts HTML control characters into their HTML encodings.

Example: <PG&E> → &lt;PG&amp;E&gt;

as [ URL | URI ]

For using a variable in the context of a URL.  Convert URL delimiters into their URL encodings. 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 | decimal | float | long ]

converts a variable into just numbers, negation sign and decimal point

as [ integer | int ]

converts a variable into just numbers and negation sign

as timespan

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

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

as timestamp [ + | - ] timespan

Adjusts the timestamp by the timespan

as time " format string "

replacement tokens for " format string "

    d = days

    hh = 2 digit hours

    h = 1-2 digit hours

    mm = 2 digit minutes

    m = 1-2 digit minutes

    ss = 2 digit seconds

    s = 1-2 digit seconds

as date " format string "

replacement tokens for " format string "

    M = 2 digit month

    MM = full month name

    D = 2 digit day of month

    DD = day of month with suffix (1st, 2nd, …)

    Y = 4 digit year

    hh = 2 digit hour in 24 hour time

    h = 1-2 digit hour in 12 hour time

    mm = 2 digit minutes

    m = 1-2 digit minutes

    ss = 2 digit seconds

    s = 1-2 digit seconds

    A = AM or PM

as [ pdate | phpdate ] " format string "

replacement tokens for " format string " match the PHP date function tokens defined here: http://php.net/manual/en/function.date.php

Example :

<# start row #>

   <td><# orders.each as dollars #></td>
  <td><# orders.total as html #></td>

<# end row #>

Conditional Text With Variable Injection


You can use variables and in text strings and conditions.

Examples:

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

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

<#[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

Referring Protocol Scheme

<#[system.referring_scheme]#>

https

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>

Session & Cookies


Cookies and sessions are special EASE variables that are used for session variables and for creating cookies. Used when you want "longer" life variables.  Defined using the "set" command.

Example:

<# set cookie.logontime to "Timestamp <#[system.time]#> <#[url.add_to_blah]#>"; #>

Cookies: Cookies are set for ever by default, or the length of time is in the php.ini (default is no expiration date)

Sessions: Stored in memache, Set in Google Cloud Storage, expire when session id expires (as set in the PHPSESSID cookie)

https://appengine.google.com/settings?&app_id=s~ease-starter-app&version_id=1.374100285664691260

In App Engine settings, cookie expiration sets the session expiration:

Example:

<#

set cookie.lp to "";

set cookie.first to "first";

set cookie.last to "last";

#>

<#

set session.home to "on";

set session.music to "";

#>

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:

http://www.php.net/manual/en/reference.pcre.pattern.syntax.php

[ ~ | REGEXP | RLIKE ]

<# start list for orders;
   show 20 rows per page;
   include when sku ~ "<#[request.regex]#>";
   set overall_total to total of orders.total;
#>

Arithmetic Expressions


Returns a value when embedded in a set function or as part of a comparison expression.

Name / Symbol

Example

Addition  "+"

set arth1.value to 12 + <# var10.value #> ;

Subtraction "-"

set arth1.value to 12 - <# var10.value #> ;

Division "/"

set arth1.value to 150 / <# var10.value #> ;

Multiplication "*"

set arth1.value to 14 * <# var10.value #> ;

Modulus "%"

set arth1.value to 12 % <# var10.value #>;

Example

<#

set var10 to 10;

set arith1.value to "12" + <# var10.value #> ;

set arith2.value to "12" - <# var10.value #> ;

set arith3.value to "150" / <# var10.value #> ;

set arith4.value to "14" * <# var10.value #> ;

set arith5.value to (2 * 4) * 6;

#>

Timestamp Calculations


Context

Example

second

seconds

set countdown to <#[var.start_time as timestamp + 60 seconds]#>;

minute

minutes

set calc.add_minutes to <#[var.start_time as timestamp + 12 Minutes]#>;

hour

hours

set calc.add_hours to <#[var.start_time as timestamp + 2 Hours]#>;

day

days

set calc.add_days to <#[var.start_time as timestamp + 12 Days]#>;

week

weeks

set calc.add_weeks to <#[var.start_time as timestamp + 2 Weeks]#>;

month

months

set calc.add_months to <#[var.start_time as timestamp + 1 Month]#>;

month-end

month-ends

months-end

monthsend

months-ends

monthsends

monthend

monthends

set calc.add_months to <#[var.start_time as timestamp + 1 Month-End]#>;

first-of-month

first-of-months

firsts-of-month

firsts-of-months

firstofmonth

firstofmonths

firstsofmonth

firstsofmonths

set calc.add_months to <#[var.start_time as timestamp + 1 First-Of-Month]#>;

year

years

set calc.add_years to <#[var.start_time as timestamp + 3 Years]#>;

decade

decades

set calc.add_decades to <#[var.start_time as timestamp + 1 decade]#>;

century

centuries

set calc.add_century to <#[var.start_time as timestamp + 1 century]#>;

millennium

millennia

set calc.add_millemmium to <#[var.start_time as timestamp + 1 millennium]#>;

Example:  Time Clock for tracking hours

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

    when creating set start_time to "<# system.date_time_short #>";

    when creating set status to "clocked in";

    when updating set end_time to "<# system.date_time_short #>";

    when updating set hours to

       <# system.timestamp #> - <# form.start_time as timestamp #> as time "hh:mm:ss";

    when updating set status to "clocked out";

    when done redirect to "/timesheet";

#>

Employee Name: <input type="text" <# employee_name #> value="Bob Smith" /><br />

Start Time: <input type="text" <# start_time #> /><br />

End Time: <input type="text" <# end_time #> /><br />

<input type="button" <# create button #> value='Clock-In' />

<input type="button" <# update button #> value='Clock-Out' />

<# end form #>

Example:  Time Sheet with overall total hours calculation

<# start list for timeclock;

    show 20 rows per page;

#>

<# start header #>

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

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

        <th>ID</th>

        <th style='padding-left:4px; padding-right:4px;'>Employee Name</th>

        <th>Status</th>

        <th>Start Time</th>

        <th>End Time</th>

        <th>Hours</th>

        <th>Action</th>

    </tr>

<# end header #>

<# start row #>

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

        <td style='font-family:monospace; font-size:9pt;'><a href='/timeclock?edit=<# id #>'><# id #></a></td>

        <td style='padding-left:4px; padding-right:6px;'><# employee_name #></td>

        <td style='padding-left:4px; padding-right:6px;'><# status #></td>

        <td style='padding-left:4px; padding-right:4px;'><# start_time #></td>

        <td style='padding-left:4px; padding-right:4px;'><# end_time #></td>

        <td style='padding-left:4px; padding-right:4px; text-align:right;'><# hours #></td>

        <td style='padding-left:4px; padding-right:4px;'><a href='/timeclock_update?edit=<# id #>'>Clock-Out</a></td>

    </tr>

<# end row #>

<# start footer #>

<# set <# total_hours #> to total of <# hours as timespan #>; #>

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

        <td colspan='5' style='text-align:right; padding-right:4px; font-size:12pt; font-weight:bold;'>Total:</td>

        <td style='padding-left:4px; padding-right:4px;'><# total_hours as time "h:mm:ss" #></td>

        <td></td>

    </tr>

</table>

<# end footer #>

<# no results #>

No Results

<# end no results #>

<# end list #>

Example: Clock Out

<# update record for "timeclock.<#[url.edit]#>" reference as "time";

    set time.end_time to "<#[system.date_time_short]#>";

    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

Subdirectory

Is referenced by:

A file in the subdirectory is referenced by:

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 data from Google Sheets and SQL Database table(s).  Because SQL Database and spreadsheets are very different, EASE Lists differ in how they operate with these two different sources of data.

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

Syntax for SQL Table List:

<# start list for sql_table_name ;

[ list_directive(s); ] 

#>

Syntax Google Sheets:

<# start list for googlesheet [ spreadsheet_id | "spreadsheet_name" ] ;

[ list_directive(s); ]

#>

A Spreadsheet List will default to the first worksheet if a worksheet name is not selected.  Use the "include all" command to select a different sheet.

Example:  Start a list of the SQL Table “contacts”; this will return all rows of the table.

<# start list for contacts; #>

Example:  List of a Google Sheet with a directive to select a worksheet

<# start list for googlespreadsheet 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

    include all columns from "Sheet1";

#>

Example:  List of a Google Sheet named "orders", using worksheet “Sheet1”

<# start list for Google Sheet "Orders";

    include all columns from "Sheet1";

#>

List Directives


The start list template has a number of commands that direct how the list will function.

Include


Used for: Google Sheets.

"Include all" is used is to select the rows returned from a Google Sheet.

Syntax:

include [ all columns | list_of_columns ]

[ from " sheet_name " ]

[ when comparison_expression ] ;

Example:  retrieves all rows in the spreadsheet:

<# start list for googlespreadsheet 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

    include all columns from "Invoices";

#>

Example:  filter results by date

<# start list for google spreadsheet "Test Spreadsheet";
            include when time as date >= "<#[url.start_date]#>" if set;
#>

Example:  only returns rows where the URL qualifications match the row cells:

<# start list for googlespreadsheet 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

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

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

#>

Include When


Used for: SQL Database

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.

Syntax:

[ sort | order ] by property [ , … ] ;

property Syntax:

field [ as context ] [ asc | desc | ascending | descending | in ascending order | in descending order ]

Example:

<# start list for articles;

   sort by articles.created_on in descending order;

#>

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.

Syntax:

[ must ] relate field to field;

Note:  "Must Relate" uses an a SQL Inner Join.  "Relate" uses a SQL Left Outer Join

Examples:  Join the article table to the product table by SKU.  (both examples are equivalent)

<# start list for articles;

    must relate sku to products;

#>

<# start list for articles;

    must relate articles.sku to products.sku;

#>

Show Unique


Used for: SQL Database

When relating multiple SQL Tables, a Unique directive will group the result set by the given SQL Table.

Syntax:

show unique sql_table_name;

Example:  Relate Items to Filtered Categories, showing only unique Items

<# 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;
#>

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;
#>

Show / Hide Pager


Used for: SQL Database, Google Sheets

Hide either top, bottom or both page headers.

Syntax:

[ show | hide ] [ both | top | bottom | ] pager[s] [ both | top | bottom | ] ;

Example:  Hide header and footer pager.

<# start list for articles;

    show 20 rows per page;

    hide both pagers;

#>

Header Template


Used for: SQL Database, Google Sheets.

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 returned data from the "Start List" command. When used with HTML table statements, the <table>  should be before the <# Start row#> template (in the start header template) and the </table> should be after the <#end row#>, in the <#start footer#> template.

Syntax:

<# start row #> … <# end row #>

Example:  To be printed out for each row in the list.

<# start row #>

    <tr style='vertical-align:top; font-size:10pt;'>

        <td style='font-size:8pt; font-family:monospace;'><a href='/spreadsheet_form?edit=<# easerowid #>'><# easerowid #></a></td>

        <td><# Time #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Type #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Customer Name #></td>

        <td style='text-align:right; padding-right:6px;'><# Total #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Payment Method #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Notes #></td>

        <td style='text-align:center;'><# Rush #></td>

        <td><a href='/spreadsheet_update_record?edit=<# easerowid #>'>Unset Rush</a></td>

    </tr>

<# end row #>

System Values Supported:

Footer Template


Used for: SQL Database, Google Sheets.

The footer template is used to display the footer (after the last row) of the returned data from the "Start List" command.

Syntax:

<# start footer #> … <# end footer #>

Example: close the HTML table directive and print the end message.

<# start footer #>

</table>

End of list….

<# end footer #>

No Results


Used for: SQL Database, Google Sheets.

The footer template is used to display the footer (after the last row) of the returned data from the "Start List" command.

Syntax:

<# no results #> … <# end no results #>

Example:

<# no results #>

No Results Found

<# end no results #>

Tips for Using Lists


This section contains tips on using lists.

Using Set In Lists


Used for: SQL Database

Calculated data can be created for each row in a list using the set command.

Example:  Applying a tax rate to calculate a new total for an order.

<# start list for orders; #>

<# start row #>
<#

// apply a tax rate of 5 percent, and add a flat $ 8.95 shipping fee
set <# new_total #> to (<# orders.total as number #> * 1.05) + 8.95 as dollars;

#>
original order total: <# orders.total #> → new order total: <# new_total #><br />
<# end row #>

<# end list #>

Example: List of orders with a List Directive to calculate an overall total

<# start list for orders;

    show 20 rows per page;

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

    set overall_total to total of orders.total;

#>

<# start header #>

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

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

        <th>ID<span style='font-weight:normal; font-size:9pt; padding-left:10px;'>(click to edit)</span></th>

        <th>Created On</th>

        <th>Buyer</th>

        <th>SKU</th>

        <th>QTY</th>

        <th>Each</th>

        <th>Total</th>

    </tr>

<# end header #>

<# start row #>

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

        <td style='font-family:monospace; font-size:9pt;'><a href='/order?edit=<# id #>'><# orders.uuid #></a></td>

        <td style='padding-left:4px; padding-right:6px;'><# orders.created_on #></td>

        <td style='padding-left:4px; padding-right:6px;'><# orders.buyer as html #></td>

        <td style='padding-left:4px; padding-right:6px;'><a href='?sku=<# orders.sku as link #>'><# orders.sku as html #></a></td>

        <td style='padding-left:6px; padding-right:5px; text-align:right;'><# orders.qty as html #></td>

        <td style='padding-left:6px; padding-right:5px; text-align:right;'><# orders.each as dollars #></td>

        <td style='padding-left:6px; padding-right:5px; text-align:right;'><# orders.total as html #></td>

    </tr>

<# end row #>

<# start footer #>

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

        <td colspan='6' style='text-align:right; padding-right:4px; font-weight:bold;'>Total:</td>

        <td style='padding-left:6px; padding-right:5px; text-align:right;'><# orders.overall_total as dollars #></td>

    </tr>

</table>

<# end footer #>

<# no results #>

No Results

<# end no results #>

<# end list #>

Example: List of Google Sheet

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

    show 20 rows per page;

#>

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

<# start row #>

    <tr style='vertical-align:top; font-size:10pt;'>

        <td style='font-size:8pt; font-family:monospace;'><a href='/spreadsheet_form?edit=<# easerowid #>'><# easerowid #></a></td>

        <td><# Time #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Type #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Customer Name #></td>

        <td style='text-align:right; padding-right:6px;'><# Total #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Payment Method #></td>

        <td style='padding-left:4px; padding-right:6px;'><# Notes #></td>

        <td style='text-align:center;'><# Rush #></td>

        <td><a href='/spreadsheet_update_record?edit=<# easerowid #>'>Unset Rush</a></td>

    </tr>

<# end row #>

<# start footer #>

</table>

<# end footer #>

<# no results #>

No Results

<# end no results #>

<# end list #>

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:

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";
#>

<# start header #>
<table border='0' cellpadding='2' cellspacing='0'>
   <tr style='font-size:12pt;'>
       <th></th>
       <th>Created On</th>
       <th>Headline</th>
   </tr>
<# end header #>

<# start row #>
   <tr style='font-size:10pt;'>
       
<td><input type='checkbox' <# checklist item #> /></td>
        <td><# created_on #></td>
       <td><# headline as html #></td>
   </tr>
<# end row #>

<# start footer #>
</table>
<input type='button' <# reviewed button #> value='Mark as Reviewed' />
<input type='button' <# rejected button #> value='Mark as Rejected' />
<# end footer #>

<# no results #>
No Unreviewed Articles.
<# end no results #>


<# end checklist form #>

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";
#>

<# start header #>
<table border='0' cellpadding='2' cellspacing='0'>
   <tr style='font-size:12pt;'>
       <th></th>
       <th>Created On</th>
       <th>Headline</th>
   </tr>
<# end header #>

<# start row #>
   <tr style='font-size:10pt;'>
       <td><input type='checkbox' <# checklist item #> /></td>
       <td><# created_on #></td>
       <td><# headline as html #></td>
   </tr>
<# end row #>

<# start footer #>
</table>
<input type='button' <# reviewed button #> value='Mark as Reviewed' />
<input type='button' <# rejected button #> value='Mark as Rejected' />
<# end footer #>

<# no results #>
No Unreviewed Articles.
<# end no results #>

<# end checklist form #>

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:

  1. <# Start form for ..... #>, which references a Google Sheet or SQL Database table and has a number of directives for setting defaults, or actions
  2. The HTML form with input type replaced with EASE Variables
  3. Form Action
  4. <# 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).

Syntax:

 <# start form for sql_table_name [ record.id ] ; [ form_directive(s) ; ] #>

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:

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 #>";
#>

<b>Email:</b><br />
<input type="email" required <# email #> value="test@test" /><br /><br />

<b>Positive Integer Number:</b><br />
<input type="integer" min="0" required <# integer #> value="7" /><br /><br />

<b>Decimal Number:</b><br />
<input type="number" required <# number #> value="7.7" /><br /><br />

<b>Dollars:</b><br />
<input type="dollars" required <# dollars #> value="$7.77" /><br /><br />

<b>Date:</b><br />
<input type="date" required <# date #> value="1979-01-17" /><br /><br />

<b>URL:</b><br />
<input type="url" required <# url #> value="http://www.example.com" /><br /><br />

<b>Input Pattern: [A-Z]{2}[0-9]{4}</b>
<div style="font-size:9pt;">(example: 2 letters, followed by 4 numbers)</div>
<input type="text" pattern="[A-Z]{2}[0-9]{4}" required <# part #> value="SK1024" /><br /><br />

<input type="button" <# Create button #> />
<input type="button" <# Update button #> />
<input type="button"
formnovalidate <# Delete button #> />

<# end form #>

Start Form for Google Sheet


Used for: Google Sheets

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

Syntax:

 <# start form for goolespreadsheet [ spreadsheet_id | "spreadsheet_name" ] [ record_id ] ; [ form_directive(s) ; ] #>

Example:   Form for an existing spreadsheet row

<# start form for spreadsheet "contact" 619485c236c5453262535fc1c04ad03a; #>

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 googlespreadsheet 0AjfXurRV-PuudE5vZnPxUy0xMlg3HnNPVzA4b01XOHc;

   save to "Sheet1";

#>

In this case, we are using the googlespreadsheet 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.

Form Directives


Form directives are commands in the Start Form Block.

Form Actions

Used for:  Google Sheets, SQL Database

Used to define what happens in a form action. Multiple actions can be defined for the same form action, but only one form action can be "done"

Syntax:

when form_action [ set command | redirect command  | call javascript_function ] ;

There are four default form actions:

Example:  These form actions are paired with input type "button" in the next Example

when creating set status to "new";


Example:  Defining a Form Button to trigger “When Creating” Form Actions

<input type='button' <# create button #> value="Create" />

Additionally, you can use user define form actions (as declared in the) and whatever you named your button. What do these other for actions do? (perform updates from the set commands?)

when mybutton set status to "Mine";
<input type=
'submit' <# mybutton button #> value="MyFunction" />

Example 1:

<# start form for googlespreadsheet

 0AlOzi7sM2A8LdG5ITnFaLTF3UTRUZFlqNzA5dHZQd3c;

when loading set row.a to "New";

save to "Sheet1";

#>

Example:

<# start form for googlespreadsheet

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.  

Syntax:

when form_action and ( conditional_expression ) [ set command | redirect command  | create record command | call javascript_function ] ;

Note:  conditional_expression is 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.

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?

      </td>

      <td>    <input type="radio"  value="Yes" <# row.m #> />    </td>

      <td>    <input type="radio"  value="No" <# row.m #> />    </td>

  </tr>

</table>

Checkbox Input Type

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

Using spreadsheets in my App<br>

   <input type="checkbox" value="Yes" <# row.h #> />

Email Input Type

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

<p>Email:

<input type="email"  style="width:300px" <# row.v #> />

Text Input Type

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

<p>name:

<input type="text"  style="width:300px" <# row.v #> />

Text Input Type with Pattern

type="text" pattern=

<input type="text" pattern="[A-Z]{2}[0-9]{4}" required <# part #> value="SK1024" /><br /><br />

HTML 5 Validated Input Types

Example:  type="integer"

<p>Count:

<input type="integer"  style="width:300px" <# Count #> />

Example:  type="number"

<p>Amount:

<input type="number"  style="width:300px" <# Amount #> />

Example:  type="dollars"

<p>Price:

<input type="dollars"  style="width:300px" <# Price #> />

Example:  type="date"

<p>Sale Date:

<input type="date"  style="width:300px" <# Sale Date #> />

Example:  type="url"

<p>URL:

<input type="url"  style="width:300px" <# urlv #> />

TextArea

<textarea></textarea>

What needs improvements to WordPress with EASE would you like to see?<br>

<textarea style="width:400px; height:105px;" <# row.p #>></textarea>

Form Selectors

<select …..

<p>Rate Your Overall Experience: <br>

   <select <# Experience #> >

        <option value="Best Ever" >Best Ever</option>

        <option value="Great" >Great</option>    

        <option value="OK" >OK</option>    

        <option value="Never Again" >Never Again</option>    

  </select>

</p>

Example:  Form with Validated Inputs and Delete Confirmation

<# 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 #>";
#>

<b>Email:</b><br />
<input type="email" required <# email #> value="test@test" /><br /><br />

<b>Positive Integer Number:</b><br />
<input type="integer" min="0" required <# integer #> value="7" /><br /><br />

<b>Decimal Number:</b><br />
<input type="number" required <# number #> value="7.7" /><br /><br />

<b>Dollars:</b><br />
<input type="dollars" required <# dollars #> value="$7.77" /><br /><br />

<b>Date:</b><br />
<input type="date" required <# date #> value="1979-01-17" /><br /><br />

<b>URL:</b><br />
<input type="url" required <# url #> value="http://www.example.com" /><br /><br />

<b>Input Pattern: [A-Z]{2}[0-9]{4}</b>
<div style="font-size:9pt;">(example: 2 letters, followed by 4 numbers)</div>
<input type="text" pattern="[A-Z]{2}[0-9]{4}" required <# part #> value="SK1024" /><br /><br />

<input type="button" <# Create button #> />
<input type="button" <# Update button #> />
<input type="button" formnovalidate <# Delete button #> />

The HTML looks like:

<p>First Name<br><input type="text" style="width:200px" tabindex="1"<# contact.first #> >

In this case, the contact table attribute "first", is used as the input field for the form using the tag: <# contact.first #>. Thats it.

For a Google Sheet, we use the attribute <# row.a #>. For example:

<br>First Name<br> <input type="text" <# row.a #> >

<#: Drop down :#>

<p>Fruit:

<select <# row.d #> >

    <option value="apples">Apples</option>

    <option value="oranges">Oranges</option>    

    <option value="bananas">Bananas</option>    

    <option value="peaches">Peaches</option>    

    <option value="pears">Pears</option>    

</select>

</p>

<#: Radio buttons :#>

<p>

Color:

<input type="radio" value="red" <# row.e #> > Red

<input type="radio" value="yellow" <# row.e #> > Yellow

<input type="radio" value="green" <# row.e #> > Green

<input type="radio" value="orange" <# row.e #> > Orange

</p>

Form Actions


Form actions are used for the response of the "input" type of "button". These can be paired with "when" statements to perform some action. "Submit" can also be used in place of "button".

There are four default form actions. They are “create”, “update”, “delete”, “done”. Each of these form actions perform the action on the value in the current form.

<input type="button" value="Submit" <# create button #> >

<input type="button" value="Save" <# update button #> >

<input type="button" value="Delete Record" <# delete button #> >

Example:  Form to insert into a table:

<#

<#:***********************************************************************

// Introduction to EASE forms (blog_form_ssheet.espx)

// This shows how a form can be used to create a new row in a

// Google Sheet

//

// ***********************************************************************

//

// Start the form.

// This: 0AjfXurRV-PuudE5vZnPxUy0xMlg3HnNPVzA4b01XOHc, the the

// Google Sheet

// ID that you can get from the google docs url.

//

// Name the sheet to be used in the spreadsheet

// specifies what sheet to save results to

//

//:#>

<# start form for googlespreadsheet "Fruit Inventory";

    save to "Sheet1";

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

#>

<#: Input goes to the next new row column "a" :#>

<br>Inventory ID: <input type="text" <# row.a #> > <br>

<br>Fruit Count: <input type="text" <# row.b #> > <br>

<br>In-stock: <input type="checkbox" value="TRUE" <# row.c #> >

<#: Drop down :#>

<p>Fruit:

<select <# row.d #> >

    <option value="apples" >Apples</option>

    <option value="oranges" >Oranges</option>    

    <option value="bananas" >Bananas</option>    

    <option value="peaches" >Peaches</option>    

    <option value="pears" >Pears</option>    

</select>

</p>

<#: Radio buttons :#>

<p>

Color:

<input type="radio"  value="red" <# row.e #> > Red

<input type="radio"  value="yellow" <# row.e #> > Yellow

<input type="radio"  value="green" <# row.e #> > Green

<input type="radio"  value="orange" <# row.e #> > Orange

</p>

<#: Submit button :#>

<input type="button" value="Submit" <# create button #> >

<# end form #>

Form Coding Examples


EASE list saved to an EASE variable, used in HTML Select form element

You can select from a table into an EASE variable and use that in a select form action.

Example: List of SQL Table to build HTML Select element body, saved to EASE variable

<# start list for offices;
   sort by name;
   save to office.options;
#>
<# start row #>
<option><# name as html #></option>
<# end row #>
<# end list #>

<# start form for employees <#[url.edit]#>;
   when done redirect to "/employees";
#>
<table border='0' cellpadding='2' cellspacing='0'>
   <tr>

        <td style='text-align:right;'>Employee Name:</td>

        <td><input type='text' style='width:200px;' <# name #> /></td>

    </tr>
   <tr>

        <td style='text-align:right;'>Job Title:</td>

        <td><input type='text' style='width:200px;' <# title #> /></td>

    </tr>
   <tr>
       <td style='text-align:right;'>Office:</td>
       <td>
           <select <# office #>>
               <option value=''>Choose an Office</option>
               <#[office.options]#>
           </select>
       </td>
   </tr>
   <tr>
       <td colspan='2' style='margin-top:4px; text-align:right;'>
           <input type='button' <# Create button #> />
           <input type='button' <# Update button #> />
           <input type='button' <# Delete button #> />
       </td>
   </tr>
</table>
<# end form #>

Example: EASE List with Create Record for Google Sheet Called in the Row Template

<# start list for invoices; #>
<# start row #>
<# create new record for googlespreadsheet "Invoices" "Sheet1" and reference as "var";
   set var.a to "<# invoices.each #>";
   set var.b to "*";
   set var.c to "<# invoices.qty #>";
   set var.d to " * 1.10";
   set var.e to "rounded math expression result:";
   set var.f to (<# invoices.qty #> * <# invoices.each #>) * 1.10;
   round var.f to 2 decimals;
#>
<# end row #>
<# end list #>

Example: Conditionals in List Templates

<# start list for articles; #>

<# start header #>
<# if("<#[url.show]#>"=="yes") {
   print "LIST HEADER - url.show was set<br />";
} #>
<# end header #>

<# start row #>
<# if("<#[url.show]#>"=="yes") {
   print "LIST ROW - url.show was set<br />";
} #>
<# end row #>

<# start footer #>
<# if("<#[url.show]#>"=="yes") {
   print "LIST FOOTER - url.show was set<br />";
} #>
<# end footer #>

<# no results #>
<# if("<#[url.show]#>"=="yes") {
   print "LIST NO RESULTS - url.show was set<br />";
} #>
<# end no results #>

<# end list #>

Example:  EASE List with Row Numbers, Update Record Calls, Set To Total of Commands, and Last Row Conditionals

<# start list for invoices; #>

<# start header #>
<h1>Header for List of Invoices</h1><hr>
<# end header #>

<# start row #>
<# update record for "<# invoices.id #>" reference as "var";
   set var.status to "processed with single math operators";
   set var.subtotal to <# invoices.qty #> * <# invoices.each #>;
   set var.tax to <# var.subtotal #> * .10;
   set var.total to <# var.subtotal #> + <# var.tax #>;
   round var.total to 2 decimals;
#>
<# if("<# lastrow #>"=="yes") {
   print "<br>This is the last item!";
}
#>
<p>
Item: <# rownumber #>
<#: rownumber would print the row number in ascending order starting at rownumber = 1 :#>
Name: <# invoices.name #> | Note: <# invoices.note #> <br>
Qty:  <# invoices.qty #> | Each: <# invoices.each #> <br>
Subtotal: <# invoices.subtotal #> | Tax:  <# invoices.tax #> | Total: <# invoices.total #> <br>
ID: <# invoices.id #>
<br /><a href="/invoice_delete?id=<# invoices.id #>">delete</a>
<hr>
<# end row #>

<# start footer #>
Total number of items <# numberofrows #>
<br />
<#
set <# subtotal #> to total of <# invoices.subtotal #>;
set <# taxtotal #> to total of <# invoices.tax #>;
set <# total #> to total of <# invoices.total #>;
round <# total #> to 2 decimals;
print "<br><br><b>The totals are: Subtotal <# subtotal #>; Tax <# taxtotal #>; OrderTotal: <# total #> </b>";
#>
<# end footer #>

<# no results #>
no results.
<# end no results #>

Commands


If - ElseIf - Else (Conditional EASE Blocks)


Used for Conditional EASE Blocks.

Syntax:

if ( logical_expression ) { [ command(s); ] }

[ elseif ( logical_expression ) { [ command(s); ] } ] [ … ]

[ else { [ command(s); ] } ]

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.

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 #>
} #>

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 ";

} #>

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 field  to 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 hours
set 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 #>

Record Operations


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


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.

<# start list for invoices; #>

<# start row #>
<# update record for "invoices.<# invoices.id #>" reference as "var";
   set var.status to "processed with math expressions";
   set var.subtotal to <# invoices.qty #> * <# invoices.each #>;
   set var.tax to <# var.subtotal #> * .10;
   set var.total to (<# invoices.qty #> * <# invoices.each #>) * 1.10;
   round var.total to 2 decimals;
#>
<# end row #>

<# end list #>

Example: Loop through all of the Row in a Google Sheet, then update the records for each Row, prepending * to the Status

<# start list for googlesheet "My Orders"; #>
<# start row #>
<# update record for googlesheet "My Orders" <# EASE Row ID #>;
   set status to "*<# status #>";
#>
<# end row #>
<# end list #>

Clone Record


Used for: SQL Database

Used to clone an existing record for an SQL Database Table.

Syntax:

clone table_name.record_id as " alias ";

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

Syntax for SQL Database:

delete record for " sql_table_name . record_id  " ;

Syntax for Google Sheet:

delete record for googlesheet

  [ " googlesheet_name " | googlesheet_id ]

  [ " worksheet_name " ]

  row_id ;

Example: Delete all of the records in a SQL Database Table

<# start list for orders; #>

<# start row #>
<# delete record for "orders.<# id #>"; #>
<# end row #>

<# end list #>

Example: Delete all of the Rows in a Google Sheet

<# start list for googlesheet "My Orders"; #>

<# start row #>

<# delete record for googlesheet "My Orders" <# EASE Row ID #>; #>

<# end row #>

<# end list #>

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.

Syntax:

include " filepath " [ ; ]

Note:  The semi-colon is only optional when the EASE Tag contains only the single 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 ] [ … ] google doc

  [ " googledoc_name " | googledoc_id ] [ ; ]

Note:  The semi-colon is only optional when the EASE Tag contains only this single 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 through google.com will be converted to direct links.

Example:

<# 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 being processed

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.

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 a
multiline 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 "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:  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:

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

Syntax:

send mail;

from_name = " email " ;

to = " email [ , … ] " ;

[ cc = " email [ , … ] " ; ]

[ bcc = " email [ , … ] " ; ]

[ subject = " text " ; ]

[ type = " [ html | text ] "; ]

[ body = """ text_line(s) """; | bodypage = " filepath " ; ]

Example:  Form Action to Send Email When Creating:

when creating send email;

    from_name = "support@cloudward.com";

    to = "cloudwardinc@gmail.com";

    cc = "bob@cloudward.com";

    bcc = "bill@cloudward.com";

    subject = "Your Order Status";

    type = "html"; // text or html

    body = """<# form.first_name #> <# form.last_name#> just completed an online submission.

Here is more text about this.  Blah blah blah

Here is a link to their form  

http://<# system.domain #>/?page=8contact_us_list&edit=<# form.id #>

Awesome.

Thx.

""";

Example:  Send Email using an ESPX file in the root directory for the message body

<# send email;

    from_name = "cloudward.build@gmail.com";

    to = "cloudward.build@gmail.com";

    cc = "cloudward.build@gmail.com";

    bcc = "cloudward.build@gmail.com";

    subject = "New Test HTML Email from <#[system.domain]#>";

    type = "html"; // text or html

    bodypage = "email_content?order_id=<#[url.order_id]#>";

#>

File content used in the above example: (from email_content.espx)

<# apply orders.<#[url.order_id]#> as "order"; #>

This is an email from <#[system.domain]#>!<br /><br />

The email was sent at <#[system.time]#><br /><br />

Your order total was <#[order.total as html]#><br /><br />

 -Management

Example:  Send Email within a Create Record statement

<# create new record for spreadsheet "Test Spreadsheet";

    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";

    send email;

        from_name = "cloudward.build@gmail.com";

        to = "cloudward.build@gmail.com";

        subject = "Create New Record test HTML Email from <#[system.domain]#>";

        type = "html"; // text or html

        body = """

New record created!

Thanks,

Management

""";

#>

Example:  Send Email with data from a table (in this case, an article table where we send an email for an unreviewed article that is part of a list)

<# start row #>

    <# if("<# articles.status #>"=="new") {

        send email;

            from_name = "cloudward.build@gmail.com";

            to = "cloudward.build@gmail.com";

            subject = "Unreviewed Article: <#[system.domain]#>";

            type = "html"; // text or html

            body = """<a href='<#[system.http_host]#>/article?edit=<# articles.uuid #>'><# articles.headline as html #></a>

<br /><br />

<# articles.body as html #>

""";

    } #>

    <tr>

        <td><a href='/article?edit=<# articles.id #>'><# articles.id #></a></td>

        <td><# articles.created_on #></td>

        <td><# articles.status as html #></td>

        <td><# articles.headline as html #></td>

    </tr>

<# end row #>

Round to


Use to round a value to the decimal places specified.

Syntax:

round field to number decimals;

Example:   Rounded Overall Totals in a List Footer Template

<# start footer #>

<# set overall_total to total of <# total #>;

    round overall_total to 2 decimals;

#>

Overall Total: <#[overall_total as dollars]#>

<# end footer #>

Upload file to Google Drive


Used For:  SQL Database Table Forms

EASE Form Input Attribute to direct a file to be uploaded to a Google Drive Folder.

Syntax:

<# upload file to googledrive " folder_path " for field #>

Example:  Uploading a file to a Google Drive Folder with the ID already set in var.folder_id

<input type="file" <# upload file to googledrive "/<#[var.folder_id]#>" for files.file #> />

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";
#>

File URL:

<input type="text" style="width:400px" <# files.file_drive_web_url #> /><br />

or Upload:

<input type="file" <# upload file to googledrive "/<#[var.folder_id]#>" for files.file #> />

<br /><br />

<input type="button" <# Create button #> />
<input type="button" <# Update button #> />
<input type="button" <# Delete button #> />

<# end form #>

Example: The "files.espx" list referenced above.

<# start list for files; #>

<# start header #>

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

    <tr>

        <th>ID</th>

        <th>Created On</th>

        <th>File</th>

        <th>Action</th>

    </tr>

<# end header #>

<# start row #>

    <tr>

        <td><a href='/file?edit=<# files.id #>'><# files.id #></a></td>

        <td><# files.created_on #></td>

        <td><img src="<# files.file_drive_web_url #>" /></td>

        <td><a href='/file_delete?id=<# files.id #>'

onclick='return(confirm("Confirm Delete?"))'>Delete</a></td>

    </tr>

<# end row #>

<# start footer #>

</table>

<# end footer #>

<# no results #>

<hr />No Results

<# end no results #>

<# end list #>

Create New Google Drive Folder, or get existing Google Drive Folder ID


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:

set variable to 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.

Importing and Exporting between SQL Database and Google Sheet


EASE imports and exports data using the import and export commands.

Syntax:

import [ google ]spreadsheet " name " into table_name ;

Example: Import the Google Sheet named “Test Spreadsheet” into the SQL Database table “imported_test_spreadsheet”.

<# import Google Spreadsheet "Test Spreadsheet" into imported_test_spreadsheet #>

Syntax:

export sql_table_name into [ google ]spreadsheet " name ";

Example:  Export the SQL Table “timeclock” into a Google Sheet named “Timesheet”.

<# export timeclock into sheet “Timesheet” #>