Contact Us!
303|905-4110

Cloudstreet Portal comes with a document importer that reads XML data input.

Your system will need to generate the XML as follows:

  1. One XML file for each document
  2. The filename must end in ".xml"
  3. The filename must be unique and should be salted with recognizable elements such as
    • <docType>_<divisionCode>_<customerId>_<docReference>.xml
    • Example: inv_050_1000_12345-170101.xml
  4. The file content must follow our prescribed XML schema described in this document
  5. You may transmit the XML file to the portal using
    • ftp/sftp (recommended)
    • http (post)

The XML Schema

The XML may be any valid XML however we recommend that for at least the <csp_header> container, that all tags be present even if you do not intend to use them. This makes the XML easier to compare and eliminates questions about whether containers were intentionally or unintentionally omitted. Since the tag names used within our document template articles are derived from these XML container names, having them present ensures that they will be loaded and ready for all documents, even if the tag contains nothing. This allows for fewer 'exceptions' when modeling document templates and can streamline your development of new templates.

Basic Rules for XML Values

Must be valid XML

When developing your XML files, the easiest way to validate them is to use an on-line XML validator. Simply copy/paste your XML into the validator and press 'validate'. The Validator will show you the errors in your XML or declare it to be valid. An XML validator that we use commonly is at http://www.xmlvalidation.com/

Monetary Values

You should include only the numerals and a decimal (if applicable). Do not embed currency symbols or commas. There are masking options in the template creator that will allow you to inject commas into your numeric values. Keeping the numerics pure can make it easier to format the data for presentation and allow other power functions such as filtering and ordering within Javascript.

Dates

We need dates to be presented within the XML as a valid Unix Time Date format. This means yyyy-mm-dd HH:MM:SS. You do not necessarily have to specify the time portion and in those cases, midnight will be assumed (00:00:00). However, the year must be four digit numeric, the month must be two digit numeric and the day must be two digit numeric. In the template editor, masking options will allow you to display the date in any valid date format you wish. But for the purposes of filtering and ordering, the dates should be passed in the Unix Time Date format to ensure smooth operation and full functionality. Passing dates as strings, will not allow for proper filtering or ordering of those fields and will prevent the use of features such as the pop-up calendars that are a part of the user interface.

<doc_reference>

The <doc_reference> container within the <csp_header> container must contain a value that is unique for this document. Refer to the first section of this article for a recommendation for the doc_reference.

 

Sections within the XML

The XML schema consists of two main containers:

Container Section Description
<csp_header>

The container that holds all metadata used by CloudStreet Portal to index the document within the document database and to control import and admin operations. Each of these containers has a corresponding field within the document editing and view functions on the portal web site.

We recommend that every container be defined whether you intend to use it or not.

<csp_document> The container that holds all of your document payload. You may place any valid XML within this container

 

Container Definitions

Parent Container Name Req Value Description
<csp_header> <csp_version> Y Recommended This contains the version of CloudStreet Portal's XML specification used when generating this document. Currently, the value of 1.0 is appropriate. This can be helpful over time if the cloudstreet portal xml schema is changed with upgrades to ensure that there is a clear way to separate documents generated at various cloudstreet portal releases. Currently a value of 3.0 is recommended.
<csp_header> <date_time> Y Recommended This is the time that the xml was generated. This is not the document transaction date. See date rules (above)
<csp_header> <doc_parent> Y Optional Can be used in cases where a document is a child of a parent document such as a invoice that is the child of a statement for example. This should contain the <doc_reference> value of the parent document.
<csp_header> <operation> Y Required This is the database operation to be performed. Possible values are insert, update, delete, upsert. The import utility uses this value to determine the database operation to perform against the <doc_reference> record in the database. The stock importer considers insert to be upsert. No delete operation is performed by the standard importer. We recommend setting this field to 'insert' for all insert or update operations when using the standard importer.
<csp_header> <expiration> Y Optional Not currently supported in CloudStreet Portal, this function may be implemented in the future. This will allow the host system to declare the date that the document will expire. This date can be used for taking document off-line or purging it from the database. This date must be encoded using the date rules described above.
<csp_header> <last_access_id> Y Recommended We recommend passing the value zero (0) to the importer. It will then update the last access user id to zero in the metadata. This value will be updated each time the document is accessed and the user id will be placed in this field.
<csp_header> <last_access_date> Y Recommended We recommend that this container hold the date that the xml file was generated in unix time date format yyyy-mm-dd HH:MM:SS
<csp_header> <division_code> Y Required This is the division code for this document. The division codes must be defined in the divisions table (see Site Administation > Divisions). The importer will look-up the division code in the division table and validate that it is correct before allowing the import of this document. If the division code passed is not found in the division table, the xml file will be passed into the csp_error folder.
<csp_header> <doc_type> Y Required This is the document type name (e.g., invoice, statement). This document type name must be defined in the document_type table (see Site Administration > Document Types). The importer will look-up the document type for the division passed in <division_code>. If it does not find the <document_type> passed has been defined for this <division_code> then the importer will reject the document and place the xml file into the csp_error folder.
<csp_header> <doc_reference> Y Required This is a primary key for the document and must be unique. If the <doc_reference> value already exists in the database, then the document will overlay the existing document in the document database. We recommend the construction of a doc_reference that includes division_code, document_type, customer_id, and perhaps additional values that will ensure that the <doc_reference> value is unique. See the example in the sample XML below.
<csp_header> <doc_version> Y Recommended This container can be used to hold a version number for the document passed. This is not to be confused with <csp_version> which contains the version of XML required by cloudstreetportal, this container can be used for you to track versions of the xml payload that you pass within the <csp_document> container.
<csp_header> <doc_status> Y Recommended This contains a status that you wish to assign to the document. CloudStreet Portal does not ascribe any meaning to the status. It is a field intended for user convenience and for any purpose you wish.
<csp_header> <doc_parser> Y Optional Future release. Recommend you leave this blank.
<csp_header> <assigned_to> Y Optional This is a convenience field intended to be used in cases where you wish to assign certain document or accounts to different administrators for review and management.
<csp_header> <doc_stage> Y Required This should contain the word 'published'. It is used by CloudStreet Portal to determine if a document should be on-line or off-line. Other values include 'unpublished'
<csp_header> <trans_date> Y Required This must contain the transaction date of the document. For invoices, this is normally the invoice date. Even if you have this date defined within your own container in <bpi_edoc_document> you must ALSO include that date in this container. You must follow unix date time convention of yyyy-mm-dd HH:MM:SS. If the time portion of the Date Time is omitted, midnight will be assumed.
<csp_header> <rep_reference> Y Optional If this document is associated with a representative at your company (e.g., a sales person) then place their salesperson code in this field. This will allow you to add content such as a photo of the sales person, contact information or even a skype link to your document.
<csp_header> <rep_name> Y Optional Related to <rep_reference> is the abilty to place additional information such as the full name of the representative associated with this document.
<csp_header> <reference> Y Optional Another field for your use. You may place additional information such as a project id or cost center code (or anything else) in this container.
<csp_header> <cust_id> Y Required This contains the customer id associated with the document. This value is matched to the customer id placed into the user's subscriptions. It is imperative that the <customer_id> passed in the XML exactly match the customer id in the subscription record including any zero padding or special characters. For example, 0123 does not match 123 and 1-23 does not match 123. It must be an exact match.
<csp_header> <cust_rep_ref> Y Optional This can contain the name of the person at the client (customer's) location that is associated with the document. This can be a code or a name or any other data
<csp_header> <cust_ref> Y Optional This can contain a customer provided reference associated with this document. For invoices, this is commonly the customer's purchase order or contract number.
<csp_header> <total_value> Y Recommended If there is a 'value' (monetary, point, grading or other metric) associated with this document, we recommend placing it here. Common use of this container is to place an invoice or statement total. This becomes part of document's metadata and is searchable, filterable and the user can order his documents based on value. It is highly recommended, even if you have a total within the <csp_document> container to duplicate that value into this container.
<csp_header> <doc_erp_status> Y Optional This can hold a status from the ERP system (pushed to the portal as an update to the record). It can contain the current status of the document on the ERP system. Possible values include 'open', 'unpaid', 'paid', 'canceled', 'delivered' or whatever you can imagine is applicable for this type of document.
<csp_header> <doc_checksum> Y Optional This can hold a checksum that you can generate on the ERP server. It can be retrieved within the loading script to validate that the content of the XML has not been manually altered from its original form.
<csp_header> <doc_tags> Y Optional

These are word tags that will be loaded into a tag field to facilitate searching of documents. The tags may be any value you wish to use. For example (net30,special_terms,hazmat, zip12345 etc.). Separate each tag with a comma

<csp_header> <user1_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user2_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user3_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user4_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user5_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user6_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user7_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user8_text> N Optional

An indexed field into which you can pass text.  Added at release 5.2

<csp_header> <user8_date> N Optional

An indexed field into which you can pass a date.  Added at release 5.2

<csp_header> <user9_date> N Optional

An indexed field into which you can pass a date.  Added at release 5.2

<csp_header> <notification> N Optional

Pass a notification date in the format yyyy-mm-dd HH:mm:ss to the portal.  By not sending this container or and empty container, the portal will mark the document that users subscribing to it should be notified.  After the users are notified, the portal will automatically update this field with the date and time that the notifications were sent to users.  If you do not want notifications to be sent to users (for example, when an update to the document is sent to the portal), then pass in a date and time in the format specified above and it will prevent the portal from sending notifications to subscribed users.

<csp_header> <user_notes> N Optional

Normally, user notes are entered by the user on the portal and you will not pass user_notes from the server.  If you do not pass the <user_notes> container in the XML payload, or if you pass the container that is empty, then the user_notes that exist in the database on the portal will be preserved even when a document is updated.  If you pass a value within the <user_notes> container, then it will overwrite the user_notes field in the portal database.

 

Sample XML for an Invoice

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document_root>
<csp_header>
<csp_version>1.0</bpi_edoc_version>
<date_time>2017-05-25 23:00:09</date_time>
<doc_reference>inv.1390.11-754140</doc_reference>
<doc_parent></doc_parent>
<operation>insert</operation>
<expiration></expiration>
<last_access_id>0</last_access_id>
<last_access_date>2017-05-25 23:00:09</last_access_date>
<division_code>064</division_code>
<doc_type>invoice</doc_type>
<doc_version>v2017-05-25 23:00:09</doc_version>
<doc_status>0</doc_status>
<doc_parser></doc_parser>
<assigned_to>436</assigned_to>
<doc_stage>published</doc_stage>
<trans_date>2017-05-25 00:00:00</trans_date>
<rep_reference>436</rep_reference>
<rep_name>436</rep_name>
<reference>436</reference>
<cust_id>1390</cust_id>
<cust_rep_ref></cust_rep_ref>
<cust_ref>5061</cust_ref>
<total_value>286.02</total_value>
<doc_erp_status></doc_erp_status>
<doc_checksum></doc_checksum>
<edoc_tags></edoc_tags>
</csp_header>
<csp_document>
<invheader>
<store_no>11</store_no>
<store_name>Smyth - Hillsboro</store_name>
<store_addr>220 West Main Street</store_addr>
<store_addr2></store_addr2>
<store_city>Hillsboro</store_city>
<store_state>OH</store_state>
<store_zip>45133</store_zip>
<store_country>USA</store_country>
<store_email></store_email>
<store_phone>9373935737</store_phone>
<store_fax></store_fax>
<store_user1></store_user1>
<store_user2></store_user2>
<store_user3></store_user3>
<cust_no>211-020</cust_no>
<cust_name>WEST MAIN AUTO REPAIR</cust_name>
<cust_addr>949 WEST MAIN STREET</cust_addr>
<cust_addr2></cust_addr2>
<cust_city>HILLSBORO</cust_city>
<cust_state>OH</cust_state>
<cust_zip>45133</cust_zip>
<cust_country>USA</cust_country>
<cust_email></cust_email>
<cust_phone>9373935562</cust_phone>
<cust_fax></cust_fax>
<cust_po>5061</cust_po>
<inv_no>11-754140</inv_no>
<inv_date>2017-05-25 00:00:00</inv_date>
<inv_print></inv_print>
<inv_writer>436</inv_writer>
<inv_freight></inv_freight>
<inv_labor></inv_labor>
<inv_tax>0.00</inv_tax>
<inv_subtotal>0.00</inv_subtotal>
<inv_total>286.02</inv_total>
<inv_total_qty>1</inv_total_qty>
<inv_total_core>0.00</inv_total_core>
<inv_total_list>579.62</inv_total_list>
</invheader>
<invdetail>
<invline>
<qty></qty>
<line></line>
<part_no></part_no>
<desc></desc>
<core_chg></core_chg>
<list_price></list_price>
<net_price></net_price>
<ext_price></ext_price>
<comment>VEHICLE 34240 - 2007 CHEVROLET TAHOE V8-5328cc 5.3L F/I Vin J</comment>
<url1></url1>
<url2></url2>
<url3></url3>
<user1></user1>
<user2></user2>
<user3></user3>
</invline>
<invline>
<qty>1</qty>
<line>DPH</line>
<part_no>FG0808</part_no>
<desc>Fuel Module</desc>
<core_chg></core_chg>
<list_price>579.62</list_price>
<net_price>286.02</net_price>
<ext_price>286.02</ext_price>
<comment></comment>
<url1></url1>
<url2></url2>
<url3></url3>
<user1></user1>
<user2></user2>
<user3></user3>
</invline>
</invdetail>
</csp_document>
</document_root>

<p>Cloudstreet Portal works by accepting XML documents from an external source then importing them into the CloudStreet Portal database.  Access to the documents is controlled via a security mechanism known as subscriptions.  An export of the subscriptions table will provide you with the information necessary to determine which documents should be uploaded to the web site as users register for the site.  By uploading only the documents to which users are subscribed, you can determine which documents to send to CloudStreet Portal.  The other approach is to begin sending all documents and then review subscriptions to determine which documents can be removed from CloudStreet Portal.  The choice is up to you.</p>
<p><strong>The Procedure</strong></p>
<ol>
<li>You must be a site administrator to perform this function.</li>
<li>Login to your CloudStreet Portal web site</li>
<li>Choose Site Administration &gt; Site-Wide Subscriptions from the menu</li>
<li>At the top of the subscriptions list page, you will see a toolbar</li>
</ol>
<p><img src="/images/cloudstreet/Help/subscriptions_list2.PNG" width="75%" /></p>
<p>The <img src="/images/cloudstreet/Help/subscriptions_csv.PNG" alt="" />button will export the selected scriptions to excel and allow you to download the list.</p>
<p><img src="/images/cloudstreet/Help/export_CSV.PNG" width="391" height="274" /></p>
<p> <img src="/images/cloudstreet/Help/subscriptions_save.PNG" width="540" height="403" /></p>
<p>Once it opens in excel, the data may be explored but it may open all in one column instead of broken into individual columns like this:</p>
<p><img src="/images/cloudstreet/Help/subscriptions_inexcel.PNG" width="75%" /></p>
<p> In excel, you can break the data into individual columns by <strong>selecting column A</strong> (where the data is stored), then choosing the <strong>Data</strong> menu then <strong>Text to Columns</strong>.</p>
<p><img src="/images/cloudstreet/Help/excel_textToColumns.PNG" width="50%" /></p>
<p>Choose the <strong>Delimited</strong> option then press <strong>Next</strong>.</p>
<p><img src="/images/cloudstreet/Help/subscriptions_delimiter.PNG" width="50%" /></p>
<p>Press Finish and the data will be broken into individual columns.</p>
<p>A program can be written to parse this CSV output then to compare it with the the controls on the ERP server the determine which division, document type and customers should have their documents uploaded to the cloudstreet portal server.</p>
<h2>Another use for Subscriptions Export</h2>
<p>Another use for this export would be as a feed for a bulk mail or email system.  You can extract the required information to generate outbound messages using the site email tool or another tool of your choosing.</p>
<p> </p>

Overview

CloudStreet Portal version 3 incorporates a new helper function that can notify your host when a portal user requests a subscription for a divisionCode-customerId-documentType combination that is not currently on file in the portal's document database.

To use this feature, you can use your FTP access to your FTP account then simply create a new directory called csp_notifications (if it is not already present).

When CloudStreet Portal sees that this directory name exists in your FTP account, it will automatically write an xml file into that directory each time an administrator on the CloudStreet Portal site approves a subscription for a divisionCode-customerId-documentType combination that does not already exist in the CloudStreet Portal document database.

Your host can poll this directory using FTP and when it finds an xml file, it can import and delete the document from the directory. The XML file contains all of the information your host may need in order to push the required documents to the portal.

Example of the XML file that is created in the csp_notifications directory:

<?xml version="1.0"?>
<notification>
<timeDate>2017-07-05 20:39:43</timeDate>
<type>subscription</type>
<event>approval</event>
<subscriberId>1001</subscriberId>
<subscriberName>testuser</subscriberName>
<subscriberUsername>testuser</subscriberUsername>
<subscriberEmail>This email address is being protected from spambots. You need JavaScript enabled to view it./subscriberEmail>
<divisionCode>030</divisionCode>
<divisionName>Selma</divisionName>
<documentType>invoice</documentType>
<customerId>12345</customerId>
<myCompanyName>Bruce Decker</myCompanyName>
<reachMeAt>303.905.4110</reachMeAt>
<customerNotes>Please let me in</customerNotes>
<approvedByUserId>840</approvedByUserId>
<approvedByUserName>bdecker</approvedByUserName>
<approvedByName>Bruce Decker</approvedByName>
<advice>Zero documents in database for this divisionCode-customerId-documentType combination. Consider importing them into Cloudstreet Portal.</advice>
</notification>

Container Purpose/Description
<type> This will contain a notification type. In the example above, Cloudstreet Portal wrote the value 'subscription'.
<divisionCode> This is the division code related to this subscription notification
<documentType> This is the documentType related to this subscription notification
<customerId> This is the customerId related to this subscription notification
<advice> This provides advice or summary information related to this subscription notification

Normal Sequence of Events

  1. A user adds a new subscription request for a specific division code, document type and customer ID to their MySubscriptions tab in the portal as a pending_approval status subscription request.
  2. A portal administrator approves the subscriptions.
  3. Cloudstreet Portal performs a series of checks to determine if CSP should place a notification file into the csp_notification directory. These checks are:
    • The 'Host Update' field in the subscriptions field must be blank
    • The Subscription status must be 'approved'
    • There must not be any documents already on file in the document database for the combination of DivisionCode, DocumentType and CustomerId
    • The directory in your FTP account called 'csp_notification' must exist
  4. If all of the above criteria are met, then CSP will generate an XML record and write it into the csp_notification directory. Otherwise, it will skip the notification write logic and simply save the subscription.
  5. The host should periodically poll the csp_notification directory looking for new files.
  6. When the host finds a file in the cspc_notification directory, it should download it via FTP to the host then host MUST delete the file from the csp_notification directory.
  7. The host should parse the XML to gather the divisionCode, CustomerId and DocumentType information.
  8. The host will generate the requested XML documents for the subcription and place them in the ftp account's csp_in directory (e.g., csp_in)
  9. The host or administrator will import the documents into CloudStreet Portal using one of the supported document import methods.
  10. The portal user will now be able to access the documents.

 

The response time between subscription submission and document availability will vary depending on:

1) The time required to approve the subscription

