This is reactive two side template library for handlebars. One template you can render on both sides:
- backend [PHP]
- frontend [JS] (optional)
Lib is wrapper of fastest handlebars implementation, based on: zordius/lightncandy
$ composer require fe3dback/kx-draw
- php >= 7.0
- composer
-
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.
-
Also you need some folder for templates.
Something like this:
- my_project_root
|- example.php // some php script
|- tmp/draw // any cache will be here
|- public/templates/*.hbs // templates folder
code from example.php
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:
code from public/templates/hello.hbs
code from example.php
$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
Result will be in $html:
<b>Hello world!</b>
In some case we want to use DrawLib from any application place:
Put this code in any shared file, executed from every other script (common.php, etc..)
/**
* 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:
$html = KXDraw()->render('hello', 1, [
'name' => 'world'
]);
Before use partials in our templates, we need to mark some templates (or entire folders as partials).
// mark /templates/common/header.hbs
KXDraw()->addPartial('/common/header');
// mark /templates/shared/*/*
KXDraw()->addPartialsDirectory('shared');
Now any marked templates can be used as partials:
code from public/templates/hello.hbs
code from public/templates/shared/name.hbs
code from example.php
$html = KXDraw()->render('hello', 1, [
'name' => 'world'
]);
Result will be in $html:
<b>Hello <i>world</i>!</b>
- All templates should have only one parent. (like in react). For example:
This is OK:
This will be broken:
In case when template have many nodes, we can wrap with some another div/span/etc..
This is OK:
- jquery >= 2.*
- handlebars.js
Handlebars can be installed with many variants:
- place JQ and handlebars.js anywhere in markup (for example before < / body> tag closing)
- AFTER place js draw implementation and exported data:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.7/handlebars.min.js"></script>
<script type="text/javascript" src="/vendor/fe3dback/kx-draw/draw.js"></script>
<!-- after export no more rendering allowed, this should be last call to KXDraw -->
<?=KXDraw()->exportToJS()?>
Go to page with templates and lib, and try in console:
KXDraw
// KXDrawRender {templates: Object, data: Object, partials: Object}
If lib included correctly, this object should contain all data, templates and partials from backend
Return all data used in backend
KXDraw.getRawData()
// Object {hello: Object}
Return all partials
KXDraw.getRawPartials()
// Object {shared/name: "<i>{{name}}</i>"}
Return all raw templates from backend files
KXDraw.getRawTemplates()
// Object {hello: "<b>Hello {{> shared/name}}!</b>"}
Update html template on page, and template data.
- 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
// old data:
{
a: 1,
b: 2
}
// new data:
{
b: 4
}
// RESULT WITH ASSIGN:
{
a: 1,
b: 4
}
// RESULT WITHOUT ASSIGN:
{
b: 4
}
Get stored data from used template
- 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"
// }
Get Jquery node object
- 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
see examples folder.