PHPackages                             rossato/declarative-php - 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. [Framework](/categories/framework)
4. /
5. rossato/declarative-php

ActiveLibrary[Framework](/categories/framework)

rossato/declarative-php
=======================

A micro-framework for building declarative and static web applications in PHP

v1.1(6y ago)1110MITPHPPHP &gt;=5.3.0

Since Jan 15Pushed 2y ago2 watchersCompare

[ Source](https://github.com/GuilhermeRossato/declarative-php)[ Packagist](https://packagist.org/packages/rossato/declarative-php)[ RSS](/packages/rossato-declarative-php/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (6)Dependencies (2)Versions (7)Used By (0)

[![Declarative PHP](https://github.com/GuilhermeRossato/declarative-php/raw/master/logo.png?raw=true)](https://github.com/GuilhermeRossato/declarative-php/blob/master/logo.png?raw=true)

🔨 Simple micro-framework for building declarative web applications in PHP 📰

Minimal experimental PHP framework inspired by ReactDOM to create web pages in a declarative way.

Create dynamic elements through php classes that render into HTML.

Getting started
---------------

[](#getting-started)

After installing this framework with `composer require rossato/declarative-php` you can build elements with the Element constructor: The class constructor receives 3 arguments: the element tag name, the properties array and the content of the element (its children):

```
require "vendor/autoload.php"

use Rossato\Element;

$div = new Element(
    "div",                   // tag name
    ["class" => "custom"],   // properties (as associative array)
    "text"                   // content
);

echo $div;
```

This outputs an html `div` element with the `custom` class and `text` as content, like so: `text`

### Nested examples

[](#nested-examples)

Elements can be nested, the third, fourth, and other parameters can be other elements

```
use Rossato\Element;

echo new Element(
    "ul",
    ["style" => "margin: 10px"],
    new Element("li", null, "First element"),
    new Element("li", null, "Second element")
);
```

You can also supply an array of elements as children:

```
use Rossato\Element;

echo new Element(
    "form",
    ["style" => "margin: 10px"],
    [
        new Element("input", ["type" => "text", "id" => "hello"]),
    ]
);
```

Generates the following:

```

```

### Functional usage

[](#functional-usage)

You are supposed to create components like this:

```
use Rossato\Element;

function Form($url) {
    return new Element("form", ["action" => $url],
    	new Element("input", ["type" => "submit", "value" => "Submit"])
    );
}

function App() {
    return new Element("div", [],
    	Form("/send/"),
	Form("/submit/")
    ]);
}

echo App();
```

### Page example

[](#page-example)

The Page element is useful if you're doing top-level stuff, it is supposedly the page's HTML tag element:

```
use Rossato\Element;
use Rossato\Page;

$page = new Page([
    new Element("title", [], "Title in the head tag")
], [
    new Element("h1", [], "Title in the body tag")
]);

echo $page; // "Title in the head tagTitle in the body tag"
```

Inspiration
-----------

[](#inspiration)

React (the javascript library / framework) has an interesting way of defining components and their hierarchical relations. This experiment is supposed to explore that on PHP.

PHP already has a DOM library internally, but it's full of features such as querying and parsing, this library is only focused on building html elements that are sanitized so that you can just do stuff. This library is [2 source files](https://github.com/GuilhermeRossato/declarative-php/tree/master/src/Rossato) big and handles attribute and content sanitization.

```
$userInput = "what\">console.log('nope')" . escapeHTML($this->$content) . "";
    }
}
```

You can probably read and understand this library in 15 minutes.

Problems you can solve using this
---------------------------------

[](#problems-you-can-solve-using-this)

Transforming data in PHP to HTML is difficult because html is not strictly validated in general:

```

    Price:

```

You think your browser will let you know that you mispelled 'span' on the second closing tag? Nope, the browser just silently goes on.

You can take advantage of PHP interpreter to tell you if something is incorrect with syntax errors that fail fast.

The idea is to declare in composition-based components all the visual logic, with the data that it needs to render fully.

React developers have been doing this in javascript, its tremendously useful and the same coding rules apply. Sadly implementing JSX is a huge chore and I don't think PHPX would catch on.

### Managing data

[](#managing-data)

Data has to be passed around in a top-down fashion:

```
function Post($index, $title, $text) {
    return new Element(
        "article",
        ["class"="article-".$index],
        new Element("h2", [], $title),
        new Element("p", [], $text),
    );
}

function PostList($postData) {
    $postList = [];
    $index = 0;
    foreach ($postsData as $name => $post) {
        $index++;
        $postList[] = new Post($index, $name, $post);
    }
    return new Element("div", ["class" => "post-list"], $postList);
}

$postsData = [
    "My life as a developer" => "It was fun",
    "I'm declaring" => "data like normal",
    "And html elements treat" => "and using it easily"
];

echo PostList($postData); // Renders pure html (but it may also throw if rendering fails)
```

Obviously, you're left alone regarding how and where you get data. But be advised: **All security rules still apply and you must [strip your tags](http://php.net/manual/pt_BR/function.strip-tags.php) from your data!**.

Instalation
-----------

[](#instalation)

But you should use `composer` to install the project from the command line, at the folder of your project:

```
composer require rossato/declarative-php

```

Just don't forget to require composer's autoload on your entry point:

```
require "vendor/autoload.php";
```

And at the top of every file you need to use the Element class, you write this:

```
use Rossato\Element;

```

Now everytime you write `Element` you'll be referring to this project's Element.

Alternatively, you can download this repository and require the files inside `/src/` manually, no credits required.

Automatic Compressing of Styles in Elements
-------------------------------------------

[](#automatic-compressing-of-styles-in-elements)

Alright, there's just ONE piece of magic in this library: they `style` property of html elements are heavily featured in two ways:

1. If you put in an object on the property, it becomes the string representation of that object:

```
$style = [
    "width" => 200,
    "height" => 200,
    "background-color" => "red"
];
echo new Element("div", ["style" => $style]);;
```

```

```

2. But if you put a raw string, then we minimize it with a simplistic function to save a few bytes every now and then:

```

```php
echo new Element("div", ["style" => "/* Text color comment */ color : red; background : blue; "]);

```

```

```

CSS is such a simple language that there is hopefully no downsite on minifying it.

Javascript
----------

[](#javascript)

You can tell this library to f\*ck off regarding it html escaping:

```
$script = new Element("script", [], "console.log('hi ');");

echo $script; // 'console.log('hi &gt;div&lt;&gt;div&lt');"

$script->isRawHTML = true;

echo $script; // 'console.log('hi ');"

```

Obviously there isn't any javascript minification going on because that would require quite a lot of code.

Usage advice
------------

[](#usage-advice)

I don't think you should write your whole web app with this tool (but if you do, let me know), only in situations where your data critically changes your output structure.

For example, when you fetch your own application for a list of items, you could use this to easily compose the list and return it as a HTML that you can just "plug" into your frontend easily, you could even detect if the user is logged in or not and show an appropriate message, or if something went wrong with the data retrieval, or whatever. All your javascript has to care about is fetching.

```
async function requestData() {
    const element = document.querySelector(".content");
    document.querySelector(".content").innerHTML = "loading...";
    const response = await fetch("/api/endpoint/");
    const html = await response.text();
    document.querySelector(".content").innerHTML = content;
}

requestData();
```

And at the endpoint you could just handle that

```