2) The polling interval of the host to the csp_notification directory

3) The time required for the host to generate the XML documents for the portal

4) The time required to transmit the generated XML documents to the portal

5) The time required to commence the document import function on the portal

6) The time required to import the documents into the portal

 

Tips

Forcing a notification to be sent from Cloudstreet Portal

The criteria defined above is used by CSP to determine if a notification record should be sent. The first criterion is to check to see if the field 'Host Update' has been set to a valid date time value. If the field contains a value, then CloudStreet Portal assumes that the host has already been updated. To override this check, simply clear the value from the Host Update field and save the subscription. Assuming the other criteria are met, the xml file will be regenerated into the csp_notification directory and the Host Update field will be set to the current date and time to indicate that the subscription notification has been sent.

Overview

CloudStreet Portal version 3 includes a helper function that will tell you which subscribers have requested to be notified when new documents are uploaded to the portal. This allows you to then create email notifications and send them to these subscribers. The system works like this:

  1. At an interval you choose (usually 10-15 min), the system will query the database looking for any new documents that have been uploaded.
  2. The system will then scan the subscription records looking for subscriptions where the user has asked to be notified when new documents matching the subscription have been added.
  3. If it finds subscriptions whereby users asked to be notified of new documents and there are new documents for those subscriptions, then an XML file will be generated and placed into the csp_notifications directory in the format of "notifyNewDoc_yyyymmdd_hhmmss.xml:
  4. This XML file will contain all of the details about each 'hit' including full user information (including email address) and all of the relevant information about the new document (e.g., doc reference, customer reference, database row number, document type, transaction date, total value, etc.)
  5. The XML file's <notice> containers will contain all of the information you will need to generate emails to your users.
  6. The <notice> containers in the file are ordered in a way that makes it easy to iterate the XML containers in top-down order knowing that all notifications for a user will be grouped together in order and not scattered throughout the XML file. The ordering is:
    1. by subscriber id
    2. then by division code
    3. then by customer id
    4. then by document type
    5. then document id
    6. then by document reference number
    7. then by total value
  7. Note: Ordering criteria 6 and 7 were added to accommodate a future project to allow administrator selection of ordering criteria and is largely ignored in this release)
  8. Once the XML file is written to the notifications directory, the document in the database is marked so that it will not be placed into the next notification XML record (you won't been told about it again.)
  9. Your mission is to poll the notifications directory (as you already do), pickup the XML file(s) and then iterate the XML and send out emails as you wish (using the information provided to you in the XML and, optionally, other information you may wish to collect and include from your ERP server.)

 

Example (excerpted)

<?xml version="1.0"?>
<NOTIFICATION>
<timestamp>2018-03-17 22:52:11</timestamp>
<notices>
<notice>
<notice_type>notifySubscriberOfNewDocument</notice_type>
<action>NOTIFY_EMAIL</action>
<subscriber_id>672</subscriber_id>
<name>CloudStreet Master</name>
<username>bdecker</username>
<email>This email address is being protected from spambots. You need JavaScript enabled to view it.</email>
<division_code>002</division_code>
<division_name>Division 002</division_name>
<customer_id>00005051</customer_id>
<document_type>invoice</document_type>
<id>10</id>
<doc_reference>002.00005051.54795</doc_reference>
<cust_ref>618019014</cust_ref>
<total_value>4364.80</total_value>
<trans_date>2003-11-12 00:00:00</trans_date>
</notice>
<notice>
<notice_type>notifySubscriberOfNewDocument</notice_type>
<action>NOTIFY_EMAIL</action>
<subscriber_id>672</subscriber_id>
<name>CloudStreet Master</name>
<username>bdecker</username>
<email>This email address is being protected from spambots. You need JavaScript enabled to view it.</email>
<division_code>002</division_code>
<division_name>Division 002</division_name>
<customer_id>00005443</customer_id>
<document_type>invoice</document_type>
<id>9</id>
<doc_reference>002.00005443.179612</doc_reference>
<cust_ref>677028/993609306</cust_ref>
<total_value>3896.00</total_value>
<trans_date>2016-12-21 00:00:00</trans_date>
</notice>
<notice>
<notice_type>notifySubscriberOfNewDocument</notice_type>
<action>NOTIFY_EMAIL</action>
<subscriber_id>674</subscriber_id>
<name>Jim Sales</name>
<username>jsales</username>
<email>This email address is being protected from spambots. You need JavaScript enabled to view it.</email>
<division_code>002</division_code>
<division_name>Division 002</division_name>
<customer_id>00005051</customer_id>
<document_type>invoice</document_type>
<id>10</id>
<doc_reference>002.00005051.54795</doc_reference>
<cust_ref>618019014</cust_ref>
<total_value>4364.80</total_value>
<trans_date>2003-11-12 00:00:00</trans_date>
</notice>
<notice>
<notice_type>notifySubscriberOfNewDocument</notice_type>
<action>NOTIFY_EMAIL</action>
<subscriber_id>674</subscriber_id>
<name>Jim Sales</name>
<username>jsales</username>
<email>This email address is being protected from spambots. You need JavaScript enabled to view it.</email>
<division_code>002</division_code>
<division_name>Division 002</division_name>
<customer_id>00005403</customer_id>
<document_type>invoice</document_type>
<id>8</id>
<doc_reference>002.00005403.54796</doc_reference>
<cust_ref>141557</cust_ref>
<total_value>3505.00</total_value>
<trans_date>2003-11-12 00:00:00</trans_date>
</notice>
</notices>
</NOTIFICATION>

 

Format and ordering

The XML will be formatted as shown in the example above. Multiple <notice> containers may exist depending on the number of new documents and the number of subscribers for the document type that have requested notification in their subscription record(s).

See ordering criteria as defined above.

Triggering event

In the current release, the notifyNewDoc notification records is produced by a cron job that is set to run on an interval you can specify (notify your CloudStreet Portal account manager). In a future release, this event may be triggered to automatically execute at the end of any document import event.

Removal of Notification

You are responsible for polling and removing notification records. This can be performed using your FTP Client. Use caution and do not remove all documents or all notifications from the notifications directory.

 

Overview

The Joomla Framework on which CloudStreet Portal is based allows the web administrator to create web pages using a simple web-based page editor. Each page is known as an article. All of the help pages and the splash page are simple articles that you can edit if you have administrator privileges. There are two primary ways to create and edit articles:

1) Login to the back-end of the web site (assuming you have permissions) and create or edit articles using the 'Content -> Article' menu.

