, (*1)
Handlebars Render (PHP/JS)
This is reactive two side template library for handlebars.
One template you can render on both sides:, (*2)
- backend [PHP]
- frontend [JS] (optional)
Lib is wrapper of fastest handlebars implementation, based on:
zordius/lightncandy, (*3)
, (*4)
Install
$ composer require fe3dback/kx-draw
Requirements [PHP side]:
Use
Prepare directories
-
First of all you need to make tmp folder inside your project, kxdraw will
be store all cache data to optimize render speed. Check RWO access to this directory., (*5)
-
Also you need some folder for templates., (*6)
Something like this:, (*7)
- my_project_root
|- example.php // some php script
|- tmp/draw // any cache will be here
|- public/templates/*.hbs // templates folder
Require lib
code from example.php, (*8)
use KX\Template\Builders\EngineFactory;
use KX\Template\Draw;
require_once 'vendor/autoload.php';
$draw = new Draw
(
(new EngineFactory())
->setExt('hbs') // templates file extension (*.hbs)
->setCacheDirReal($cacheDir) // cache directory (we can safely delete dir, and cache will be rebuild)
->setTemplatesDirReal($templatesDir) // where our templates live
->setUseCache(true) // recommend to turn ON this feature (compile only first time)
->setUseMemCache(true) // recommend to turn ON this feature (helpful for loops)
->build()
);
Ok, we got $draw class, so we can render some template:, (*9)
code from public/templates/hello.hbs, (*10)
<b>Hello {{name}}!</b>
code from example.php, (*11)
$html = $draw->render('hello', 1, [
'name' => 'world'
]);
What we use:
- 'hello' - this is template file name (without extension)
- 1 - unique render id. Good idea to use EntityID (productId, userId, articleId, etc..) for that.
- ['name'=>'world'] - data used in template, (*12)
Result will be in $html:, (*13)
<b>Hello world!</b>
Global scope use
In some case we want to use DrawLib from any application place:, (*14)
Put this code in any shared file, executed from every other script (common.php, etc..), (*15)
/**
* Get draw object
* global scope wrapper
*
* @return Draw
*/
function KXDraw(): Draw
{
global $__kxDrawEntity;
if (is_null($__kxDrawEntity))
{
$cacheDir = '/'; // todo replace to your dir
$templatesDir = '/'; // todo replace to your dir
// make draw object, we can use only this class directly
$__kxDrawEntity = new Draw
(
(new EngineFactory())
->setExt('hbs') // templates file extension (*.hbs)
->setCacheDirReal($cacheDir) // cache directory (we can safely delete dir, and cache will be rebuild)
->setTemplatesDirReal($templatesDir) // where our templates stored
->setUseCache(true) // recommend to turn ON this feature (compile only first time)
->setUseMemCache(true) // recommend to turn ON this feature (helpful for loops)
->build()
);
}
return $__kxDrawEntity;
}
Use:, (*16)
$html = KXDraw()->render('hello', 1, [
'name' => 'world'
]);
Partials
Before use partials in our templates, we need to mark some templates (or entire folders as partials)., (*17)
// mark /templates/common/header.hbs
KXDraw()->addPartial('/common/header');
// mark /templates/shared/*/*
KXDraw()->addPartialsDirectory('shared');
Now any marked templates can be used as partials:, (*18)
code from public/templates/hello.hbs, (*19)
<b>Hello {{> shared/name}}!</b>
code from public/templates/shared/name.hbs, (*20)
<i>{{name}}</i>
code from example.php, (*21)
$html = KXDraw()->render('hello', 1, [
'name' => 'world'
]);
Result will be in $html:, (*22)
<b>Hello <i>world</i>!</b>
Templates and Reactivity
- All templates should have only one parent. (like in react). For example:
This is OK:, (*23)
<div>..some_content..</div>
This will be broken:, (*24)
<div>..some_content1..</div>
<div>..some_content2..</div>
In case when template have many nodes, we can wrap with some another div/span/etc.., (*25)
This is OK:, (*26)
<div>
<div>..some_content1..</div>
<div>..some_content2..</div>
</div>
Export to JS
Requirements [JS side]:
Handlebars can be installed with many variants:
- list handlebars.min-latest.js
- http://handlebarsjs.com/installation.html, (*27)
Include
- place JQ and handlebars.js anywhere in markup (for example before < / body> tag closing)
-
AFTER place js draw implementation and exported data:
=KXDraw()->exportToJS()?>
JS Usage
Go to page with templates and lib, and try in console:, (*28)
KXDraw
// KXDrawRender {templates: Object, data: Object, partials: Object}
If lib included correctly,
this object should contain all data, templates and partials
from backend, (*29)
Methods:
KXDraw.getRawData()
Return all data used in backend, (*30)
KXDraw.getRawData()
// Object {hello: Object}
KXDraw.getRawPartials()
Return all partials, (*31)
KXDraw.getRawPartials()
// Object {shared/name: "<i>{{name}}</i>"}
KXDraw.getRawTemplates()
Return all raw templates from backend files, (*32)
KXDraw.getRawTemplates()
// Object {hello: "<b>Hello {{> shared/name}}!</b>"}
KXDraw.update(templateName, uniqueId, data = {}, assign = true)
Update html template on page, and template data., (*33)
- string templateName - path to templateFile
(relative without extension)
- string uniqueId - id from backend
- object data - object with fields
- bool assign DEF: TRUE - if true, update will combine old
data with new data
KXDraw.update('hello', 1, {name:"KXRender"});
// true
Assign example, (*34)
// old data:
{
a: 1,
b: 2
}
// new data:
{
b: 4
}
// RESULT WITH ASSIGN:
{
a: 1,
b: 4
}
// RESULT WITHOUT ASSIGN:
{
b: 4
}
KXDraw.getDataByUniqId(templateName, uniqueId)
Get stored data from used template, (*35)
- string templateName - path to templateFile
(relative without extension)
- string uniqueId - id from backend
KXDraw.getDataByUniqId('hello', 1);
// Object {
// name: "world",
// _kx_draw_template_name: "hello",
// _kx_draw_unique_id: "1"
// }
KXDraw.getNodeByUniqId(templateName, uniqueId)
Get Jquery node object, (*36)
- string templateName - path to templateFile
(relative without extension)
- string uniqueId - id from backend
KXDraw.getNodeByUniqId('hello', 1);
// [b, prevObject: r.fn.init(1)]
// > 0: b
// > length: 1
Examples
see examples folder., (*37)