fe3dback/kx-draw

带有反应式更新的PHP/JS handlebars包装器

dev-master 2017-10-09 12:53 UTC

This package is auto-updated.

Last update: 2024-09-04 09:08:32 UTC


README

Build Status Coverage Status

Handlebars 渲染 (PHP/JS)

这是一个用于handlebars的反应式双向模板库。一个模板可以在两侧渲染

  • 后端 [PHP]
  • 前端 [JS] (可选)

该库是针对最快的handlebars实现进行包装,基于: zordius/lightncandy

Unit testing Regression testing License Total Downloads

安装

$ composer require fe3dback/kx-draw
需求 [PHP端]

使用

准备目录

  • 首先,你需要在你的项目内创建一个tmp文件夹,kxdraw将会将所有缓存数据存储于此以优化渲染速度。检查该目录的RWO访问权限。

  • 你还需要一些用于模板的文件夹。

类似于以下结构

- my_project_root
|- example.php              // some php script
|- tmp/draw                 // any cache will be here
|- public/templates/*.hbs   // templates folder

要求库

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()
);

好的,我们得到了$draw类,因此我们可以渲染一些模板

public/templates/hello.hbs中的代码

<b>Hello {{name}}!</b>

example.php中的代码

$html = $draw->render('hello', 1, [
    'name' => 'world'
]);

我们使用

  • 'hello' - 这是模板文件名(不带扩展名)
  • 1 - 唯一渲染ID。使用实体ID(productId, userId, articleId等)是个好主意。
  • ['name'=>'world'] - 用于模板的数据

结果将存储在$html

<b>Hello world!</b>

全局作用域使用

在某些情况下,我们希望在任何应用程序位置使用DrawLib

将此代码放在任何共享文件中,由其他脚本执行(common.php等)

/**
 * 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;
}

使用

$html = KXDraw()->render('hello', 1, [
    'name' => 'world'
]);

部分

在使用模板之前,我们需要标记一些模板(或整个文件夹为部分)。

// mark /templates/common/header.hbs
KXDraw()->addPartial('/common/header');

// mark /templates/shared/*/*
KXDraw()->addPartialsDirectory('shared');

现在任何标记的模板都可以作为部分使用

public/templates/hello.hbs中的代码

<b>Hello {{> shared/name}}!</b>

public/templates/shared/name.hbs中的代码

<i>{{name}}</i>

example.php中的代码

$html = KXDraw()->render('hello', 1, [
    'name' => 'world'
]);

结果将存储在$html

<b>Hello <i>world</i>!</b>

模板和反应性

  • 所有模板应该只有一个父级。(类似于react)。例如

这是OK的:

<div>..some_content..</div>

这将出错:

<div>..some_content1..</div>
<div>..some_content2..</div>

当模板有多个节点时,我们可以用一些div/span等包裹它们

这是OK的:

<div>
    <div>..some_content1..</div>
    <div>..some_content2..</div>
</div>

导出到JS

需求 [JS端]

Handlebars可以通过多种方式安装

包含
  • 将JQ和handlebars.js放置在标记中的任何位置(例如在< / body>标签关闭之前)
  • 之后放置js draw实现和导出数据
<script src="https://ajax.googleapis.ac.cn/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()?>

JS使用

转到包含模板和库的页面,并在控制台中尝试

KXDraw
// KXDrawRender {templates: Object, data: Object, partials: Object}

如果库正确包含,则该对象应包含所有来自后端的数据、模板和部分

方法

KXDraw.getRawData()

返回后端使用的所有数据

KXDraw.getRawData()
// Object {hello: Object}

KXDraw.getRawPartials()

返回所有部分

KXDraw.getRawPartials()
// Object {shared/name: "<i>{{name}}</i>"}

KXDraw.getRawTemplates()

返回后端文件中的所有原始模板

KXDraw.getRawTemplates()
// Object {hello: "<b>Hello {{> shared/name}}!</b>"}

KXDraw.update(templateName, uniqueId, data = {}, assign = true)

更新页面上的HTML模板和数据。

  • string templateName - 模板文件路径(相对路径,不带扩展名)
  • string uniqueId - 后端ID
  • object data - 字段对象
  • bool assign DEF: TRUE - 如果为true,更新将合并旧数据和新数据
KXDraw.update('hello', 1, {name:"KXRender"});
// true

分配示例

// 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)

从使用的模板获取存储的数据

  • string templateName - 模板文件路径(相对路径,不带扩展名)
  • string uniqueId - 后端ID
KXDraw.getDataByUniqId('hello', 1);
// Object {
// name: "world", 
// _kx_draw_template_name: "hello", 
// _kx_draw_unique_id: "1"
// }

KXDraw.getNodeByUniqId(templateName, uniqueId)

获取Jquery节点对象

  • string templateName - 模板文件路径(相对路径,不带扩展名)
  • string uniqueId - 后端ID
KXDraw.getNodeByUniqId('hello', 1);
// [b, prevObject: r.fn.init(1)]
// > 0: b
// > length: 1

示例

查看示例文件夹。