2) Navigate to a page and click the small 'paper and pencil' icon in the upper right corner of the page to bring that page into the editor

CloudStreet Portal uses these articles as templates for displaying your document information to an end-user. You can 'paint' a document page to suit your requires (examples, Invoice, Statement, etc.) Into the article (template) you will put special [placeholder] tags to identify where fields from your document will be injected to the article. Placeholders are indentified in your page by surrounding them with an opening and closing square brackets. At run time, CloudStreet Portal will load the document data for the document and then it will replace each [placeholder] with the text from the document.

You as a document designer simply need to know the [placeholder] names within the document.

Placeholders

There are three types of placeholders available to you as a form designer:

Automatic Placeholders

Automatic placeholders perform tasks such as providing automatic numbing of table rows.

CloudStreet Placeholders

These are placeholders whose values are set by the CloudStreet Portal engine and that are available for you to use within your document templates

The bpi_edoc_header class exposes the header containers for the referenced document

Class Placeholder From XML Container Description
csp_header [csp_header.date_time] <date_time>  
csp_header [csp_header.expiration] <expiration>  
csp_header [csp_header.last_access_id] <last_access_id>  
csp_header [csp_header.doc_type] <doc_type>  
csp_header [csp_header.doc_version] <doc_version>  
csp_header [csp_header.doc_status] <doc_status>  
csp_header [csp_header.doc_parser] <doc_parser>  
csp_header [csp_header.trans_date] <trans_date>  
csp_header [csp_header.rep_ref] <rep_ref>  
csp_header [csp_header.reference] <reference>  
csp_header [csp_header.cust_id] <cust_id>  
csp_header [csp_header.cust_rep_ref] <cust_rep_ref>  
csp_header [csp_header.cust_ref] <cust_ref>  
csp_header [csp_header.total_value] <total_value>  
csp_header [csp_header.doc_xml] <doc_xml>  
csp_header [csp_header.assigned_to] <assigned_to>  
csp_header [csp_header.stage] <stage>  
csp_header [csp_header.doc_reference] <doc_reference>  
csp_header [csp_header.operation] <operation>  
csp_header [csp_header.tags] <tags>  
csp_header [csp_header.division_code] <division_code>  
csp_header [csp_header.doc_erp_status] <doc_erp_status>  

The Division Class exposes information about the division for the referenced document. This values are not passed to CloudStreet Portal via XML but instead are the values that you have created for a division using the 'division' menu option in the administrator menu.

Class Placeholder Description
division [division.id] The cloudstreet internal id for the referenced division
division [division.date_time] The date/time the division records was last updated.
division [division.division_code] The external division code sent to CloudStreet Portal
division [divison.division_name] The full name of the division
division [division.description] Full description of the division
division [division.address_1] Address line 1 of the division
division [division.address_2] Address line 2 of the division
division [division.city] City of division
division [division.state] State of division
division [division.zip] Zip of division
division [division.phone] Phone number of division]
division [division.fax] Fax number of division
division [division.email] Email address of division
division [division.division_url] A web url of the division
division [division.logo_url] A url to a png, jpg or gif image that can be used in an image url in the template editor
division [division.image_url] Another image url that can be used specifically for this division
division [division.notes] The content entered into the notes field for this division.

 

Document-Specific Placeholders

Document-specific placeholders are initialized by your loading scrupt and generally explose the specific containers of your XML document but may contain other placeholders that can perform more advanced functions such as reaching back into the ERP system for real-time updates or status.

See your CloudStreet Portal Administrator for documentation for your specific documents.

 

EXAMPLE TEMPLATE

Industrial Recycling Services
 
[invheader.div_name] [[bpi_edoc_hdr.division_code]]
[invheader.div_addr]
[invheader.div_city], [invheader.div_state] [invheader.div_zip]
[invheader.div_phone]
Manufacturing Plant and Office
[invheader.div_city], [invheader.div_state]
[invheader.div_addr]
[invheader.div_city]
[invheader.div_state]
CUST NO
[invheader.cust_no]    
SOLD TO
[invheader.cust_name]
[invheader.cust_addr1]
[invheader.cust_addr2]
[invheader.cust_city], [invheader.cust_state] [invheader.cust_zip]

SHIP TO

[invheader.shipto_name]
[invheader.shipto_addr1]
[invheader.shipto_addr2]
[invheader.shipto_city], [invheader.shipto_state] [invheader.shipto_zip]

 

 

DATE YOUR ORDER NO In consideration for the extension of this credit, the vendee agres to pay all costs of collecting the amount of this invoice including a reasonable attorney's fee and further agrees to pay a 1-1/2 % service charge per month for the unpaid balance due. TERMS INVOICE NO.
[invheader.inv_date;frm='mm/dd/yy'] [invheader.order_no]   [invheader.inv_terms] [invheader.inv_no]

 

{artdatatable defaultRowCount=500}

