我想知道 - 解析类似内容的最有效方法是什么:

{{HEADER}}

Hello my name is {{NAME}}

{{#CONTENT}}
    This is the content ...

    {{#PERSONS}}

        <p>My name is {{NAME}}.</p>

    {{/PERSONS}}

{{/CONTENT}}

{{FOOTER}}

当然,这最终有点像一个模板系统,所以我的计划是创建一个“遍历”的散列图。模板,就像这样

$hash = array(
    'HEADER' => 'This is a header',
    'NAME' => 'David',
    'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
    'FOOTER' => 'This is the footer'
    );

值得注意的是“部分”。 (以#开头的标签),可以重复多次,我认为这就是让我失望的原因......

此外,任何部分都可以包含任意数量的其他部分和常规标记...

那么..你怎么做的?

有帮助吗?

解决方案

预期的输出是这样的:

这是一个标题

您好,我的名字是David

This is the content ...

My name is Heino.

My name is Sebastian.

这是页脚


如何管理哈希映射中嵌套数组与模板中可重复部分的关系?该模板的实际行为应该是什么?如果为非节元素提供了数组,它会做什么?如果为一个section元素提供一个单独的值,它是否会被视为只有一个元素的数组(我假设如此)?

无论如何,关于模板的解析器(无论你最终用数据映射做什么)......我要做的是为每种类型的令牌创建一个类,包括非泛型的一个类 - 说出内容。这些将继承自具有可覆盖的Parse,Render和Map方法的公共令牌基类。

绘制您的状态图并找出每个状态的入口和出口点,然后将其编码到令牌之间的调用结构中。最后,您希望生成描述模板的可枚举标记集合。

一旦你以抽象形式获得它,你可以遍历在令牌上调用Map的集合,将数据从hashmap分配给标记,然后调用Render将模板渲染到它的最终形式。

希望有所帮助。

其他提示

最有效的方法是编译模板到php代码。只需包含编译版本。

Smarty模板引擎做了类似的事情。您还可以查看smarty源并检查它们如何解析标记。

您最好使用现有解析器(如XML或JSON),因此您不必编写自己的解析器,以便其他人可以轻松地为解析器编写文档而无需专门的工具。但是,如果您想编写自己的解析器,可能需要考虑使用 Lex Yacc

我会选择第三方解析器,因为我喜欢更聪明,更努力地工作,但是如果你正在做这个练习,或者你真的想要构建自己的模板引擎(在PHP中,我假设因为标签),我将首先回顾一下设计模式,复合设计模式

复合模式在Java框架中经常用于这样的事情,包括XML解析。

我会在.php单独的文件中使用这样的东西:

<?php echo $HEADER ?>

Hello my name is <?php echo $NAME?>

<div id="CONTENT">
    This is the content ...

    <?php foreach ($PERSONS as $PERSON) : ?>

        <p>My name is <?php echo $PERSON['NAME']?>.</p>

    <?php endforeach ?>

</div>

<?php echo $FOOTER ?>

只需将上面的文件包含在填充引用变量的文件中即可。

信不信由你,PHP已经提供了模板系统声称要实现的所有功能。没有必要在PHP之上添加另一层抽象(和复杂性)。

我使用 PHP的DOM 。我的模板语言只是带有ID和类属性的HTML。但是,如果你想坚持你的计划,我会使用 preg_replace_callback ,其模式与你的语法和一个回调函数,它在哈希中找到适当的替换,在容器元素上递归调用它自己。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top