{"id":22412803,"url":"https://github.com/leongrdic/php-dataplater","last_synced_at":"2025-07-31T23:31:02.559Z","repository":{"id":38533950,"uuid":"463657582","full_name":"leongrdic/php-dataplater","owner":"leongrdic","description":"template engine that uses HTML data-* attributes so your templates look great before rendering","archived":false,"fork":false,"pushed_at":"2022-09-12T09:09:25.000Z","size":65,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-30T14:06:26.977Z","etag":null,"topics":["data-attributes","html","html-data-attributes","html5","php","template","template-engine","templating-engine"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leongrdic.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-25T19:49:18.000Z","updated_at":"2024-04-23T18:33:10.000Z","dependencies_parsed_at":"2022-09-02T01:00:12.343Z","dependency_job_id":null,"html_url":"https://github.com/leongrdic/php-dataplater","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leongrdic%2Fphp-dataplater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leongrdic%2Fphp-dataplater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leongrdic%2Fphp-dataplater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leongrdic%2Fphp-dataplater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leongrdic","download_url":"https://codeload.github.com/leongrdic/php-dataplater/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228312174,"owners_count":17900218,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-attributes","html","html-data-attributes","html5","php","template","template-engine","templating-engine"],"created_at":"2024-12-05T14:10:26.008Z","updated_at":"2024-12-05T14:10:26.751Z","avatar_url":"https://github.com/leongrdic.png","language":"PHP","readme":"# Dataplater\n\n[![release](http://poser.pugx.org/leongrdic/dataplater/v)](https://packagist.org/packages/leongrdic/dataplater)\n[![php-version](http://poser.pugx.org/leongrdic/dataplater/require/php)](https://packagist.org/packages/leongrdic/dataplater)\n[![license](http://poser.pugx.org/leongrdic/dataplater/license)](https://packagist.org/packages/leongrdic/dataplater)\n[![run-tests](https://github.com/leongrdic/php-dataplater/actions/workflows/run-tests.yml/badge.svg)](https://github.com/leongrdic/php-dataplater/actions/workflows/run-tests.yml)\n\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28%0A%20%20%20%20template%3A%20%22This%20is%20%3Cvar%20data-dp%3Dphp.strrev%28%60emosewa%60%29%3E%3C%2Fvar%3E%22%0A%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%29%3B%0Aprint_r%28%24result%29%3B)\n\nDataplater is a templating engine written in PHP that uses HTML data-attributes and keeps templates valid and clean.\nThis makes Dataplater perfect for creating document templates like invoices, contracts, emails, etc. which can be **previewed in the browser before rendering**.\n\n## Features\n- 💻 make HTML templates that look great even before rendering\n- 💾 use data-attributes to pass data into your template\n- ⚡ powerful expression language ([SMPLang](https://github.com/leongrdic/php-smplang))\n- 📩 automatic escaping\n- 👍 UTF-8 support\n- 🧮 access to php functions in expressions\n- 🔗 include HTML files\n- ➿ nested foreach loops\n- 🔤 set inner HTML or custom attributes of elements\n- 🗑️ delete elements based on conditions\n\n\n## Examples\n\n```html\nThis is \u003cvar data-dp=php.strrev(`emosewa`)\u003e\u003c/var\u003e\n\u003c!-- line above becomes: --\u003e\nThis is \u003cvar\u003eawesome\u003c/var\u003e\n```\n\n\nI actually created an [invoice template](https://leongrdic.github.io/php-dataplater/invoice.html) for Dataplater that's used in production.\nThe template's source code is [here](examples/invoice.html).\n\n## Install\n```shell\ncomposer require leongrdic/dataplater\n```\n\n### Requirements\n\n- PHP 8.0+\n- DOM \u0026 XML extensions\n\n## Usage\n\n```php\n$dp = new \\Le\\Dataplater\\Dataplater(\n    filename: 'template.html', // path relative to baseDir or an absolute path\n    // OR\n    template: '\u003chtml\u003e...\u003c/html\u003e', // doesn't have to be a full HTML document\n    \n    // optional:\n    vars: [ 'var' =\u003e 'value', ], // global vars\n    baseDir: 'app/templates/', // base directory for templates\n    attr: 'data-custom' // custom base attribute\n);\n```\n\nWhen creating a Dataplater object, you can either provide a **path to your template file** or pass the **template as a string**.\nThe recommended way to initialize the object is by using PHP8's named arguments.\n\nOptional parameters:\n- `vars`: an array of global vars to pass into the template with keys being the vars' names\n- `baseDir`: the base directory to use for includes (defaults to `.`)\n- `attr`: the base attribute name to use for all attributes (defaults to `data-dp`)\n\n### `render()` method\n\n```php\n$html = $dp-\u003erender([\n    'var' =\u003e 'local value',\n    'function' =\u003e fn () =\u003e 'some value',\n]);\n```\n\nThe `render()` method renders the template and returns the rendered HTML as a string.\n\nThe optional parameter is an array of local vars that will override any global vars with the same name.\n\nYou can call this method multiple times on the same object with different vars to render multiple variants of the same document.\n\n\n## Attribute reference\n\nIf you change the base attribute to e.g. `data-custom` (when creating the Dataplater object), use `data-custom-foreach` instead of `data-dp-foreach`.\n\nAll Dataplater attributes will be automatically removed from the template after rendering.\n\n### `data-dp-include`\n**Value**: filename of the HTML template to include.\n\nContent of the included file will be inserted into the document replacing the element with the `data-dp-include` attribute.\n\n```html\n\u003ctemplate data-dp-include=\"include.html\"\u003e\u003c/template\u003e\n```\n\n### `data-dp-if`\n**Value**: SMPL expression\n\nIf the expression evaluates to `true`, the element will be rendered, otherwise it will be removed.\n\n```html\n\u003cdiv data-dp-if=false\u003ethis element will always be removed\u003c/div\u003e\n\n\u003cdiv data-dp-if=\"id \u003e 1\"\u003ethis will be rendered if the condition is met\u003c/div\u003e\n```\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24html%20%3D%20%3C%3C%3CHTML%0A%3Cdiv%20data-dp-if%3Dfalse%3Ethis%20element%20will%20always%20be%20removed%3C%2Fdiv%3E%0A%0A%3Cdiv%20data-dp-if%3D%22id%20%3E%201%22%3Ethis%20will%20be%20rendered%20if%20the%20condition%20is%20met%3C%2Fdiv%3E%0AHTML%3B%0A%0A%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28template%3A%20%24html%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%5B%27id%27%20%3D%3E%202%5D%29%3B%0A%0Aprint_r%28%24result%29%3B)\n\n### `data-dp-foreach`\n**Value**: SMPL expression\n\n**Additional attributes**:\n- `data-dp-key`: name of var in which will be the current element key (optional)\n- `data-dp-value`: name of var in which will be the current element value (required)\n\nThe expression must evaluate to an array or an iterable object.\nChildren of the element with the `data-dp-foreach` attribute will be copied for each iteration and the `data-dp-key` and `data-dp-value` vars will be set to the current element key and value to be used in those child elements.\n\nThe element containing the `data-dp-foreach` attribute will be removed after the loop.\n\n```html\n\u003cul\u003e\n    \u003ctemplate data-dp-foreach=['google','youtube'] data-dp-var=name data-dp-key=id\u003e\n        \u003cli data-dp=\"id+1 ~ '. ' ~ name\"\u003e\u003c/li\u003e\n    \u003c/template\u003e\n\u003c/ul\u003e\n\n\u003ctemplate data-dp-foreach=users data-dp-var=user\u003e\n    \u003ca data-dp-href=user.url data-dp=user.name\u003e\u003c/a\u003e\n\u003c/template\u003e\n```\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24html%20%3D%20%3C%3C%3CHTML%0A%3Cul%3E%0A%20%20%20%20%3Ctemplate%20data-dp-foreach%3D%5B%27google%27%2C%27youtube%27%5D%20data-dp-var%3Dname%20data-dp-key%3Did%3E%0A%20%20%20%20%20%20%20%20%3Cli%20data-dp%3D%22id%2B1%20~%20%27.%20%27%20~%20name%22%3E%3C%2Fli%3E%0A%20%20%20%20%3C%2Ftemplate%3E%0A%3C%2Ful%3E%0A%0A%3Ctemplate%20data-dp-foreach%3Dusers%20data-dp-var%3Duser%3E%0A%20%20%20%20%3Ca%20data-dp-href%3Duser.url%20data-dp%3Duser.name%3E%3C%2Fa%3E%0A%3C%2Ftemplate%3E%0AHTML%3B%0A%0A%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28template%3A%20%24html%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%5B%27users%27%20%3D%3E%20%5B%0A%20%20%5B%27url%27%20%3D%3E%20%27%231%27%2C%20%27name%27%20%3D%3E%20%27foo%27%5D%2C%0A%20%20%5B%27url%27%20%3D%3E%20%27%232%27%2C%20%27name%27%20%3D%3E%20%27bar%27%5D%2C%0A%5D%5D%29%3B%0A%0Aprint_r%28%24result%29%3B)\n\n### `data-dp-html`\n**Value**: SMPL expression\n\nIf the expression evaluates to `null`, no action will be taken (the element will be rendered without any modifications).\n\nThe expression otherwise must evaluate to a string. The string will be inserted into the element as HTML replacing the element's content.\n\nThe inserted HTML will have only `data-dp`, `data-dp-attr` and attribute shortcuts rendered which means that other attributes like `data-dp-if` or `data-dp-foreach` will be ignored.\n\n```html\n\u003cdiv data-dp-html=\"'\u003cb\u003e' ~ name ~ '\u003c/b\u003e'\"\u003e\u003c/div\u003e\n\n\u003cdiv data-dp-html=\"'\u003cb data-dp=name\u003e\u003c/b\u003e'\"\u003e\u003c/div\u003e\n```\nNote the quotes around the expression in the second example - the outer quotes are defining content of the HTML attribute and the inner quotes are defining a string within the SMPL expression.\n\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24html%20%3D%20%3C%3C%3CHTML%0A%3Cdiv%20data-dp-html%3D%22%27%3Cb%3E%27%20~%20name%20~%20%27%3C%2Fb%3E%27%22%3E%3C%2Fdiv%3E%0A%0A%3Cdiv%20data-dp-html%3D%22%27%3Cb%20data-dp%3Dname%3E%3C%2Fb%3E%27%22%3E%3C%2Fdiv%3E%0AHTML%3B%0A%0A%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28template%3A%20%24html%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%5B%27name%27%20%3D%3E%20%27Foobar%27%5D%29%3B%0A%0Aprint_r%28%24result%29%3B)\n\n### `data-dp`\n**Value**: SMPL expression\n\nIf the expression evaluates to `null`, no action will be taken (the element will be rendered without any modifications).\n\nThe expression otherwise must evaluate to a string. The string will be inserted into the element as escaped text replacing the element's content.\n\n```html\n\u003cspan data-dp=message\u003e\u003c/span\u003e\n\n\u003cvar data-dp=\"balance \u003e 0 ? balance : 'empty balance'\"\u003e\u003c/var\u003e\n\n\u003clabel data-dp=`cool`\u003e\u003c/label\u003e\n```\nNote: HTML interprets the attribute from the last example as: \u003ccode\u003edata-dp=\"\\`cool\\`\"\u003c/code\u003e, and SMPLang will interpret \u003ccode\u003e\\`cool\\`\u003c/code\u003e as a string literal. If you wrote `data-dp=\"cool\"` instead, SMPLang would look for a var called `cool` and return its value.\n\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24html%20%3D%20%3C%3C%3CHTML%0A%3Cspan%20data-dp%3Dmessage%3E%3C%2Fspan%3E%0A%0A%3Cvar%20data-dp%3D%22balance%20%3E%200%20%3F%20balance%20%3A%20%27empty%20balance%27%22%3E%3C%2Fvar%3E%0A%0A%3Clabel%20data-dp%3D%60cool%60%3E%3C%2Flabel%3E%0AHTML%3B%0A%0A%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28template%3A%20%24html%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%5B%0A%20%20%20%20%27message%27%20%3D%3E%20%27This%20is%20a%20demo%20message.%27%2C%0A%20%20%20%20%27balance%27%20%3D%3E%200%2C%0A%5D%29%3B%0A%0Aprint_r%28%24result%29%3B)\n\n### `data-dp-attr`\n**Value**: `attribute name ; SMPL expression`\n\nIf the expression evaluates to `null`, the attribute won't be set, and it's value will be left as is (if any).\n\nThe expression otherwise must evaluate to a string. The string will be escaped and inserted as the attribute value for the desired attribute.\n\nDataplater also provides a few shortcut for the following attributes: `id` `class` `title` `alt` `value` `href` `src` `style` using the syntax: **data-dp-`attribute`**.\n\n```html\n\u003cspan data-dp-attr=\"title ; message\"\u003e\u003c/span\u003e\n\u003c!-- or --\u003e\n\u003cvar data-dp-title=message\u003e\u003c/var\u003e\n\n\u003cdiv data-dp-class=\"!hidden ? 'show'\"\u003e\u003c/div\u003e\n```\n[![try](https://img.shields.io/badge/Try%20it%20out-on%20PHPSandbox-%237E29CE)](https://play.phpsandbox.io/leongrdic/dataplater?input=%24html%20%3D%20%3C%3C%3CHTML%0A%3Cspan%20data-dp-attr%3D%22title%20%3B%20message%22%3E%3C%2Fspan%3E%0A%3C%21--%20or%20--%3E%0A%3Cvar%20data-dp-title%3Dmessage%3E%3C%2Fvar%3E%0A%0A%3Cdiv%20data-dp-class%3D%22%21hidden%20%3F%20%27show%27%22%3E%3C%2Fdiv%3E%0AHTML%3B%0A%0A%24dp%20%3D%20new%20%5CLe%5CDataplater%5CDataplater%28template%3A%20%24html%29%3B%0A%0A%24result%20%3D%20%24dp-%3Erender%28%5B%0A%20%20%20%20%27message%27%20%3D%3E%20%27This%20is%20a%20demo%20message.%27%2C%0A%20%20%20%20%27hidden%27%20%3D%3E%20false%2C%0A%5D%29%3B%0A%0Aprint_r%28%24result%29%3B)\n\n## Expression reference\n\nDataplater uses the [SMPLang](https://github.com/leongrdic/php-smplang) expression language. Refer to the SMPLang readme for more information about the syntax and supported operators.\n\nVars from Dataplater are accessible as vars in the SMPL expression.\n\nDataplater also provides a global object `php` which is basically a proxy to all php functions. Use it to access any PHP function from within your expressions:\n\n```\nphp.count(users) \u003e 0\n\nphp.array_reverse(links)\n\nphp.implode('-', php.explode(' ', someText))\n```\n\nKeep in mind you can still pass your own closure/function vars and use them in your templates.\n\nWhen the expression returns a closure, Dataplater will attempt to call it (without any params) and use the result instead of the closure.\n\nDataplater wraps all SMPL exceptions in a `\\Le\\Dataplater\\ParseException` which gives you access to the line number and the causing HTML element.\n\n## Rendering order\n\n1. Includes are inserted (single level only)\n2. `if` checks are performed (except for those in loops)\n3. Loops are performed (recursively) and their contents are fully rendered (which allows for nested loops; including `if` checks)\n4. HTML insertions are performed\n5. Text and attribute insertions are performed\n\n## Notes\n\nDataplater heavily relies on the PHP DOM extension and all escaping is done by the DOM extension natively, so passing user-generated data into Dataplater vars should be safe, although if you do use data from untrusted sources, make sure proper validations is done.\n\nAlso keep in mind that DOM extension sometimes reformats HTML (like adds attribute brackets, removes closing tags if unnecessary, etc.) and that the code coming out of Dataplater is not going to be indented well.\n\nAny contributions to this project are welcome!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleongrdic%2Fphp-dataplater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleongrdic%2Fphp-dataplater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleongrdic%2Fphp-dataplater/lists"}