Item DELV. TICKET QTY. SHIPPED DESCRIPTION PRICE Total
[invdetail.#] [invdetail.item_deltick;block=tr] [invdetail.item_qty] [invdetail.item_desc] [invdetail.item_price] [invdetail.item_extprice]

{/artdatatable}

 

PAY FROM THIS INVOICE NO STATEMENT RENDERED REMIT TO SUB TOTAL [invheader.inv_subtotal]
  [invfooter.inv_remit_name] TAX  
 
[invfooter.inv_remit_addr]
[invfooter.inv_remit_city], [invfooter.inv_remit_state] [invfooter.inv_remit_zip]

 

TOTAL AMOUNT [invheader.inv_total]

Placeholder Formatting Modifiers

Placeholders will inject dynamic data from the referenced document into the template. Sometimes, data being injected may not be in the precise format you desire for end user ease of use. For example, dates are generally stored in unix time/date format ( yyyy-mm-dd HH:MM_SS). This format is foreign to not technical users of the documet so it may be desirable to reformat the date into something more palateable to the end-user. In situations like this, formatting codes can be added to the placeholder to modify the display of the placeholder's data.

Placeholder Documentation

TinyButStrong (TBS) -- The little content engine that could.

CloudStreet Portal provides a Joomla Plug-in known as Tiny But Strong (TBS). The TBS templating engine allows CloudStreet Portal to extend the normal capabilities of Joomla to work more easily and seamlessly with dynamic data you are providing from your ERP host. In the documentation below, you will see references to TBS. This is referring to the CloudStreet Portal TBS Plug-in that allows the placeholder (aka tag) system to function.

 

A field is a placeholder (aka tag) which has to be replaced by a single data item. Fields must have a name to identify it (which does not have to be unique) and can have parameters to modify the displayed value.

Syntax: TEMPLATE ... [FieldName{;param1}{;param2}{;param3}{...}] ... TEMPLATE

Element Description
FieldName The name of the Field.
Warning: names that begin with onload, onshow and var.are reserved for automatic fields.
param1 Optional. One or more parameters from the list below and separated with ';'.
Some parameters can be set to a value using the equal sign '='.
Example: frm=0.00
If the value contains spaces, semicolons or quotes, then you can use single quotes as delimiters.
Example: frm='0 000.00'
To specify a literal single quote, escape it with a second single quotes.
Example: ifempty='hello that''s me'

A parameter can contain embedded TBS fields, but only under special circumstances:
- the embedded field is merged before the parent field,
- the embedded field if a [var] field placed into a parameter file, script, if, then, else or when.
In the other cases; the embedded TBS field will not be processed and will be taken as is, like text.
Examples:
[x;strconv=[var.y]] : [var.y] will not be merged and parameter "strconv" will have an unvalid value.
[x;if [var.y]=1] : [var.y] will be correctly merged and the "if" condition will be correctly evaluated.

 

Field's parameters:

Parameter Description
strconv=val

Ennables you to modify the string conversion for this field only. Note that the string conversion used by default for all fields is the charset option. It is often corresponding to an Xml/Html charset but not necessary.

You can specify several values using seperator '+'. Example : strconv=yes+js

The values can be one of the following keywords:

yes (default value) Performe the default special string conversion, including new lines.
no No special string conversion. Useful to modify Xml/Html source.
nobr Let the default string conversion, except new lines (useful for <pre> tags for example).
wsp Preserve white spaces (useful for spaces at the beginning of lines).
esc No special string conversion and double the single quote characters (').
js Convert the data item to a string that can be inserted between JavaScript text delimiters.
url Convert the data item to a string that can be inserted inside an URL. (supported since TBS version 3.5.2)
look Deprecated. Performs the default string conversion only if no Xml/Html entities are found inside the data item.

Versioning: Parameter strconv is supported since TBS version 3.8.0. It is an alias of parameter htmlconv which was misnamed and becomes deprecated.

. (dot)

If the data item is empty, then an unbreakable space is displayed. Useful for cells in tables.

ifempty=val

If the data item is empty, then it is replaced with the specified value.

att=path

Move the current field into an attribute of an XML/HTML tag before it is merged. This parameter is very useful when it is too difficult for the template designer to place a TBS field into an attribute.

The value path must indicate the place of the attribute relatively to the current field.
If the attribute doesn't exist in the specified tag, then it is created.
If the attribute already exists in the specified tag and it has already a value, then the field replaces all the current value.
You can chose to place the field as an added value using parameter attadd.
You can complete the attribute's value by applying a mask to it using parameter ope=msk.
You can delete the attribute in case of empty value using parameter magnet=#.

Syntax for value path: att=[+][tag1+tag2+tag3+...#]attribute or att=.
By default the attribute is searched before the current field. But if '+' is the first character of the path, then it is searched after. If no tag list is specified, then the attribute is looked at in the first tag met in the search direction. If a tag list is used, tag1 is search first, then tag2, ... regardless of the direction of the search (before/after). You can put a tag name between one or several bracket levels in order to specify that the searched tag must embed the current field.

If you set att=. then TBS will assume that the TBS fields is already positioned inside the target attribute.

Examples:

[onshow.x;att=class] moves into attribute 'class' of the first tag placed before.
[onshow.x;att=div#class] moves into attribute 'class' of the first <div> placed before.
[onshow.x;att=+div#class] moves into attribute 'class' of the first <div> placed after.
[onshow.x;att=((div))#class] moves into attribute 'class' of the second embedding <div> placed before.
[onshow.x;att=table+div#class] moves into attribute 'class' of the first <div> after the first <table> placed before.

Notes:

  • Before version to 3.10.0, method MergeBlock() could not move a TBS field over another field placed after it. This makes a TBS error to occur.
  • When the attribute has no value before the field is moved, then chooses what string delimiter to use regarding other attributes (XML/HTML accepts both (") and (')). You can force the delimiter you need using option att_delim.

Versioning: Parameter att is supported since TBS version 3.5.0

attadd

To be used with parameter att. Indicate that the field is added into the attribute's value, instead of being replacing the attribute's value. Please note that the added value won't be simply concatenated with previous values, it will be added with a space character separator in order to perform an adding to the meaning of attributes.

Example:

<div>[onshow.x;att=class;attadd]
in this example, if we have $x='style2' then we obtain <div>

There is no way for now to simply concatenate the field's value with the previous attribute's value. But instead, you can use parameter ope=msk in order to apply a mask to the field's value.

Example:

<div>[onshow.z;att=class;ope=msk:style*]
in this example, if we have $z='2' then we obtain <div>

Versioning: Parameter attadd is supported since version 3.5.0

atttrue
or
atttrue=value

To be used with parameter att. Indicates that the attribute (indicated with parameter att) must be managed as a boolan XHTML/HTML attribute. I.e. it is either present in the tag with the format attribute="attribute" in order to mean TRUE, or ommited in the tag in order to mean FALSE.

If atttrue is set with a given value, then the boolean attribute will be TRUE (present) if the field is equal to this value, otherwise it will be FALSE (omitted).
If atttrue is set with no value, then the boolean attribute will be TRUE (present) if the field's value is non empty, and it will be FALSE (omitted) if the field's value is empty.

Examples:

<input type="checkbox">[onshow.accept;att=selected;atttrue=1]

Versioning: Parameter atttrue is supported since TBS version 3.6.0

magnet=tag
or
magnet=expr
or
magnet=#

Assign a magnet XML/HTML zone to the field. A magnet tag is kept as is when the field has a value, and is deleted when the field is null or empty string.

Parameter magnet supports the same syntax as parameter block, i.e. that expr must be an XML/HTML tag or a TBS extended block expression.
It also support the syntax magnet=# which means that the magnet zone is the HTML/HTML attribute wherein the TBS field is embedded.

Example:

(<a href="/[onshow.link;magnet=a]">click here</a>)
Result for $link='www.tbs.com': (<a href="/www.tbs.com">click here</a>)
Result for $link='': ()

By default, the magnet XML/HTML zone should be delimited by a pair of opening-closing tags (like <a></a>) which first tag is placed before the TBS fields. But this can be changed using parameter mtype (see below).

Remark:

the parameters if, then, else are processed before parameter magnet.

Versioning:

  • Since version 3.3.0, parameter ope has keywords (nif, minv, mok and mko) that improve parameter magnet.
  • The sytax magnet=# without parameter att is supported since version 3.8.0.
mtype=val

To be used with parameter magnet. Define the magnet type.

Value Magnet behavior when field is null or empty string
m*m That's the default value. Delete the pair of tags that surrounds the TBS field. Everything that is between them is deleted also. The field can be put inside one of the tags.
Example:
(<a href="/[onshow.link;magnet=a]">click here</a>)
Result for $link='www.tbs.com': (<a href="/www.tbs.com">click here</a>)
Result for $link='': ()
m+m Delete the pair of tags that surrounds the field, but keeping everything else that is between the tags.
Example:
(<a href="mailto:[blk.email;magnet=a;mtype=m+m]">[blk.name]</a>)
Result for $email=This email address is being protected from spambots. You need JavaScript enabled to view it.': (<a href="mailto:This email address is being protected from spambots. You need JavaScript enabled to view it.">MyName</a>)
Result for $email='': (MyName)
m* Delete the single tag that is before the field, and everything that is between the tag and the field.
Example 1: <img href="/[onshow.link;magnet=img;mtype=m*]">
Example 2: <br> [onshow.address;magnet=br]
*m Delete the single tag that is after the field, and everything that is between the tag and the field.
Example: [onshow.address;magnet=br;mtype=*m]<br>
enlarge

Enlarge the bounds of the Field up to the bounds of the commentary Html tags which surround it, or up to another specified couple of XML/HTML tags.

Example:

xxx <!-- [myfield;enlarge] here some comments --> yyy

or

xxx <div> [myfield;enlarge=div] here some comments </div> yyy

are strictly identical to:

xxx [myfield] yyy

This parameter is particularly useful for the template designing when you are using a Visual HTML Editor (such as Dreamweaver or FrontPage).

Versioning:

  • Parameter enlarge is supported since version 3.8.0. It is an alias of parameter comm which was misnamed and becomes deprecated.
  • Parameter comm is available for other XML/HTML tags since 3.0.
noerr

Avoid some of the Error messages. When a message can be cancelled, it is mentioned in the message.

file=filename

Replace the field with the contents of the file.

Filename can be a string or an expression.
You can use the keyword [val] inside the expression to insert the current data item.
You can use [var] fields inside the expression.
If parameter script is used by omitting the filename value (example: [onshow.file;script;subtpl]), then the field's value is used for the file name.
If the file is not found, then it will be searched in the folder of the last loaded template (since version 3.2.0).

Examples:

[onload;file=header.html]
[onload;file=[var.filename]]

If filename is an empty string, then no error message is displayed, it is like parameter file is ignored. This can be used to manage conditional insertion.

Example:

[onload;file=[var.insert;if [val]=1;then 'header.html';else '']]

You will found more details about this parameter in the chapter Subtemplates.

See also: getpart and script

getpart=taglist

To be used with parameter file or script.
Indicates that not all the file contents is loaded but only some XML/HTML parts of it defined with the tag list. The tags of the list must be separated with plus (+), and placed between parentheses if you want the tags themselves to be retrieved with their content. If the file has several XML/HTML part of a tag, all those parts will be automatically concatenated. If parameter getpart is used without value, then the <body> tag is taken by default.

Example:

[onload;file=header.htm;getpart=(script)+(style)+body]

Versioning:

  • Parameter getpart is supported since version 3.8.0. It is an alias of parameter getbody which was misnamed and becomes deprecated.
  • Parameter getbody is supported since version 3.0. In previous versions, it was automatically processed when using parameter file. Now it becomes explicit.
  • The tag list is supported since version 3.5.0. Before this version, the value of getbody can be only one tag without parentheses.
store=taglist

To be used with parameter file or script.
It works like parameter getpart but the recovered part is buffered into a store instead of being directly displayed. This enables you to store some parts of the sub-template and display them elsewhere in the main template.
A store can be displayed using a special automatic field using the key store and the name of the store.
By default the name of a store is 'default', but it can be changed using parameter storename.

Parameter store is useful to use a sub-template as a component that will spread several contents in the main template.

Example:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>The main template</title>
  [onshow.store.default]
</head>
<body>
  Here is a component :
  <div>
    [onload;file=component1.htm;getpart=body;store=(script)+(style)]
  </div>
</body>
</html>

Versioning: Parameter store is supported since version 3.8.0.

storename=name To be used with parameter store. Parameter storename changes the name of the store. See parameter store.

Versioning: Parameter store is supported since version 3.8.0.

rename old=new

To be used with parameter file or script. Renames TBS blocks and fields in the subtemplate before it is inserted. You can define several block to rename by separate them with coma. If a new name is an empty string then the old block is deleted by merging it with an empty array.

This parameter is useful when you want to use the same subtemplate several times in the main template.

Example:

Address 1: [onload;file=address.htm]
Address 2: [onload;file=address.htm;rename town1=town2,zip1=zip2,email=]

Versioning: parameter rename is supported since TBS version 3.5.1.

See chapter 'Subtemplates' for more details about subtemplates.
script=filename

Execute the Php script just before replacing the TBS field.

Filename can be a string or an expression.
You can use the keyword [val] inside the expression to insert the current data item.
You can use [var] fields inside the expression.
If parameter script is used by omitting the filename value (example: [onshow.file;script;subtpl]), then the field's value is used for the file name.
If the file is not found, then it will be searched in the folder of the last loaded template (since version 3.2.0).

* Take care that in your script variables will be obsiously local instead of global. This is because the script is called from a method. In order to define or reach global variables in your script, you have to use the Php instruction global or the array $GLOBAL.
* gives to you predefined local variables that can be used in your script:
- $CurrVal refers to the current value of the field. It can be modified.
- $CurrPrm refers to the array of field's parameters.
- $this refers to the current instance. (See parameter subtpl for good usage)
* If the filename expression (or the value of the field) return an empty string (''), then parameter script is ignored and no error occurs. You can use this behavior in order to use a conditional insertion.

See chapter 'Subtemplates' for more details about how to use this parameter in subtemplate mode.

subtpl

To be used with the parameter script or parameter onformat. Activate the subtemplate mode during the script or function execution.

See chapter 'Subtemplates' for more details.

if expr1=expr2

Display the data item only if the condition is verified, otherwise display nothing unless parameter then or else are used.

Supported operators are:

= or == equal
!= not equal
+- greater than
+=- greater than or equal to
-+ less than
-=+ less than or equal to
~= match the regular expression (since TBS version 3.0)

Both expr1 and expr2 must be string or numerical expressions.
You can use the keyword [val] inside the expression to insert the current data item.
You can use [var] fields inside the expression.
The expressions may contain other fields, but you have to make sure that they are merged before the containing field.
Since version 3.0, it is also possible to define several couples of if/then in the same field.

See parameters then and else for some examples.

then val1

If the parameter if is defined and its condition is verified, then the data item is replaced with val1.

Since version 3.0, it is also possible to define several couples of if/then in the same field.

Examples:

[onshow.image;if [val]='';then 'image0.gif']
[onshow.x;if [val]=1;then 'one';if [val]=2;then 'two';else 'more']

You can use the keyword [val] inside the expression to insert the current data item.
You can use [var] fields inside the expression.

else val2 If the parameter if is defined and its condition is not verified, then the data item is replaced with val2.
Example:
[onshow.error_id;if [val]=0;then 'no error';else 'error found']
You can use the keyword [val] inside the expression to insert the current data item.
You can use [var] fields inside the expression.
protect=val

Enables you to protect or unprotect the data item to be merged by replacing the characters '[' with their corresponding XML/HTML code '&#91;'. The value val can be one of the following keywords:
  yes: (default value) data item is protected.
  no: data item is not protected.

By default, all data merged with a template is protected except if it's a file inclusion. It is strongly recommended to protect data when it comes from free enter like on a forum for example.

Nevertheless, it is possible to disable the protection by default if you set TBS option 'protect' to false.

ope=action

Makes one or several operations on the value to merge. You can define several operations to be processed in order by separating them with coma (,).

Example:

[onshow.x;ope=add:-1,mod:10]

Supported operations are:

max:n Limit the text string to a maximum of n characters. If the string is cut, then its end is replaced with dot lines '...'.
Example: [onshow.caption;ope=max:10]
  • Add parameter maxhtml to indicate that the value before merging can contain Html characters. Only characters starting with "&" end ending with ";" will be considered. HTML entities are not considered as HTML characters.
  • Add parameter maxutf8 to indicate that the value before merging can contain UTF8 characters. Versionning: maxutf8 is supported since TBS version 3.5.2.
  • Add parameter maxend to change the cutting symbol.
Example: [onshow.caption;ope=max:10;maxhtml;maxend='+']
mod:n Apply the modulo n to the value to merge. Example: [onshow.numlig;ope=mod:7]
add:n Add the numeric n to the value to merge. Example: [onshow.number;ope=add:-1]
mul:n Mutlyplies the value to merge by the numeric n.
div:n Divises the value to merge by the numeric n.
list If the value before merging is a Php Array, then its items are displayed separated with a coma (,).
Example: [onshow.myarray;ope=list]
Add parameter valsep in order to change the item separator.
Example: [onshow.myarray;ope=list;valsep='+']
mok:x (means "magnet ok") To be used with parameter magnet. The TBS fields is never displayed, but the magnet tag is kept when the value of the field is equal to 'x'. The magnet tag is deleted in other cases. You can define several values to keep the magnet tag by defining several mok. Example: [onshow.x;magnet=div;ope=mok:1,mok:2] (mok is supported since version 3.5.2)
mko:x (means "magnet ko") To be used with parameter magnet. The TBS fields is never displayed, but the magnet tag is deleted when the value of the field is equal to 'x'. The magnet tag is kept in other cases. You can define several values to delete the magnet tag by defining several mko. Example: [onshow.x;magnet=div;ope=mko:1,mko:2] (mok is supported since TBS version 3.5.2)
nif:x (means "null if") If the value is equal to 'x' then it is replaced with '' (empty string). This operation is designed to make parameter magnet to work with other values than ''. (supported since version 3.3.0)
minv (means "magnet invisible") Replace the value with '' (empty string) but parameter magnet will consider the old value. This operation is designed to make totaly invisible a TBS field which do magnet stuffs. (supported since version 3.3.0)
msk:x (means "mask") Apply a mask to the value. Characters '*' in the mask will be replaced by the original value. Example: [onshow.img_id;ope=msk:img_*.gif] (supported since version 3.6.0)
lower Convert the value to lower case. (supported since version 3.8.0)
upper Convert the value to upper case. (supported since version 3.8.0)
upper1 Convert the value to upper case for the first character only. (supported since TS version 3.8.0)
upperw Convert the value to upper case for the first character of each word. (supported since version 3.8.0)
utf8 Can be used with max, upper, lower, upperw in order to indicate that the value is UTF8 encoded. upper1 is not supported in UTF8. (supported since version 3.8.0)

Versioning:

  • Parameter ope is supported since version 3.0. It replaces parameter max which doesn't exist since this version.
  • Multiple operations and 'mul" and "div" are supported since version 3.2.0.
frm=format

Specify a format to display for a data item which type is date/time or numeric. It is possible to use a conditional format which changes depending on the sign of the value. The format is considered as numeric type as soon as it contains the character 0, otherwise it is considered as date/time type.

Date-time format:

It is a VisualBasic like format. The following keywords are recognized:

d, dd, ddd, dddd: number of the day, number of the day in two digits, short name of the day, full name of the day. Add keyword (locale) to display locale names.
xx displays st, nd, rd or th depending to the number of the day.
w number of the day in the week (from 0 to 6)
m, mm, mmm, mmmm: number of the month, number of the month in two digits, short name of the month, full name of the month. Add keyword (locale) to display locale names.
yy, yyyy: year in two digits, full year.
hh, rr, nn, ss: hour-24, hour-12, minutes, seconds forced on two digits.
h, r hour-24, hour-12
ampm, AMPM : "am" or "pm" signal , "AM" or "PM" signal.
(locale) Display locale day and month's names. The locale language can be set using the PHP function setlocale(). It works only if locale parameters have been set on the server. For PHP reasons, in locale mode xx does not work and d does like dd.

Other characters are kept. It is possible to protect the strings inside by putting them between double quotes (").

Examples:

[fld;frm=mm/dd/yyyy] will display 12/21/2002
[fld;frm='yyyy-mm-dd hh:nn:ss'] will display 2002-12-21 15:45:03

Versioning:

  • Keywords ampm and AMPM are supported since TBS version 3.0.
  • Keyword hm was supported since 3.0 and is deprecated and replaced with keyword rr since version 3.2.0.
  • Keywords rr, r, and h are supported since version 3.2.0.
  • Keyword (locale) is supported since version 3.4.0.
Numeric format:

To define the decimal part, use an expression like '0d0...' where 'd' is the decimal separator , and '0...' is a continuation of zeros corresponding to the number of decimals.
If there is no decimal, use the format '0.' (with a dot).

To define a thousand separator, use an expression like '0t000d...' where 't' is the thousand separator. If there is no decimal, use the format '0t000.' (with a dot).

In order to display leading zeros, use an expression like '0000d...' where '0000' represents the number of digits you want to have. If there is no decimal, use the format '0000.' (with a dot). Versioning: This feature is supported since version 3.5.2.

If the format contains the character '%', then the value to display will be multiplied by 100. The character '%' is displayed too.

The numerical format may contain other strings. But only the expression with one or more zeroes placed to the right will be taken as a format, other characters will be kept.

Examples:

Value Field Display
2456.1426 [fld;frm='0.000'] 2456.143
  [fld;frm='$ 0,000.00'] $ 2,456.14
  [fld;frm='$ 0,000.'] $ 2,456
  [fld;frm='000000.'] 002456
0.2537 [fld;frm='0.00 %'] 25.37%
  [fld;frm='coef 0.00'] coef 0.25
[Note: When using javascript plug-ins to convert tables to grids, etc, some javascript libraries will be come confused when injecting special characters such as commas, currency symbols, etc into the value.  Please tests sorting and filtering with your chosen Javascript plug-in before releasing to your end-users.
Conditional formats:

You have the possibility to define up to 4 conditional formats when the value is respectively positive, negative, zero or null (or empty string). Conditional formats must be separated by a '|' character. Each conditional format is optional.

Examples:

Value Field Display
2456.1426 [chp;frm='+0.00|-(0.00)|*|empty'] +2456.14
-156.333 [chp;frm='+0.00|-(0.00)|*|empty'] -(156.33)
0 [chp;frm='+0.00|-(0.00)|*|empty'] *
null [chp;frm='+0.00|-(0.00)|*|empty'] empty
-8.75 [chp;frm='+0.00|-(0.00)'] -(8.75)
locale

Deprecated since version 3.4.0.
It does the same as the keyword (locale) used in parameter frm.

tplfrms

Enables you to define formats in the template that you can reuse for parameter frm. Works only with onload automatic fields.
It is the same feature as option tpl_frms, but option tpl_frms is defined in the PHP side, while parameter tplfrms is defined in the template side.

Example:

[onload;tplfrms;doll=$ 0,000.00;mydt=yyyy-mm-dd]
[onshow.amount;frm=doll] ... [onshow.date;frm=mydt]
tplvars

Enables you to define variables in the template that you can retrieve in the Php programm using TplVars property. Works only with onload automatic fields.

Order of processing parameters:

When you want to use several parameters in the same TBS field, then it can be interesting to understand in which order they are processed.
TBS changes the value to be merged, without changing the original value.

Order of processes:

  1. Retreive the value of the field to be merged.
  2. Change the value using parameters:
    1. onformat
    2. ope + plug-ins OnOperation
    3. frm or strconv or default char conversion
    4. if
    5. file
    6. script
    7. att
    8. ifempty or atttrue or magnet or attadd, those parameters cannot work together, the first used in this list is applied
  3. Insert the value in the template.

Automatic fields

Automatic fields enable you to automatically merge PHP global variables when some events occur.

For example [onload.x] will be merged with the global variable $x when the LoadTemplate() method is called.

Automatic fields can only merge PHP variables when they are global. There is no way to merge a variable which is local to a function, unless you make a reference to it with a global variable, or if you merge it using MergeField().
Automatic fields can also merge TBS special information (see Special automatic fields), or data of the ObjectRef property (see Objet Oriented Programming).

There are three types of automatic fields:

  • [onload] fields, which are automatically merged when the LoadTemplate() method is called.
  • [onshow] fields, which are automatically merged when the Show() method is called.
  • [var] fields, which are automatically merged only if they are embedded into parameter file, script, if, then, else or when. Thus placed, they are merged when their parent are merged.

Versioning:

  • Automatic fields [onload] and [onshow] are supported since version 3.2.0. For compatibility with versions prior to 3.2.0, remaining [var] fields are still merged as if there were [onshow] fields but is it recommended to use real [onshow] fields instead.
  • [var] are processed into parameter then and else since version 2.02.

Automatic fields may or may not have a sub name, like x in [onload.x], [onshow.x] or [var.x]. An automatic field without sub name will be merged with an empty string value (''). Example: [onload;file=header.html] this field inserts a subtemplate when LoadTemplate() method is called.

An automatic field having a sub name will be merged with the corresponding global PHP variable.
If the global variable doesn't exist at this moment, then a error is displayed, unless you add parameter noerr.

Examples:

[onload.x] this field will be merged with the global variable $x when LoadTemplate() is called.
[onshow.x] this field will be merged with the global variable $x when Show() is called.
[b1.col1;if [val]=[var.x];then 'good'; else 'bad'] : the [var.x] field is merged in the same time as [b1.col1].

You can also merge array's items, object's properties or object's methods using a dot (".") as separator. Resource variables are ignored.
For example (valid for both [onload], [onshow] and [var]):

[onshow.tbl.item1]   will display   $tbl['item1']
[onshow.tbl.item2.a.0]   will display   $tbl['item2']['a'][0]
[onshow.obj.prop1]   will display   $obj->prop1
[onshow.obj.methA]   will display   $obj->methA()
[onshow.obj.methB(x,y)]   will display   $obj->methB('x','y')
[onshow.tbl.item3.prop2.item4   will display   $tbl['item3']->prop2['item4']

Versioning: calling methods with arguments from an automatic field is supported since TBS version 3.0.

Note: You can also force the merge of [var] fields or other types at anytime using the MergeField() method.

 

Embedded automatic fields

An embedded TBS field is never merged, unless :

  • it is merged before the parent field,
  • il is a [var] field placed into a paremeter file, script, if, then, else or when.

Examples:

[onload;if [onload.x]=1;then 'yes';else 'no']
This example will always display 'no', because the embedded [onload.x] fild will never be evaluated. It is better to use [onload;if [var.x]=1;then 'yes';else 'no'] instead, or better : [onload.x;if [val]=1;then 'yes';else 'no']

[b1.nom;block=tr;headergrp=[var.x]]
In this example, [var.x] will not be merged yet when you call $TBS->MergeBlock('b1',...)
The header will then be defined badly.
It needs one of those:
- using an onload field: [b1.name;block=tr;headergrp=[onload.x]]
- calling $TBS->MergeField('var') avant $TBS->MergeBlock('b1',...)
- using a customized field name: [b1.name;block=tr;headergrp=[zzz]] manually merged with $TBS->MergeField('zzz',$x)

Security: how to limit automatic fields usage in templates?

You can limit the automatic fields usage by defining a prefix for allowed PHP variables. For details, see create a new TBS object.

Prevent from processing automatic fields [onload] and [onshow]

TBS options onload and onshow enable you to cancel the processing of [onload] and [onshow] fields. Those options accept only true of false values. This can be very useful especially, but not only, for some TBS plug-ins. Note that [var] fields are automatically processed even if onshow option is set to false. See method SetOptions() for more details about TBS options.

Versioning:

  • Options onload and onshow are supported since TBS version 3.8.0
  • Properties $TBS->OnLoad and $TBS->OnShow do act like the corresponding options but are deprectated. Those properties are supported since TBS version 3.6.0.

Special automatic fields:

A Special automatic field is a TBS automatic field which has a special name and can display special data provided by the template engine.
The special names can work only with automatic fields. That is [onload], [onshow] and [var].
The scpecial names always have a double dot before the key instead of one.

Example: Date of the day : [onshow..now;frm='mm-dd-yyyy']

Available keys for special automatic fields:
 
Key Description Example
now Date and hour of the server. [onshow..now;frm='mm-dd-yyyy']
version The version of CloudStreet Portal TBS plug-in. [onshow..version]
script_name The name of the PHP file currently executing. <form action="[onshow..script_name]">
template_name The name of the last loaded template file.
It is the name given to the LoadTemplate() method.
 
template_date The creation date of the last loaded template file.  
template_path The directory of the last loaded template file.
It is the directory given to the LoadTemplate() method.
 
tplvars.* The value of an item set in the TplVars property.
('*' must be the key of an existing item in the array)
[onshow..tplvars.title]
cst.* The value of a PHP constant.
(* must be the name of an existing constant)
[onshow..cst.PHP_VERSION]
tbs_info Information oninstalled plug-ins. [onshow..tbs_info]
error_msg Display errors that have been avoid during the time when TBS option noerr is set to true. [onshow..error_msg]
php_info Display the PhpInfo sight, the same as the PHP function phpinfo(). [onshow..php_info]
store.* Display the contents aggregated in a store. [onshow..store.default]

Versioning:

  • special var fields cst and tbs_info are supported since TBS version 3.2.0.
  • error_msg is supported since TBS version 3.5.0.
  • php_info and store are supported since TBS version 3.8.0.

Blocks:

A TBS block enables you define a zone and to display data from a record source. You can define a block using one or two tags (see below).

Merging with data:

Merging a block with data is done using the MergeBlock() method. When a block is merged with data, it is repeated as many times as there are records; and the associated fields are replaced by the value of the columns stored in the current record.
A field associated to a block is identified by its name which should be made of the name of the block followed by the name of the column to display and separated by a dot.

Examples:

- [Block1.ColA] This field will display the value of column ColA when block Block1 is merged.
- [Blokc1.ColB;frm='dd-mm-yyyy'] Another field but with a parameter.

 

Since version 3.5.0 column names with spaces are accepted.

Remark: when two separated blocks have the same name, then they will be considered has two sections of the same block. All content placed between those two sections of a block will be ignored and deleted during the merging. See sections of blocks to know more about sections.

Block syntaxes:

There are three possible syntaxes to define a TBS block:

Explicit Syntax:
Two tags are used. One for the beginning of the block and another for the end of the block.
Example:
TEMPLATE...[BlockName;block=begin;params]...TEMPLATE...[BlockName;block=end]...TEMPLATE
Those tags for the block definition will be deleted during the merging.
Relative Syntax:
The block is defined by a pair of opening-closing XML/HTML tags which is given by a single tag.
Example:
TEMPLATE...<tag_name...>...[BlockName;block=tag_name;params]...</tag_name...>...TEMPLATE
This tag for the block definition must be placed between the pair of XML/HTML tags.
This tag will be deleted during the merging.
Remark: You can aslo define a block's zone by a combination of XML/HTML tags. See parameter block for more details.
 
Simplified Syntax:
An associated TBS field is used to define the block in a relative way (see the relative syntax above).
Example:
TEMPLATE...<tag_name...>...[BlockName.ColumnName;block=tag_name;params]...</tag_name...>...TEMPLATE
The tag for the block definition (i.e. the block=... parameter) must be placed between the pair of XML/HTML tags. You are nor obliged to put the parameter block on the first field, it can be any of them inside the zone defined by the block.
Remarks:
• You should not repeat the parameter block=... on each fields of the block, only one is enough. If you place several of them, this will be accepted by TBS but it may bring confusions about complementary parameters for block.
• You can aslo define a block's zone by a combination of XML/HTML tags. See parameter block for more details.

Which syntax to use?

The 'absolute' syntax is rarely used with Visual Editors because tags have often to be placed between two XML/HTML tags. On the other hand, it is convenient for textual editors.

The 'relative' syntax enables you to indicate a block using only one tag. Furthermore, there is no need to hide the tag because it will be deleted during the displaying. This syntax is quite practical.

The 'simplified' syntax is really simple. It enables you to define a block and a TBS Field with only one tag. This syntax is the most current and the most practical.

Tip: You can use the 'relative' or the 'absolute' syntax with custom tags using the XML/HTML standard.

Example:

<custom_tag>Hello [blk1.column1;block=custom_tag], how are you?</custom_tag>

Synopsis of a block tag:

Element Description
BlockName The name of the TBS block.
params Optional. One or several parameters from the list below. Separated with ';'.
block=begin Indicates the beginning of the block.
block=end Indicates the end of the block.
block=tag
or
block=expr

Define a block bounded by the XML/HTML element, that is between the opening XML/HTML tag <tag...> and the closing XML/HTML tag </tag> which surround the tag. The couple of indicated XML/HTML tags are integral part of the bloc. The tag can also be placed inside the opening tag.

If the element is a single tag ending with "/" (such as <image href="/img.gif" /> ) then the block is bounded by the single tag.

Examples:

<table id="tab1"> <tr><td>[b1.column1;block=tr]</td></tr></table>
The block is defined by the zone framed by pointillets.
<table id="tab1"> <tr id="row-[b1.column2;block=tr]"><td>[b1.column1]</td></tr></table>
The TBS tag can be placed inside the opening tag.
<div id="image-list"> <image href="/img/[b1.column1;block=image]" alt="the picture" /> </div>
If the tag is a single tag ending with "/" then the block is bounded by the single tag.
Special marks:
block=_ Define a block on the text line which holds the TBS tag. A text line always ends with a new-line char. New lines for Windows, Linux and Mac are supported. This feature is very useful for a template with text contents for example. Supported since TBS 3.1.0.
block=/ Define a block on the tags containg the TBS field. TBS assumes the tags is ending with "/", otherwise an error occurs. Supported since TBS 3.1.0.
block=. Define a block on the TBS field that contains this parameter. Supported since TBS 3.10.0.
block=tag/ Deprectated. By adding character "/" at the end of the tag's name, TBS assumes the tag is single. This syntax is ignored since TBS version 3.5.2 because TBS can recognize single tags by itself. Coding "block=image/" is the same as "block=image".
Extended blocks:

You can define the block's zone (or the section's zone) beyond the simple XML/HTML elements or special marks by using the following expressions. Note that Special Marks (see above) can be used for extended blocks.

To define the block's zone on several successive elements:

<ul>...</ul><div>[b1.field1;block=div+div+div+table]</div><div>...</div><div>...</div><table>...</table><p>...</p>

The same using multiplicated elements: (supported since TBS 3.10.0)

<ul>...</ul><div>[b1.field1;block=3*div+table]</div><div>...</div><div>...</div><table>...</table><p>...</p>

To define the block's zone on several successive elements placed before:

The element placed bewteen brackets means the one which contains the block's definition.

Exemple #1: ... <span>...</span><div>[b1.field1;block=p+(div)]</div> ...

Exemple #2: ...<span>...</span> <div>[b1.field1;block=p+(div)+table]</div> <table>...</table> ...

To define the block's zone on a tag of the same type but with a higher encapsulation level:

... <div> <div> [b1.field1;block=((div))] </div> </div> ...

The number of bracket means the encapsulation level of the tags.

To define the block's but exclusing the limits, use the operator "!" on the limit elements: (supported since TBS 3.10.0)

Exemple #1: ...<div>...text here...[b1.field1;block=!div]...text there...</div>...

Exemple #2: ...<ul>...</ul><div>...text here...[b1.field1;block=div+!table]...text there...</div><ul>...</ul><table></table>...

Exemple #3: ...<p></p><ul>...</ul><div>...text here...[b1.field1;block=!p+(.)+!table]...text there...</div><ul>...</ul><table></table>...

Note that the operator "!" can be used only on the first and the last element of the block definition.

Versioning : The Extended Blocks feature is supported since TBS version 3.0. Before that, you had to use parameters 'extend' and 'encaps' which are not supported anymore.

Block's parameters:

 

Parameter Description
nodata Indicates a section that is displayed only if there is no data to merge.

Example:
[b1.field1;block=tr] [b1.field2]
[b1;block=tr;nodata]There is no data.

For more information about sections, see the chapter 'Sections of blocks'.

bmagnet=tag
or
bmagnet=expr
Indicates an XML/HTML zone which must be deleted if the block is merged with no record (an emprt query, for example, or a PHP Array with no items). Parameter bmagnet supports the same syntax as parameter block, i.e. that expr must be an XML/HTML tag or a TBS extended block expression.
Example:
[b1.field1;block=tr;bmagnet=table] [b1.field2]
In this example, the table will be deleted if there is no record to merge.

Remark:
Value null is not accepted by MergeBlock() method as a data source, and it makes a TBS error instead of deleting the bmagnet zone. If you data source may be null, then you should make a check previously.
Example:
if (is_null($data)) $data = array();
$TBS->MergeBlock('b1',$data);

Versioning: parameter bmagnet is supported since TBS version 3.0.

parallel=configuration_id

Merge a block with a parallel process for sub-blocks. This can typically merges a table block in columns.
By default, TinyButStrong supports the configuration id named "tbs:table" for merging HTML tables. But you can define your own configuration.
See Parallel merge for examples and how to add a custom configuration.

Versioning: parameter parallel is supported since TBS version 3.9.0.

headergrp=colname Indicates a header section that is displayed each time the value of column colname changes.
colname must be a valid column name returned by the data source.
Since TBS version 3.3.0, colname can also be a virtual column # or $, and it also support the subitems syntaxe of TBS fields.
You can define several headergrp sections with different columns. Placement's order of headergrp sections in the block can modify the result.
For more information about sections, see the chapter 'Sections of blocks'.
footergrp=colname Indicates a footer section that is displayed each time the value of column colname changes. See headergrp.
splittergrp=colname Indicates a splitter section that is displayed each time the value of column colname changes. See headergrp.
parentgrp=colname Indicates a parent section that is displayed each time the value of column colname changes. Unlike other sections, a parentgrp section allows normal sections inside itself. It's a way to define both a header and a footer in one section.
serial Indicates that the block is a main block which contains serial secondary blocks.
For more information, see the chapter 'serial display (in columns)'.
p1=val1 Indicates the use of a dynamic query. All the occurrences of the string '%p1%' found in the query given to the MergeBlock() method are replaced by the value val1. For more information, see the chapter Subblocks with dynamic queries.
If it used without any value, that enables you to merge several blocks of the same name. See "Merging several blocks with the same data" for more details.
sub1=column1 Define the column containing the data for an automatic subblock.
For more information, see the chapter Automatic subblocks.
ondata=fct_name Indicates the name of a user Php function that will be executed during the block merging.
Since TBS version 3.0, it's also possible to indicate a method of a class. See OOP.
The function is called each time a record is taken from the data source. You can use the arguments of such a Php function to edit records before they are merged. The function must have the following syntax:
  function fct_name($BlockName,&$CurrRec,$RecNum) { ... }
Argument Description
$BlockName Returns the name of the block calling the function (read only).
$CurrRec Returns an associative PHP array containing the current record (read/write ; don't forget the & in the function header).
If you set this variable to false, it ends the merging like it was the end of the record set.
$RecNum Returns the number of the current record (read only, first record is number 1).
Examples:
function f_add_column($BlockName,&$CurrRec,$RecNum) {
  $CurrRec['len'] = strlen($CurrRec['text']);
}

Since TBS version 3.6.0, it's possible to limit the allowed PHP functions for parameter ondata. See create a new TBS object.
when expr1=expr2 Make the section conditional and define its condition. A conditional section is displayed only if its condition is verified.
Supported operators are:
= or == equal  
!= not equal  
+- greater than  
+=- greater than or equal to  
-+ less than  
-=+ less than or equal to  
~= expr1 match the regular expression expr2
(for experimented users)
Versioning: added in TBS 3.0
Both expr1 and expr2 must be string or numerical expressions. The expressions may contain [var] fields.
Example:
<div>[onload;block=div;when [var.x]~='*to*'] ... </div>
The <div> block will be displayed only if $x>0.

Note: do not confuse parameter when (which works only for TBS blocs or sections) and parameter if (which works only for TBS fields). Thus, parameter when is taken into account only if parameter block exists in the same TBS tag.
See conditional blocks for more details.

default Indicates a section of block that must be displayed only if no conditional section of the same block has been displayed.
several Indicates that several conditional sections of the block can be displayed if several conditions are true. By default, conditional sections are exclusive.

 

Sections of block:

Different blocks having the same name will be regarded as sections of the same block.

Sections can be used to:

  • alternate the display (normal sections),
  • display something if there is no data (NoData section),
  • display a header each time the value of a column changes (grouping sections).

Normal sections:

When you define several normal sections, they will be used alternatively for each record.

Example:

[b1.caption;block=tr]
[b1.caption;block=tr]

In this example, the block named 'b1' contains two normal sections. Records will be displayed alternatively with a green background and with a blue background.

NoData section:

The NoData section is a section displayed only if the data source has no records. There can be only one NoData section in a block. The NoData section is defined by adding the parameter nodata.

Example:

[b1.caption;block=tr]
There is nothing. [b1;block=tr;nodata]

Grouping sections:

Grouping sections are displayed every time a column's value in the record-set changes. You can define header, footer, splitter or parent sections using parameters headergrp, footergrp, splittergrp, and parentgrp. See block's parameters for more details.

Example:

Year: [b1.year;block=tr;headergrp=year]
[b1.caption;block=tr] [b1.amount]

Conditional sections:

Conditional sections are displayed only if their condition is verified. The condition for display is defined using parameter when. As soon as a section has this parameter, it becomes conditional. See Conditional display for more details.

Example:

[b1.name;block=tr]
[b1.address;block=tr;when [b1.add_ok]==1]

Parallel merge (dynamic columns):

The parallel merge is supported since TBS version 3.9.0.

The parameter parallel enables you to merge a block with a parallel process for sub-blocks. This can typically merges a table block in columns.

How does it works ?

First of all you have to define a block over one or several closed cells in the same row of a table. It can be at any row of the table, it makes no difference. Then add parameter "parallel=tbs:table" to this block. Then TBS will merge the cells as expected for this row, but also for all the same columns of other rows in the table. The configuration "parallel=tbs:table" tells how is structured the <table> element in HTML, and then it can found other cells of the same columns. TBS can even process spanned cells if it is consistent with the asked merge.

By default, TinyButStrong supports the configuration named "tbs:table" for merging HTML tables. But you can define your own configurations.

Example:

Template:

Category [b.date]
Thin [b.thin;block=td;parallel=tbs:table]
Heavy [b.heavy]
Total [b.total]

PHP:

$data = array(
 array('date' => '2013-10-13', 'thin' => 156, 'heavy' => 128, 'total' => 284),
 array('date' => '2013-10-14', 'thin' => 233, 'heavy' =>  25, 'total' => 284),
 array('date' => '2013-10-15', 'thin' => 110, 'heavy' => 412, 'total' => 130),
 array('date' => '2013-10-16', 'thin' => 258, 'heavy' => 522, 'total' => 258),
);
$TBS->MergeBlock('b', $data);

Result:

Category 2013-10-13 2013-10-14 2013-10-15 2013-10-16
Thin 156 233 110 128
Heavy 128 25 412 130
Total 284 258 522 258

Remark: The parallel merge doesn't work with headergrp and serial mode.

Define a new configuration:

$configuration = array(
 // Name of the parent entity. The process will be limited to this element and its childs.
 'parent' => 'table',
 // Names of tags that must be simply ignored. Such start and ending tags are ignored but childs are not ignored.
 // For elements that must be completely ignored including childs, you just have to not mentioned it in the configuration.
 'ignore' => array('!--', 'caption', 'thead', 'thbody', 'thfoot'),
 // Names of entities recognized as column's definitions, and their span attributes ('' for no span attribute).
 // Such entities must always be placed before the row entities.
 'cols'   => array(),
 // Names of entities recognized as rows.
 'rows'   => array('tr'),
 // Names of entities recognized as cells, and their span attibute ('' for no span attribute).
 'cells'  => array(
   'td' => 'colspan',
   'th' => 'colspan',
  ),
);
// Save the new configuratin with its ID.
$TBS->SetOption('parallel_conf', 'tbs:table',  $configuration);
    

Serial display (in columns):

The serial display enables you to display several records inside a block. For this, you have to use a main block and secondary blocks.

Example:

Rec 1
Rec 2
Rec 3
Rec 4
Rec 5
Rec 6
Rec 7
Rec 8
Rec 9
...
...
...

In this example, main blocks are the blue lines of the table, the secondary blocks are the pink cells.

Syntax:

The main block and its secondary blocks are merged using only one call to the MergeBock() method. The main block must be defined using the parameter serial. The secondary blocks must be nested into the main block. The secondary block's names must be the name of the main block followed by "_" and a number indicating display order.

Example:

[bx;block=tr;serial][bx_1.txt;block=td]
[bx_2.txt;block=td]
[bx_3.txt;block=td]
[bx_4.txt;block=td]

Empty secondary block:

You can specify a special secondary block that will be used to replace unused secondary blocks (without records). This "Empty" secondary block must have the index 0. It can either be placed inside the main block with the normal secondary block, or alone inside another serial block. The "empty" secondary block is optional.

Example:

[bx;block=tr;serial][bx_1.txt;block=td]
[bx_2.txt;block=td]
[bx_3.txt;block=td]
[bx_4.txt;block=td]
[bx;block=tr;serial][bx_0;block=td] No records found.
     

Remark: The serial display also works with sections of block and dynamic queries.

Subblocks:

A subblock is a TBS block nested into another TBS block and that should be displayed as a separated block for each record of its parent block.

Example:

Parent block record #1
Subblock record #1.1
Subblock record #1.2
Parent block record #2
Subblock record #2.1
Subblock record #2.2
Subblock record #2.3
Parent block record #3
Subblock record #3.1

They are two different ways to perform subblocks with TBS:

  • Automatic subblock: (since TBS 3.5.0) it is when the data of the parent block has a column which contains the ready-to-merge data for the subblock. Automatic subblocks are activated using parameter sub1 in the parent block, and they are merged automatically during the merge of the parent block. No extra MergeBlock() are needed. See Automatic subblocks for more details.
  • Subblock with dynamic query: it is when the data of the subblocks are retrieved using a query which can change for each record of the parent block. Subblocks with dynamic queries need an extra MergeBlock() to perform the merging with their dynamic query. Parameter p1 is also needed in the subblock definition in order to set the values to inject in the dynamic query. See Subblocks with dynamic queries for more details.

Automatic subblocks:

Automatic subblock are supported since TBS version 3.5.0.

You can use automatic subblocks when the data of the parent block has a column which contains the ready-to-merge subdata for the subblock. Set parameter sub1=column in the parent block to define the column which contain the data for the subblock. If you have several subblocks to merge in the same parent block then use parameters sub2, sub3, ... The name of the subblock must be the same as the parent block followed by the suffix _sub1, (or _sub2, _sub3, ...).

The data of the parent block must have a column which contains the data of the subblock. Supported data types are:

  • a PHP array
  • an object supported by TBS (natively or with a plug-in)
  • a text string of values separated by comas (,).

Example:

Name: [body.name;block=tr;sub1=spokenlg]
[body_sub1.val;block=tr]

Corresponding PHP code:

$data = array(
  array('name'=>'Peter', 'spokenlg'=>array( 'US', 'FR' ) ),
  array('name'=>'Paul',  'spokenlg'=>array( 'US' ) ),
  array('name'=>'Jack',  'spokenlg'=>array( 'FR', 'ES', 'IT') ),
);
$TBS->MergeBlock('body', $data);

Result of the merge:

Name: Peter
US
FR
Name: Paul
US
Name: Jack
FR
ES
IT

Have the column optional:

If you want no error message when the column is omitted in the parent data, then you can set it optional by using parenthesis. This is working only if the parent data is a PHP array. Optional column is supported since TBS version 3.6.0.

Example:

Name: [body.name;block=tr;sub1=(spokenlg)]
[body_sub1.val;block=tr]

Direct subblocks (which are not saved under a column):

If you use parameter sub1 by omitting the column name, then TBS will assume that the data for the subblock are available directly on the current record instead of under a column of this record. Direct subblocks are supported since TBS version 3.6.1.

Example of data that can be merged with a direct subblock:

$data = array();
$data['group1'] = array();
$data['group1'][] = array('id'=>1, 'name'=>'peter');
$data['group1'][] = array('id'=>2, 'name'=>'paul');
$data['group2'] = array();
$data['group2'][] = array('id'=>3, 'name'=>'jules');
$data['group2'][] = array('id'=>4, 'name'=>'jim');

Example of direct subblock that can be merged with those data:

Group : [body.$;block=tr;sub1]
[body_sub1.name;block=tr]

Several levels of automatic subblocks:

TBS supports several levels of automatic subblock. For example you cab have blocks "b", 'b_sub1", 'b_sub1_sub1", 'b_sub1_sub1_sub1" and so on.

Subblocks with dynamic queries:

Principles of the dynamic queries:

It is possible to use the MergeBlock() method with a dynamic query. In your template, you have to define a block by adding the parameters p1, p2, p3,... with their values. The parameter $query given to the MergeBlock() method must be a string and has to contain marks such as %p1%, %p2%, %p3%, ... in order to welcome the values of the parameters p1, p2, p3,...

Note that you can also use a dynamic query with a PHP Array using a string that refers to a PHP Array stored in a global variable. See Php data sources.

Each section of the block to be merged that contains a parameter p1 will be computed as a separate block for which the dynamic query is re-executed. The sections of the block that have no parameter p1 are combined with the previous section with a parameter p1.

Example:

Country: France

[blk.town;block=tr;p1='france'] [blk.country]

Country: USA

[blk.town;block=tr;p1='us'] [blk.country]

Corresponding PHP code:

$TBS->MergeBlock('blk', $cnx_id, "SELECT town,country FROM t_geo WHERE (country='%p1%')");

Or using an Array:

global $data_town; // the coutry code is the main key of the array
$TBS->MergeBlock('blk', 'array', 'data_town[%p1%]');

Result of the merge:

Country: France

Paris france
Toulouse france

Country: USA

Washington us
Boston us

Use with subblocks:

Dynamic queries enable you to easily build a system of a main-block with subblocks. Here is how you can do it:

  1. Create a main block, and then a subblock inside the main block.
  2. Link them by adding to the subblock a parameter p1 whose value is a field from the main block.
  3. At the PHP side, merge the main block first, and then the subblock.

Example:

Country: [main.country;block=tr]
[sub.town;block=tr;p1=[main.cntr_id]]

Corresponding PHP code:

$TBS->MergeBlock('main', $cnx_id, 'SELECT country,cntr_id FROM t_country');
$TBS->MergeBlock('sub', $cnx_id, 'SELECT town FROM t_town WHERE (cntr_id=%p1%)';

Or using an Array:

$TBS->MergeBlock('main', $data_county);
global $data_town; // the coutry code is the main key of the array
$TBS->MergeBlock('blk', 'array', 'data_town[%p1%]');

Result of the merge:

Country: France
Paris
Toulouse
Country: Germany
Berlin
Munich
Country: Spain
Madrid
Barcelona

Remarks:

  • The parameter strconv=esc enables you to pass protected string values to the query.
  • The dynamic queries also work with sections of block and serial display.

Automatic blocks:

Automatic blocks enable you to automatically merge conditional blocks when some events occur.

There are two types of automatic blocks:

  • [onload] blocks which are merged automatically when the LoadTemplate() method is called.
  • [onshow] blocks which are merged automatically when the Show() method is called.

Automatic blocks are not merged with data ; that's why they cannot have normal sections (non conditional sections) and linked fields. Automatic blocks can have only conditional sections. Conditions are evaluated only once, and they can be expressions containing [var] fields.

Example:

[onload;block=tr;when [var.light]=1]Light is ON.

[onshow;block=tr;when [var.user]=1] User : [onshow.username]

If you need to have a group of exclusive sections, with or without a default section, you can suffix the [onload] and [onshow] bloc's names with "_" followed by a sub name.

Example:

[onload_ligth;block=tr;when [var.light]=1] Light is ON.
[onload_ligth;block=tr;when [var.light]=0] Light is OFF.
[onload_ligth;block=tr;default] Light is ?

See Conditional sections for more details.

Subtemplates:

here are two ways to insert subtemplates in your main template.

Primary insertion using parameter file:

This is the best way to simply insert a part contained in another file, like usually done for headers and footers.

The value given to parameter file must be the name of a file existing on the server. You can use an expression with [var] Fields and the [val] keyword which represent the value of the field. If the value is an empty string, then no error message is displayed, it is like parameter file is ignored. This can be used to manage conditional insertion.

Examples:

[onload;file=header.htm]
[onload;file=[var.file_header]]
[onload.sub1;file=[val]]
[onload;file=[var.insert;if [val]=1;then 'header.html';else '']]

Contents of the file is inserted at the place of the field, without no char conversion and no TBS protection.
[onload] tags contained in the file are processed at the insertion. [onshow] tags will be merged on the Show() method because they became part of the main template.

The subtemplate can contain any TBS fields, including [var] fields and blocks to be merged. If you intend to merge data with a block defined into a subtemplate, then it's suggested to use parameter file in an [onload] field in order to ensure that the subtemplate is inserted before you call MergeBlock().

You can create a subtemplate in an independent XML/HTML/Text file, and ask TBS to include in the main template only the <body> part (or another part). This can be done by adding parameter getpart to parameter file in the TBS field of the main template. This technique enables you to work WYSIWYG with your subtemplates.

Insertion driven with Php code using parameter subtpl:

Parameter subtpl is useful to manage subtemplate insertion with Php code. Parameter subtpl is active only when used with a parameter script or onformat. It turns the current TBS instance in Subtemplate mode during the script or function execution and can act on a new template without deteriorating the main template.

The Subtemplate mode presents the following characteristics:

* Php outputs are displayed at the field's place instead of being immediately sent to the client. For example, using the Php command echo() will insert a text in the main template instead of be directly output it. Using the Show() method will also insert the result of the sub-merge into the main template.
   
* A reference to the TBS instance is provided by local variable $this or $TBS, whether you use parameter script or onformat. This variable be used for new submerges without deteriorating the main template. The Show() method won't stop any script execution during the Subtemplate mode like it does by default in normal mode.

When the script or the function ends, the TBS instance returns in normal mode with the main TBS template.

Example with parameter script:

HTML:
[onload.file;script=specialbox.php;subtpl]
PHP script:
<?php
  echo('* Here include a subtemplate *');
  $this->LoadTemplate($CurrVal);
  $this->MergeBlock('blk1',$GLOBALS['conn_id'],'SELECT * FROM table1');
  $this->Show(); 
?>
Remarks: $CurrVal is a local variable provided by TBS when using parameter script ; this variable is a reference to the value of the field currently merged. In the example above, $CurrVal has the value of the global variable $file. You can replace it, for example, by the name of the subtemplate to load (for example: 'mysubtpl.htm'). See parameter script for more information.

Example with parameter onformat:

 

HTML:
[onload.user_mode;onformat=f_user_info;subtpl]
PHP user function:
function f_user_info($FieldName,&$CurrVal,&$CurrPrm,&$TBS) {
  if ($CurrVal==1) { // User is logged in
    $TBS->LoadTemplate('user_info.htm');
    $TBS->MergeBlock('blk1',$GLOBALS['conn_id'],'SELECT * FROM table1');
    $TBS->Show();
  } else { // User not logged in
    echo('You are not logged in.');
  }
}
Remarks: $CurrVal is a variable declared as an argument of the function. It's TBS that is in charge to call this function making $CurrVal referring to the value of the fields currently merged. In this example above, $CurrVal is equal to the global variable $user_mode. In the same way, variable $CurrPrm is a reference to the array of parameters of the field currently merged, and $TBS is a reference to the TinyButStrong instance currently used. See parameter onformat for more information.

Conditional display overview:

TinyButStrong offers several tools for conditional display for both fields and blocks.

Conditional fields

For any TBS fields you can use parameters for conditional display, recalled below.

Parameter Description
. (dot) Display an Html unbreakable space if the field value is empty.
ifempty=value2 Display value2 if the field value is empty.
magnet=tag Delete a tag or a pair of tags if the field value is empty.
if condition
then value1
else value2
Display value1 or value2 depending on whether the condition is verified or not.
frm=format1|format2|format3|format4 Changes the numeric format or date/time format depending on whether the value is positive, negative, zero or empty.

Example:
[onshow.error_id;if [val]=0;then 'no error';else 'error found']

Conditional sections

You can use conditional sections any TBS block (data block or automatic block). A conditional section is a section which has a parameter when defining a condition, or parameter default. At the block's merging, each when condition of conditional sections is evaluated until one is verified. As soon as one when condition is verified, its conditional section is kept and other conditional sections are deleted. If no when condition is verified, then the default section is displayed if it exists.

• The case of data blocks:

If it is a data block, it means a block merged with MergeBlock(), then the conditional sections are reassessed for each record. It is even possible to define a data block with only conditional sections, with no standard section.

• Defining the conditions:

The conditions defined into parameters when can be expressions that contain [var] fields et and linked fields (if it is a data block). See parameter when for more details about operators supported by TBS.

• Section exclusivity:

By default conditional sections are exclusive inside a block. It means only one conditional section of a block can be displayed. But if you want a block to have non-exclusive conditional sections, you can use parameter several on the first conditional section. With this parameter, all conditions are evaluated and each true condition makes its section to be displayed.

Example with a data block:

Name: [b1.Name;block=tr] standard section
Address:
[b1.add_line1;block=tr;when [b1.address]=1]
[b1.add_line2]
[b1.add_zip] - [b1.add_town]
conditional section
No address.[b1;block=tr;default] default conditional section (optional)

Example with an automatic block:

[onload_err;block=tr;when [var.email]='';several] Your email is empty.
[onload_err;block=tr;when [var.name]=0] Your name is empty.
[onload_err;block=tr;default] All is ok.

 

Improve CloudStreet Portal by coding:

You can add features to CloudStreet Portalusing plug-ins. The database plug-ins simply enable the method MergeBlock() to recognize new types of database. The other plug-ins enable you to add features to or to modify its main methods in order to make it more specialized.

In both cases, a plug-in is made of a set of PHP functions or one PHP class which have to fit with a special syntax expected by Cloudstreet Portal.

Extended methods:

Extended methods are custom methods that you can add to a TinyButStrong instance. This can be usefull for a plug-in for example.

Versioning: Extended methods are supported since TBS version 3.8. The feature needs PHP 5.0 or higher.

Examples:

If you define:
$TBS->ExtendedMethods['newMethod1'] = array(&$myObject, 'myMethod');
then if you call:
$TBS->newMethod1($x);
it whill run :
$myObject->myMethod($x);

If you define:
$TBS->ExtendedMethods['newMethod2'] = 'myFunction';
then if you call:
$TBS->newMethod($x);
it whill run :
myFunction($x);

Block alias:

 

A block alias is a special name for a block definition, which will be replaced with another list of tags or which will call a custom function to find the block bounds.
Block alias really empower the way of defining blocks. It is useful for plug-ins or when you want to simplify the understanding of the template coder.

Versioning: Block alias are supported since TBS version 3.8.

Examples:

$TBS->SetOption('block_alias', 'row', 'tr'); // the alias replace one tag
$TBS->SetOption('block_alias', 'dblrow', 'tr+tr'); // the alias replace several tags
$TBS->SetOption('block_alias', 'my_alias', array($myObj, 'findBounds') ); // the alias call a custom function to find the bounds

Use in the template :

[blk1;block=row] or [blk1;block=row+row] or even [blk1;block=th+row]
[blk2;block=dblrow]
[blk3;block=my_alias]

Defining a block alias with a function:

Example :

class clsTest {
 /** 
  * Function findBound() will be call two times for finding the bounds of the block. Once with $Forward=true, and once with $Forward=false.
  * It is supposed to return the position of the inner bounds of the block. 
  * It can return false if an error occurs of if the template source is inconsistent for finding the block at the given position.
  *
  * @param string  $Tag The name of the block alias
  * @param string  $Txt The source of the template
  * @param integer $Pos The position of the TBS field in $Txt
  * @param boolean $Forward The direction of the search
  * @param mixed   $LevelStop Encapsulation level in a block of the same type. Ignore this in your code if your block type does not support self-encapsulation. 
  * @return integer
  */
	function findBound($Tag, $Txt, $Pos, $Forward, $LevelStop) {
		if ($Forward) {
			return strpos($Txt, '}', $Pos);
		} else {
			return strrpos(substr($Txt, 0, $Pos+1), '{');
		}
	}
}

Data Reader Plug-ins:

Versioning: Data Reader plug-ins are supported since TBS version 1.8.

When you use $TBS->MergeBlock($BlockName, $Source, $Query), TBS is first examining $Source to see if it supported as a data source.

A Data Reader plug-in enables TBS to to recognize new data sources.

You can found several examples of Data Reader plug-in at the TinyButStrong web site.

Data Reader plug-in made with 3 PHP functions

Synopsis:

function tbsdb_XXX_open(&$Source, &$Query) 
This function is called one time by the MergeBlock process, before the other user functions.
It is supposed to use $Source and $Query to open a recordset, and return a reference of that recordset.
function tbsdb_XXX_fetch(&$Rs [,$RecNum]) 
This function is called several times by the MergeBlock process, as many times as there are data to fetch from the query.
This function should return the next record as an associative array (column name=> value), or return false if there is no record left.
$Rs is the value provided by tbsdb_XXX_open(). It is commonly a recordset's reference.
$RecNum can be useful for some database type such as Oracle, for which the number of the record is needed to retrieve it.
function tbsdb_XXX_close(&$Rs) 
This function is called on time by the MergeBlock process, after the other user functions.
This function should close the recordset properly.
$Rs is the value provided by tbsdb_XXX_open(). It is commonly a recordset's reference.

TBS will automatically use this Data Reader plug-in for $TBS->MergeBlock($BlockName, $Source, $Query) when:

  • $Source is equal the string 'XXX'.
  • or
  • $Source is a PHP ressource which type is named 'XXX'. Spaces are deleted and '-' are replaces with '_'.
  • or
  • $Source is a PHP object which class is named 'XXX'.

 

Data Reader plug-in made with a class

Example with a direct object:

class MyCustomClass {
  function tbsdb_open(&$Source, &$Query) {...}
  function tbsdb_fetch(&$Rs ,$RecNum) {...}
  function tbsdb_close(&$Rs) {...}
}
$Source = new MyCustomClass();
$TBS->MergeBlock($BlockName, $Source, $Query);    

When the MergeBlock process meet of value for $Source which is an object, and have at least 3 methods namedtbsdb_open(), tbsdb_fetch() and tbsdb_close(), then it assumes that the object is a Data Reader plug-in. There can be other methods and properties, but those 3 methods must have the same syntax and the same feature as the user functions described above.

Example with an objet saved in ObjectRef:

class MyCustomClass {
  function XXX_open(&$Source, &$Query) {...}
  function XXX_fetch(&$Rs ,$RecNum) {...}
  function XXX_close(&$Rs) {...}
  function YYY_open(&$Source, &$Query) {...}
  function YYY_fetch(&$Rs ,$RecNum) {...}
  function YYY_close(&$Rs) {...}
}
$TBS->ObjectRef = new MyCustomClass();
...
$TBS->MergeBlock($BlockName, '~XXX', $Query);

When the MergeBlock process meet a value for $Source which is a string beginning with '~' then it assumes that property $TBS->ObjectRef is a Data Reader plug-in based on an object (see OOP). The object must have the same requirements as a Data Reader plug-in based on objet described above, but the names of the methods can be different.

 

Other plug-ins:

Versioning: plug-ins are supported since TBS version 3.0.

Coding a plug-in using a PHP class:

• Plug-in's key:

Each plug-in has a plug-in key which is the name of its Php class. This key must be given to the method PlugIn() when you use it. Thus, it is recommended to define a PHP constant for the plug-in's key (see example below).

• Plug-in events:

A TBS plug-in must be a PHP class which contains one or several specific methods that will be recognized and plugged by TBS. Those specific methods are called plug-in events because they are executed automatically by TBS when the corresponding event occurs. A TBS plug-in can also have other methods and properties for internal purpose. A TBS plug-in must have at least the OnInstall event.

For example:

// TBS plug-in XXX 
define('TBS_XXX','clsTbsPlugIng_XXX'); // That is the plug-in's key 
class clsTbsPlugIng_XXX() {
  function OnInstall(...) {...} // That is the OnInstall event 
  ...
}

ee the PHP file "tbs_plugin_syntaxes" to have all plug-in events, their usage and expected arguments. There is also a list of supported events at the bottom of this section.

The OnInstall event is special. It has to return an array with all activated events for the current plug-in (see the PHP file "tbs_plugin_syntaxes"). The OnInstall event is called when the plug-in is installed at the TBS instance.

This event can be called in three situations:

  • When using method PlugIn() with the plug-in's key for the first time.
  • When using method PlugIn() with the plug-in's key and the argument TBS_INSTALL.
  • When a new TBS instance is created, if the plug-in's key has be added to the global array $_TBS_AutoInstallPlugIns[] (see file "tbs_plugin_syntaxes.php" for more details).
• Property ->TBS:

As soon as the plug-in is installed on the TBS instance, a property ->TBS is automatically added to the plug-in, its value is a reference to the parent TBS instance. Remember this because this property can be very useful inside the plug-in's code.

Coding a plug-in using PHP functions:

The plug-ins' key is a string that you choose and which will be used for naming the function. It is recommended to define a PHP constant for the plug-in's key (see example below).

The plug-in events are coded using functions, and they names must be the string 'tbspi_', followed by the plug-in's key, followed by '_' and the event's name.

Example:

define('TBS_XXX', 'xxx');
function tbspi_xxx_OnInstall(...) {...}
...

All the rest works like for plug-in coded with a class. You must have at least the event OnInstall created, and it works the same way.

Remark: PHP functions are often faster than methods, but they don't let you having a ->TBS property to reach the parent TBS instance.

• List of plug-in events:
  Plug-in Events Description
OnInstall Executed automatically when the plug-in is called for the first time, or when PlugIn() method is called with the specific argument for installing.
OnCommand Executed when PlugIn() method is called. This is a way to execute any user command specific to the plug-in.
BeforeLoadTemplate Executed when LoadTemplate() method is called. Can cancel TBS basic process.
AfterLoadTemplate Executed at the end of LoadTemplate().
BeforeShow Executed when Show() method is called. Can cancel TBS basic process.
AfterShow Executed at the end of Show().
OnData Executed each time a record of data is retrieved for a MergeBlock() process. (similar to parameter 'ondata' but for every block)
OnFormat Executed each time a fields is being merged. (similar to parameter 'onformat' but for every fields)
OnOperation Executed each time parameter 'ope' is defined with an unsupported keyword.
OnCacheField Executed each time a field is put in the cache of a Block definition. (supported since TBS 3.6.0)
BeforeMergeBlock Executed when bounds of a block are founded. Can cancel TBS basic process.
OnMergeSection Executed when a section is merged, and before it is added to other sections.
OnMergeGroup Executed before a header, a footer or a splitter section is merged. (supported since TBS 3.3.0)
AfterMergeBlock Executed just before a merged block is inserted into the template.
OnSpecialVar Executed when a non native Special Var Field (like [onshow..now]) is met.
OnMergeField Executed on each field met when using the MergeField() method.

 

Summary:

TBS Field's parameters:

Parameter Summary
strconv

Char conversion Mode for the field's value.

htmlconv Deprecated, alias of strconv.
. (dot) If the value is empty, then display an unbreakable space.
ifempty If the value is empty, then display another value.
att Move the field into the attribute of an XML/HTML tag.
   attadd Use with att. Indicate that the merged value must be added instead of be replacing the attribute's value.
   atttrue Use with att. Indicate that the target attribute must be managed as a boolean attribute.
magnet If the value is empty, then delete surrounding tags.
   mtype Use with magnet.
if If the condition is verified, then change the value.
   then Use with if.
   else Use with if.
onformat Executes a Php user function to modify the field merging.
frm Apply a date-time or a numeric format.
tplfrms Use with onload fields only. Define template formats.
tplvars Use with onload fields only. Define template variables.
protect Protection mode for characters '['.
enlarge Enlarges the field's bounds up to the Commentary tag that surround it.
comm Deprecated, alias of enlarge.
noerr Avoid some TBS error messages.
file Includes the contents of the file.
script Executes the Php script.
   getpart Use with file or script. Insert only a part of the subtemplate.
   getbody Deprecated, alias of getpart.
   store Use with file or script. Store a part of the subtemplate in order to display it elsewhere.
   storename Use with store. Change the name of the store.
   rename Use with file or script. Rename TBS block and fields in a subtemplate.
   subtpl Use with script or onformat. Turns the TBS instance into subtemplate mode.

TBS Block's parameters:

Parameter Summary
block Defines the block's bounds.
nodata Indicates the section that is displayed when there is no data in the data source.
headergrp Indicates a header section that is displayed when the value of a column changes.
footergrp Indicates a footer section that is displayed when the value of a column changes.
splittergrp Indicates a splitter section that is displayed when the value of a column changes.
parentgrp Indicates a parent section that is displayed when the value of a column changes.
parallel Indicates a configuration for merging data in columns or with any custom parallel method.
serial Indicates a section that contains a series of several records.
p1 Sends a parameter to the dynamic query for the data source.
sub1 Define the column containing the data for an automatic subblock.
ondata Executes a Php user function to modify the record when it has just been taken from the data source.
when Use with onload or onshow. Displays the section when the condition is verified.
   default Use with onload or onshow. Displays the section when no section is displayed.
   several Use with when. Indicate that several blocks of the group can be displayed.

Names of Special Fields and Blocks:

Name Summary
val The keyword [val] can be used in field's parameters to represent the field's value.
# Virtual column name for a block. It displays the record's number.
$ Virtual column name for a block. It displays the record's key if the data source is a Php Array.
onload Automatic field or block, merged when the template is loaded.
onshow Automatic field or block, merged when the template is shown.
var Embedded automatic field.