简体   繁体   English

Javascript 自定义模板引擎

[英]Javascript custom template engine

I'm trying to create a custom template engine in javascript but I'm having trouble getting started as I cannot extract tokens using regex.我正在尝试在 javascript 中创建一个自定义模板引擎,但由于无法使用正则表达式提取令牌,因此我无法开始使用。 Here are the requirements:以下是要求:

  1. Variables are defined like this: $(variable)变量定义如下: $(variable)
  2. Functions: $(name arg1 "this is arg2 but it contains whitespaces.")函数: $(name arg1 "this is arg2 but it contains whitespaces.")
  3. Function arguments can contain other variables $(name $(variable) arg2) Function arguments 可以包含其他变量$(name $(variable) arg2)

Both variables and functions will be rendered async.变量和函数都将异步呈现。 For example: Get the value for $(variable) from db then replace it.例如:从 db 中获取$(variable)的值,然后替换它。

This is not for rendering an html page but to simply replace a string entered by a user on the backend.这不是为了呈现 html 页面,而是简单地替换用户在后端输入的字符串。

Edit编辑

More information:更多信息:
Suppose a user enters the following string: $(id $(lowercase John))假设用户输入以下字符串: $(id $(lowercase John))
On the backend application must do:在后端应用程序必须做到:

  1. Convert "John" to lowercase.将“约翰”转换为小写。
  2. Get the id for "john" from db.从 db 获取“john”的 id。

This is only a simple example to demonstrate how this should work.这只是一个简单的例子来演示它应该如何工作。

Are there any libraries that can help me achieve this?有没有可以帮助我实现这一目标的库? If not, any idea how to implement this?如果没有,知道如何实现吗?

EDIT 2: I tried using Mustache and I changed the delimiters to $(), however the function (section) tags do no satisfy the requirements.编辑 2:我尝试使用Mustache并将分隔符更改为 $(),但是 function(部分)标签不满足要求。 In Mustache, for functions I must do this: $(#name) $(variable) "this is arg2 but it contains whitespaces."$(/name) also it does not support async rendering.在 Mustache 中,对于函数我必须这样做: $(#name) $(variable) "this is arg2 but it contains whitespaces."$(/name)也不支持异步渲染。

Here .在这里 This regex will identify the templates that can be replaced.此正则表达式将识别可以替换的模板。 Note that it only selects the innermost templates in nested templates.请注意,它只选择嵌套模板中最里面的模板。

/\$\((?<FirstTerm>\S+?)(?<OtherTerms>(?:\s+(?:\w+|".*?"))+)?\)/g

So just use a regex replace function with your templating logic recursively until there are no more matches.因此,只需使用正则表达式用您的模板逻辑递归替换 function ,直到没有更多匹配项。 The inner templates will be replaced and you'll be left with the string with templates replaced.内部模板将被替换,您将留下替换模板的字符串。

If not, any idea how to implement this?如果没有,知道如何实现吗?

You should use an Abstract Syntax Tree, and write a compatible parser.您应该使用抽象语法树,并编写兼容的解析器。 While regex (as Pedro Lima stated) is good for simple templating, if you ever want to extend the parser, you'll need something a bit more robust.虽然正则表达式(如 Pedro Lima 所说)适用于简单的模板,但如果您想扩展解析器,您将需要一些更健壮的东西。

As an example of an Abstract Syntax Tree parser, $(test1 $(test2) test3) lorem ipsum $(test4) would be turned into the following:作为抽象语法树解析器的示例, $(test1 $(test2) test3) lorem ipsum $(test4)将变成以下内容:

前面语句的抽象语法树表示。分支:“模板”,带有子“test1”,“模板”,带有子“test2”和“test3”; “ lorem ipsum ”;和“模板”,带有子“test4”。 (Thanks to Mile Shang's Syntree for the tree generator.) (感谢 Mile Shang 的Syntree的树生成器。)

As for specifically how to write a parser, I think you can figure it out.至于具体怎么写解析器,我想你可以自己弄清楚。 Just iterate over the string and check for the template delimiter.只需遍历字符串并检查模板分隔符。 Reading the source code for a templating library like Handlebars might help.阅读像 Handlebars 这样的模板库的源代码可能会有所帮助。

Other answers on this post are correct, however, I want to share exactly how I managed to implement this:这篇文章的其他答案是正确的,但是,我想确切地分享我是如何实现这一点的:

  1. Create a recursive match function.创建递归匹配 function。 I usedSteven Leviathan's article to implement this.我使用Steven Leviathan 的文章来实现这一点。

  2. Create a render function and inside the function call the recursive match function to find and replace variable/function names with appropriate values.创建一个渲染 function 并在 function 内部调用递归匹配 function 以查找变量/函数名称并将其替换为适当的值。

  3. Keep calling the render function recursively until all arguments inside a function have been replaced.继续递归调用渲染 function 直到 function 内的所有 arguments 都被替换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM