PHPackages                             lucinda/view-language - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. lucinda/view-language

ActiveLibrary[Templating &amp; Views](/categories/templating)

lucinda/view-language
=====================

High performance view templating API for PHP applications using tags &amp; expressions inspired by Java JSTL and C Compiler

v4.1.2(1y ago)024.0k33MITPHPPHP ^8.1

Since Nov 7Pushed 1y ago2 watchersCompare

[ Source](https://github.com/aherne/php-view-language-api)[ Packagist](https://packagist.org/packages/lucinda/view-language)[ Docs](https://github.com/aherne/php-view-language-api)[ RSS](/packages/lucinda-view-language/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (66)Used By (3)

View Language API
=================

[](#view-language-api)

Table of contents:

- [About](#about)
    - [Expressions](#expressions)
    - [Tags](#tags)
- [Configuration](#configuration)
- [Compilation](#compilation)
- [Installation](#installation)
- [Unit Tests](#unit-tests)
- [Examples](#examples)
- [Reference Guide](#reference-guide)

About
-----

[](#about)

This API is the PHP compiler for ViewLanguage templating engine, a markup language inspired by JSP&amp;JSTL @ Java that acts like an extension of HTML standard, designed to completely eliminate the need for scripting in views by:

- interfacing variables through **[expressions](#expressions)**.
- interfacing logics (control structures, repeating html segments) through **[tags](#tags)**

[![diagram](https://camo.githubusercontent.com/538fc0ace22c2e433a1307d59f7b3242adef314bb9dacc06e145c33fa1b459a0/68747470733a2f2f7777772e6c7563696e64612d6672616d65776f726b2e636f6d2f766965772d6c616e67756167652d6170692e737667)](https://camo.githubusercontent.com/538fc0ace22c2e433a1307d59f7b3242adef314bb9dacc06e145c33fa1b459a0/68747470733a2f2f7777772e6c7563696e64612d6672616d65776f726b2e636f6d2f766965772d6c616e67756167652d6170692e737667)

In order to achieve its goals, following steps need to be observed:

- **[configuration](#configuration)**: setting up an XML file where templating is configured
- **[compilation](#compilation)**: using [Lucinda\\Templating\\Wrapper](https://github.com/aherne/php-view-language-api/blob/master/src/Wrapper.php) to read above XML and compile a template

API is fully PSR-4 compliant, only requiring PHP8.1+ interpreter and SimpleXML extension. To quickly see how it works, check:

- **[installation](#installation)**: describes how to install API on your computer, in light of steps above
- **[unit tests](#unit-tests)**: API has 100% Unit Test coverage, using [UnitTest API](https://github.com/aherne/unit-testing) instead of PHPUnit for greater flexibility
- **[examples](#examples)**: shows an example how to template with ViewLanguage, including explanations for each step
- **[reference guide](#reference-guide)**: shows list of tags that come with API

Expressions
-----------

[](#expressions)

An **expression** is a ViewLanguage representation of a *scripting variable*. Syntax for an expression is:

```
${variableName}
```

where **variableName** can be:

DescriptionViewLanguage ExamplePHP Translationa scalar variable${foo}$fooan array variable, where hierarchy is represented by dots${foo.bar}$foo\["bar"\]a back-end helper function (native or user-defined)${htmlspecialchars(${foo.bar})}htmlspecialchars($foo\["bar"\])a short if using ternary operators${(${foo.bar}!=3?"Y":"N")}($foo\["bar"\]!=3?"Y":"N")A very powerful feature is the **ability to nest expressions**: writing expressions whose key(s) are expressions themselves. This can go at any depth and it is very useful when iterating through more than one list and linking a one to another's key/value association:

ViewLanguage ExamplePHP Translation${foo.bar.${baz}}$foo\["bar"\]\[$baz\]Tags
----

[](#tags)

A **tag** is a ViewLanguage representation of a *scripting logic*. All tags act like an extension of HTML standard and as such they have names and optionally attributes and bodies. There are two types of tags known by ViewLanguage:

- [macro tags](#macro-tags): api-defined tags to be processed before content is compiled.
- [library tags](#library-tags): api/user-defined tags subject to compilation that belong to a library and have an unique name within that library.

A very powerful feature is the **ability of tags to be recursive**: it is allowed to put View Language tags inside View Language tags. Whenever that happens, compiler goes progressively deeper until no tags are left!

### Macro Tags

[](#macro-tags)

**Macro tags** work in a way similar to C macros: before code is compiled, they are read and "expanded" so that compilation will run on a full source. Syntax is identical to that of normal HTML tags:

```

```

Where:

- **NAME**: name of tag that performs a single logical operation.
- **ATTRIBUTE**: configures tag behavior

API defines following macro tags:

- [escape](#tag-escape): tag whose body will be ignored by compiler. This is necessary to mark content inside as not subject to parsing.
- [import](#tag-import): tag whose declaration will be replaced by compiler with the body of file pointed by its "file" attribute. This is crucial for layouting/templating.
- [namespace](#tag-namespace): tag whose declaration will inform compiler where to look for tag libraries not found in default folder.

At the moment, it is not possible for users to define their own macro tags!

### Library Tags

[](#library-tags)

**Library tags** are compilable api/user-defined HTML snippets expected to implement scripting logic in a View Language application. They are non-static repeating snippets of template (html) code that depend on variables and thus can't be loaded using .

Their syntax extends HTML standard:

```
...
```

or, if they have no body:

```

```

Where:

- *LIBRARY*: namespace that contains related logical operations to perform on a template. Rules:
    - Value must be lowercase and alphanumeric.
    - "-" sign is allowed as well to replace spaces in multi-word values
- *TAG*: name of tag that performs a single logical operation.Rules:
    - Value must be lowercase and alphanumeric.
    - sign is allowed as well to replace spaces in multi-word values
- *ATTRIBUTE*: configures tag behavior (can be zero or more). Rules:
    - Name must be lowercase and alphanumeric.
    - "\_" sign is allowed as well to replace spaces in multi-word names
    - Value can only be primitive (string or number) or ViewLanguage expressions.
    - Unlike standard HTML, attributes cannot be multilined currently.

#### Standard Tags

[](#standard-tags)

API includes a **standard library** containing tags for programming language instructions where *LIBRARY* is empty:

- [:for](#tag-for): iterates numerically through a list
- [:foreach](#tag-foreach): iterates through a dictionary by key and value
- [:if](#tag-if): evaluates body fitting condition
- [:elseif](#tag-elseif): evaluates body fitting condition that did not met previous if/elseif.
- [:else](#tag-else): evaluates body that did not met previous if/else if
- [:set](#tag-set): creates a variable and/or sets a value for it.
- [:unset](#tag-unset): unsets a variable.
- [:while](#tag-while): performs a loop on condition.
- [:break](#tag-break): ends loop.
- [:continue](#tag-continue): skips evaluating the rest of current loop and moves to next iteration.

Standard tags work with *ATTRIBUTE* values of following types:

- *scalars*: strings or integers
- *EXPRESSION*: ViewLanguage expressions. If helper functions are used as attribute values, they must be left undecorated: *count(${asd})* instead of *${count(${asd})}*.
- *CONDITION*: syntax is expected to be C-like, but ultimately matches that of language code is compiled into (in our case, PHP). Example: *${x}==true* means in PHP *$x==true*.

#### User Defined Tags

[](#user-defined-tags)

In order to break up HTML response into discrete units, developers must create their own libraries &amp; tags. User defined tags are found on disk according to these rules:

- library name must be a folder inside tags folder supplied on compilation
- tag code muse be a HTML file inside library folder whose name equals *name*

ViewLanguage ExamplePHP Translation&lt;foo:baz attr="1"/&gt;$contents = file\_get\_contents($tagsFolder."/foo/baz.html");
// replaces all occurrences of $\[attr\] with 1Configuration
-------------

[](#configuration)

To configure this API you must have a XML with a **templating** tag inside:

```

```

Where:

- **compilations\_path**: (mandatory) path into which PHP compilations of ViewLanguage templates are saved
- **tags\_path**: (optional) path into which ViewLanguage tag libraries are located
- **templates\_path**: (optional) path into which templates are located
- **templates\_extension**: (optional) template files extension. If not set, "html" is assumed!

Example:

```

```

Compilation
-----------

[](#compilation)

Once you have completed step above, you need to instantiate [Lucinda\\Templating\\Wrapper](https://github.com/aherne/php-view-language-api/blob/master/src/Wrapper.php) in order to be able to compile templates later on:

```
$wrapper = new Lucinda\SQL\Wrapper(simplexml_load_file(XML_FILE_NAME));
```

Object has following method that can be used to compile one or more templates:

MethodArgumentsReturnsDescriptioncompilestring $template, array $datastringCompiles ViewLanguage template into HTML and returns result### How are templates compiled?

[](#how-are-templates-compiled)

As in any other templating language, compilation first traverses the tree of dependencies ever deeper and assembles result into a PHP file then produces an HTML by binding it to data received by user. It thus involves following steps:

- if a PHP compilation for *$template* argument exists, checks if elements referenced inside have changed since it was last updated. If it doesn't exist or it changed:
    - parses **[](#tag-import)** tags recursively (backing-up **[](#tag-escape)** tag bodies in compilation file to be excluded from parsing) and appends results to compilation file
    - parses **[](#tag-namespace)** tags defined in templates, to know where to locate user-defined tag libraries not defined in default taglib folder
    - parses **[library tags](#library-tags)** recursively (backing-up **[](#tag-escape)** tag bodies in compilation file to be excluded from parsing) and replaces them with relevant PHP/HTML code in compilation file.
    - parses **[expressions](#expressions)** and replaces them with relevant PHP code in compilation file.
    - restores backed up **[](#tag-escape)** tags bodies (if any) in compilation file
    - caches new compilation on disk along with a checksum of its parts (templates, tags) for future validations
- in output buffer, loads compilation file, binds it to *$data* supplied by user and produces a final HTML out of it

Since the whole process is somewhat performance hungry, PHP compilation files will be cached on disk and returned directly on next requests unless one of its components (template or tag) has changed. This makes API able to compile in around 0.001 sec amortised time, thus bringing no performance taxation whatsoever but all the advantages of an elegant view!

Installation
------------

[](#installation)

First choose a folder where API will be installed then write this command there using console:

```
composer require lucinda/view-language
```

Then create a *configuration.xml* file holding configuration settings (see [configuration](#configuration) above) and a *index.php* file in project root with following code:

```
require(__DIR__."/vendor/autoload.php");
$wrapper = new Lucinda\SQL\Wrapper(simplexml_load_file("configuration.xml"));
```

To compile a template:

```
$html = $wrapper->compile(TEMPLATE_NAME, USER_DATA);
```

Where:

- TEMPLATE\_NAME is the *base template* that must obey following rules:
    - must be a path to a file located in *templates\_path* (see **[configuration](#configuration)**)
    - file it points to must have *templates\_extension* (see **[configuration](#configuration)**)
    - because of above, must not include extension
- USER\_DATA is a list of values from back-end to be accessed in template, obeying following rules:
    - must be an array
    - entry keys must be strings or integers (the usual PHP requirements)
    - entry values must be scalars or arrays
    - if array is multidimensional, keys and values in siblings must obey same rules as above

To display results:

```
header("Content-Type: text/html; charset=UTF-8");
echo $html;
```

Unit Tests
----------

[](#unit-tests)

For tests and examples, check following files/folders in API sources:

- [unit-tests.sql](https://github.com/aherne/php-view-language-api/blob/master/unit-tests.xml): SQL commands you need to run ONCE on server (assuming MySQL) before unit tests execution
- [test.php](https://github.com/aherne/php-view-language-api/blob/master/test.php): runs unit tests in console
- [unit-tests.xml](https://github.com/aherne/php-view-language-api/blob/master/unit-tests.xml): sets up unit tests and mocks "sql" tag
- [tests](https://github.com/aherne/php-view-language-api/tree/v3.0.0/tests): unit tests for classes from [src](https://github.com/aherne/php-view-language-api/tree/v3.0.0/src) folder

Examples
--------

[](#examples)

Assuming *configuration.xml* (see **[configuration](#configuration)** and **[installation](#installation)**) is:

```

```

Let's create a *application/views/index.html* template with following body:

```

Hello, dear ${data.author}! Author of:

```

What above does is:

- loads body of a *application/views/header.html* template
- echoes value of *author* array key of $data via **[expressions](https://www.lucinda-framework.com/view-language/expressions)**
- loops through value of *apis* array key of $data via **[&lt;:foreach&gt;](https://www.lucinda-framework.com/view-language/standard-tags#:foreach)**
- on every iteration, loads body of *application/taglib/my/api.html* template (user tag), binding attributes to values
- loads body of a *application/views/footer.html* template

Contents of *application/views/header.html* file:

```

        View Language API Tutorial

```

Contents of *application/taglib/my/api.html* file:

```
$[link]
```

Contents of *application/views/footer.html*:

```

```

As one can see above, templates depend on variables to be received from back-end (*author* &amp; *apis*), both keys of **$data** array. Assuming value of latter is:

```
$data = [
	"author" => "Lucian Popescu",
	"apis" => ["View Language API" => "https://www.lucinda-framework.com/view-language", "STDOUT MVC API" => "https://www.lucinda-framework.com/stdout-mvc"]
];
```

Now let's compile *application/views/index.html* template (see **[compilation](#compilation)**) and bind it to *$data*:

```
require(__DIR__."/vendor/autoload.php");
$wrapper = new Lucinda\SQL\Wrapper(simplexml_load_file("configuration.xml"));
$html = $wrapper->compile("index", $data);
```

First, ViewLanguage base template is compiled into PHP, results saved in a **compilations/index.php** file (in case it doesn't exist already) with following body:

```

        View Language API Tutorial

        Hello, , author of:

            $url) { ?>
