This article refers to dap version 0.1.7

Lesson 1. Hello, world!

Here are some simple examples illustrating the dap way of document handling. The objective of these examples is to show that dap is not as weird as it might seem (if you have already read dap language quicktour).

Note: C-style //comments are used for short and are invalid in HTML. Cut them out, if you copy the example code into real HTML.

Welcome to dap

Dap functionality is currently implemented in javascript, and can be utilized in any HTML/XHTML document. Important: the document must have a proper !DOCTYPE declaration — this forces browsers to view the document in standards mode; dap may not work in quirks mode. Also, try to keep the document as well-spelled, as possible. The cleaner the better.

One very common issue with dap powered HTML files — the closing tags. Current versions of browsers don't respect self-closing tags in HTML files. It is not a big deal in ordinary HTML, where self-closing tags are generally useless (except <br />, <hr />, <img ... /> and a few others). You will hardly find an <h1/> tag in regular HTML. But when using dap, self-containg elements (elements having neither text, nor sub-elements inside) are very common. Content of such nodes is generated dynamically by their dap-rules, so the tags for such nodes need no any markup inside, and normally should be self-closing. But, as said above, browsers don't like self-closing tags and <h1 d="! =hello"/> will cause problems in an HTML file. The workaround is to use <h1 d="! =hello"></h1>-like constructs instead. The good news is that only HTML files are subject to this legacy abuse. In XML, any self-closing tags are okay, thus dap libraries (wich are pure XML files) don't suffer from this issue.

After all, delivering the dap power to an HTML document is as simple as:

<script type="text/javascript" src="http://dapmx.org/0.1.7/core.js"></script>

Status context and status entries

Status context is the most important concept in dap. Status context entries (or simply, status entries) provide a mechanism for defining dependencies between nodes in document. You might think of status entries as of ordinary variables, but with automatic change-tracking. When a status entry value is updated, all the nodes depending on it are automatically updated, too.

As any variables, status entries are bound to the scope they are defined in. A status entry's scope covers the node, wich introduces the entry, and its descendants. Nodes, interacting by means of a status entry, must be covered by its scope.

<div d=" $myVar=Hello,world!">//introduce a status entry $myVar in the scope of this node
 <h4 d="! $myVar"></h4>//write the $myVar's value into this h4. Thus, this node is dependent on $myVar
 <p>see the numeric value of:</p>
 <ul>
  <li d="ui" u=" $myVar=1">one</li>//ui mapper attaches event listener (click by default) to the node.
  <li d="ui" u=" $myVar=2">two</li>//u-rule is run on node event, and updates the $myVar,
  <li d="ui" u=" $myVar=3">three</li>//and this change will force dependent nodes to update, too
 </ul>
</div>

see the numeric value of:

The first thing about dap is: spell it correctly! You will notice, that steps in dap rules often start with a leading space. Such steps refer to the "empty" mapper, and this "leading" space is actually a separator between the empty name of the mapper and the first token.

The empty mapper does nothing beyond execution of its token list. Empty mappers in the example above (the <div>'s d-rule and <li>s' u-rules) assign a literal value to $myVar status entry. Assigning a value to a status entry in d-rule (down phase) introduces a new entry; assigning in u-rule (up-phase) updates its value.

The <h4>'s d-rule writes $myVar's value into the node by means of dap core ! mapper. Since $myVar is used to generate <h4>'s content, the node is marked dependent from $myVar and will rebuild each time $myVar is updated.

The <li>s' d-rule consists of a single ui mapper, which adds an event listener (click by default) to the node. When the event comes, the node launches up-phase: executes its own u-rule, and bubbles the u-phase up to its parent and so on.

Converters

Converters allow to transform the value of a token prior to feeding it to the mapper. Simplest converters are just string-to-string functions.

You might notice, that the "Hello,world!" string from the previous example lacks a whitespace after the comma. That is, because a space character is reserved in dap as tokens separator and thus can't be used in literal values, as well as in aliases and entry references. Equal sign (=) is also invalid in literals. To provide a literal containing whitespaces or equal signs, or any symbols not allowed in an XML-node attribute, use escaped representation of the literal and usc converter to unescape it:

<i d="! :usc=Yes,%20you%20can%20use%20spaces%20and%20'%3D'%20signs!"></i>

NOTE: This purely syntactical restriction on whitespaces is only applied to literals provided immediately in the dap rule. Values, obtained from datasources or whatever calculated are free from it. Another good reason to keep long textual messages in a separate resource file.


Data context and data entries

Instead of repeating similar patterns in document code, the pattern can be programmatically repeated by * mapper. When a rowset is populated, the rest of the rule (including the node's content execution) is performed for each row in the rowset. And for each of those rows a new data scope is created. All the nodes, generated for one row share this row's data scope. Outer (parent) data scopes are inherited by inner data scopes and remain visible from within them. Thus, a node's data context includes entries of all its data scopes.

The most straightforward way of providing a rowset is building it from a literal by some string-to-rowset converter. Dap core provides a few such converters, two of them are: csv (comma separated values) and nvp (after "name:value pairs", though this name is not ideally exact)

In the example below, <tbody> populates <tr> pattern from a literal by the nvp converter.

<div d=" $color=black $hex=000">//introduce status entries (with initial values)
 <h4 d="htm.style@color=concat =# $hex; !=space $color :usc=color's%20RGB%20value =is $hex"></h4>
 <table class="grid">
  <thead>
   <tr>
    <th>RGB</th>
    <th>color</th>
   </tr>
  </thead>
  <tbody d="* :nvp@color,hex=red:F00;yellow:FF0;green:0F0;cyan:0FF;blue:00F">
   //content is repeated for each row in the dataset
   <tr d="ui" u=" color$ hex$">//on user event, status entries are updated from corresponding data entries
    <td style="color:white" d="htm.style@backgroundColor=concat =# hex; ! hex"></td>
    <td d="! color"></td>
   </tr>
  </tbody>
 </table>
</div>


RGB color

Here, the <h4>'s color and <td>'s backgroundColor style properties are set by htm.style mapper. This is not a core dap mapper. It is defined in starter-kit/htm.xml extension library.

The proper notation of a web-color is constructed by concatenation of # (a mesh sign) and an RGB value. The mesh sign is provided literal, RGB value is taken from the row's color data entry, and both tokens are concatenated by the concat flattener. Resulting value is fed to the htm.style mapper which assigns it to the node's style aspect specified by the alias.

The space flattener concatenates tokens by a single space, which is useful for joining separate words into a sentence. Here, in <h4> it concatenates color name (taken from the color data entry), some introductory literals and the color's RGB value (taken from the hex field) into a human-readable predicate.

U-rules of tr elements in resulting table update $color and $hex status entries, and thus force the dependent h4 node rebuild. Both tokens of the rule a written in shortened form: name$, which is equivalent to name$name, which, by token structure definition, copies a data entry value into its namesake status entry.

U-rules are executed, starting from the node that launched u-phase, and bubbling up throught all its ancestors. Thus, actions common to a number of nodes, may be delegated to their common ancestor.

<div d=" $what=house $who=Jack">
 <span class="box">
  <p>This is the <i d="!=space $what =that $who =built"></i>.</p>
  <p>This is the malt that lay in the <i d="!=space $what =that $who =built"></i>.</p>
  <p>This is the rat that ate the malt that lay in the <i d="!=space $what =that $who =built"></i>.</p>
 </span>
 <span class="box">
  <ul d="* :csv@who=Arnie,Sly,Bruce" u=" $what=planet">//These built a planet
   <li d="ui; ! who" u=" who$"></li>
  </ul>
  <ul d="* :csv@who=Cartman,Kenny,Stan,Kyle" u=" $what=clubhouse">//Theese built a clubhouse
   <li d="ui; ! who" u=" who$"></li>
  </ul>
 </span>
</div>

This is the .

This is the malt that lay in the .

This is the rat that ate the malt that lay in the .

In this example, the $who entry is updated by the li ui elements, while the $what entry is updated by the associated uis' common ancestors — the ul elements.


Getting external data

Rowsets can also be obtained from external files. The simplest case is a static XML dataset. Typical XML datasets can be loaded and parsed by dap core #dat converter. This converter "converts" an URL into a file, loaded from that URL, and that file "converts" into a rowset. The resulting rowset can be immediately fed to a rowset populator (* mapper), or stored in a data or status entry for later use.

The example below imitates a simple mini-site with basic navigation through pages.

<div>
 <table>
  <tbody>
   <tr d=" $page=home">//current page is pointed by a status entry
    <td>
     <ul d="* :csv@page=home,pricelist,contacts">//menu is populated as a static rowset
      <li d="! page; htm.?@chosen=eq page $page; ui" u=" page$"/>
     </ul>
    </td>
    <td>
     <div d="? $page@home">//when $page is equal to 'home' - allow this div
      <h3>Home page</h3>
      <p>This virtual mini-site sells MiG aircrafts. Check the pricelist, and choose yours.</p>
     </div>
     //the pricelist div
     <div d="? $page@pricelist;  $name= $info=">
      //if no model is chosen yet, display an invitation message
      <h3 d="? $name:!@">Select a model from the list below</h3>
      //once the model is chosen, show its name and info
      <h3 d="? $name@">Description of <span d="! $name"></span></h3>
      <p d="! $info" style="height: 60px"></p>
      <table class="grid">
       <tbody d="* :#dat=/samples/pricelist.xml">//data is taken from external XML file
        <tr d="ui" u=" name$ description$info">
         <td d="!=space =Product product"></td>
         <td d="! name"></td>
         <td d="!=space =$ price:fo.num"></td>
        </tr>
       </tbody>
      </table>
     </div>
     //contacts div
     <div d="? $page@contacts">
      <h3>Contact information</h3>
      <p>To purchase a MiG or a Su, please don't hesitate to contact:</p>
      <a href="http://www.roe.ru/" target="_blank">RosOboronExport</a>
     </div>
    </td>
   </tr>
  </tbody>
 </table>
</div>

Home page

This virtual mini-site sells MiG aircrafts. Check the pricelist, and choose yours.

Select a model from the list below

Description of :

Contact information

To purchase a MiG or a Su, please don't hesitate to contact:

RosOboronExport

* Product descriptions are taken from Wikipedia.

* Actual prices may differ from given here.

In this example, data is taken from external XML file: /samples/pricelist.xml. Flat prices from the file are formatted (digit groups separates to better distinguish the number's order of magnitude) by num converter from starter-kit/formats.xml library.

To highlight the selected menu item, htm.? mapper is used in conjuction with eq flattener. Dap core eq flattener compares tokens from the token list and succeeds (returns true) when they are all equal. The htm:? mapper checks resulting value, and if it is true, applies specified CSS-class to the node, otherwise removes that CSS-class from it. Thus, for each particular <li> element, value of page entry of its data scope is compared against $page status entry value; if they match, .chosen CSS-class assigned to that <li>; otherwise .chosen is taken off that <li>.


Using external libraries

To use an external dap library in the page, the library is loaded by dap core #lib converter. Earlier on this page we used the starter-kit/htm.xml and starter-kit/formats.xml libraries. The referene to these libraries can be found in this document's <body> d-rule:

<body class="samples" d=":#lib @htm=starter-kit/htm.xml @fo=starter-kit/formats.xml">

You may create your own libraries and use them across multiple pages of a project or even across multiple projects. Actually, this is the recommended way of building large-scale dap projects. Building a dap library is even simpler then building a dap powered HTML-page. Detailed description of the process is given in the next lesson.

IMPORTANT: Currently, due to browsers' security restrictions, dap core #-converters can load data (yes, dap libraries are data, too) only from the same domain, as of the main page. Thus, to use Starter-Kit libraries, you need them downloaded and deployed on your webserver.


Dap & CSS

The highlight styles used here, might look not very elegant. These styles have no relation to dap functionality. All appearance-related aspects (fonts, colors, borders, etc.) are defined in respective CSS-stylesheets and dap itself does nothing about visual appearance of page elements.

However, there are, currently two, css-classes related to dap:

In the attached ui.css file, these classes are defined as follows:

.ui{cursor:pointer; }
.over{color:red; }
.chosen{background-color:yellow; } /* not a dap-related class, but addressed by htm.?@chosen clause */
		

In your own work, you will certainly make them more good-looking.


Placing the "powered by dap" logo

Please, don't forget to place the "powered by dap" logo (with a hyperlink to dap home page) on your dap-powered page. This will help dap in its World Dominance Plot и спасет отца русской демократии.

<a target="_blank" href="http://dapmx.org">
 <img src="http://dapmx.org/logo/powered-by-dapmx-0-1.gif" alt="DAPMX 0.1" border="0" style="border:none" />
</a>

The preferred place for the logo is somewhere around the bottom-left corner, or anywhere else on your choice.

Next, you might wish to see:


DAPMX 0.1