在后端使用模板引擎的三个明显例子

一方面,主题确实是方形的。 另一方面,它是圆形的。 但是,在三角形应该与之相交的第三面,物体弯曲并倾斜。


-Alyoshenka会去会议室吗? -Lenochkina感兴趣地卡在门上。
-Alyoshenka没有参加会议。 Aleshenka写了一篇文章。
-关于立方体?
-还有什么立方体? -我低下了眼睛,手中,真相是一个不幸的立方体。 那是一个球。 那是菱形。
-不是关于立方体! 与球无关。 关于模板。
“我告诉他们!” 图案啊。 -海伦已经在走廊上跑了。


“关于模板。甚至大约三个不同的模板。” 更准确地说,是在服务器代码中使用模板的三个原因。 这些原因都不会与HTML有关。


在示例中,由于简单的语法以及所有移动内容的实现,因此我使用了Mustache语法。 与.Net Razor不同,Mustache实际上不允许任何自由,例如,.Net Razor允许您在模板内进行代码编写,从而为软弱的开发人员树立了榜样。


代码示例将在python中。 Mustache for Python的实现称为pystache


因此,让模式进入的三个原因 你的生活 您的代码。


文本工件


如果您的系统内部存在某些数据,例如关系数据库中的数据或通过API调用获得的数据,则有时您需要基于此数据创建构件。


工件可以是例如JSON或纯文本文件,附件,HTTP响应。 最主要的是-工件本质上是从系统中相对紧凑的数据部分中应用功能的结果。 而且工件具有自己的语法。


人工产物可以是文本格式的银行对帐单,以上载到遗留系统。 该工件可能是.json文件形式的电子支票的卸载,该附件将通过邮件作为附件发送给客户端。


在所有这些情况下,您将通过使用工件模板极大地简化您的生活。


什么是模板引擎? 这是一个将采用对象模型(上下文),采用模板,将一个模板应用于另一个对象并给出结果的库。 对象模型和模板由程序员准备。 最终结果由模板引擎准备。


示例:尝试创建有关订单的短信。


首先,准备对象模型:


def add_comma(list): for a in list[:-1]: a["comma"] = True def get_model(): res = { "documentId": 3323223, "checkDate": "01.02.2019 22:20", "posId": 34399, "posAddr": "Urupinsk, 1 Maya 1", "lines": [ { "no": 1, "itemtext": "Hello Kitty", "amount": 3, "sumRub": "55.20" }, { "no": 2, "itemtext": "Paper pokemons", "amount": 1, "sumRub": "1230.00" }, { "no": 2, "itemtext": "Book of Mustache", "amount": 1, "sumRub": "1000.00" } ], "total": { "amount": "3285.20" } } add_comma(res["lines"]) res["posInUrupinsk"] = res["posId"] > 34000 return res 

该代码是纯虚拟的。 在实际代码中,可能会有一个数据库查询,这是一种用于计算值的逻辑(例如,我们根据订单项计算total.amount的值)。


注意以下几点:


  • 这不是订单的对象模型,而是为在模板中使用而准备的更简单的东西。 实际业务模型中的值“ sumRub”和“ total.amount”不应为文本形式,对象模型中的lines数组的“逗号”值不属于该值,仅需要简化呈现(pystache无法理解列表项是最后一个)之后,无需加逗号。
  • 字段类型“数量”是文本,该文本的格式设置为在模板中输出。 如果您的模板引擎支持格式程序(例如“ ... {someValue | asMoney}”之类的格式程序),则无需在模型中直接进行格式设置。
  • 对于Uryupinsk的客户,模板中的文本应该看起来有些不同(经理在最后一刻跑过去并要求添加-业务人员确实要求,他们突然为该市发起了营销活动)。 因此,我们向模型添加了布尔值“ posInUrupinsk”,并在模板中使用了它。
  • 最好不要从模板中再次使用模型,除了渲染其他模板

小胡子模板的文本如下所示:


 {{#posInUrupinsk}}    !        100   . {{/posInUrupinsk}} {{^posInUrupinsk}}    : {{/posInUrupinsk}} {{#lines}} #{{no}} ... {{itemtext}}: {{sumRub}} {{#comma}};{{/comma}}{{^comma}}.{{/comma}} {{/lines}} : {{total.amount}} --------------------------- N : {{documentId}}  {{checkDate}} 

我们在模板中看到,乌里平斯克订单的文件抬头不同于其他城市。 我们还看到在商品位置的最后一行的末尾有一个点,在所有早期位置有一个分号。 模型生成器中的“逗号”属性和“ add_comma”方法对此负责。


将上下文应用于模板的代码很简单:


 model = get_model() with open(os.path.join("templates", "check.txt.mustache"), 'r') as f: template = f.read() check_text = pystache.render(template, model) print(check_text) 

结果:


    !        100   . #1 ... Hello Kitty: 55.20 ; #2 ... Paper pokemons: 1230.00 ; #2 ... Book of Mustache: 1000.00 . : 3285.20 --------------------------- N : 3323223  01.02.2019 22:20 

另一个提示:如果任务允许,请使用呈现的模板(例如,以JSON格式)保存模型本身。 这将有助于调试和故障排除。




打印机发出三声吱吱声,发出新型号。 三角形的一面现在是一个完美的三角形。 另外两个侧面是正方形。 神经网络过着自己的生活,并拒绝在所有方面提供模型原语。


“我给海伦一个立方体。” 我以为 让它高兴。


代码生成


您可能需要在运行时从后端内部创建JavaScript。 怎么了 例如,用于创建浏览器端报告。 或者从Go程序中获取F#中的脚本。 还是ReactJS中的Kotlin代码(我无法想象为什么这样做是有必要的,但是突然之间您有这样的倾向)。


在代码生成的情况下,最好先用手编写结果代码(我们要生成的代码),然后再将其分解为模板和模型。 这种方法将使我们免于 向往 模型过于复杂。 使模型复杂化永远不会太迟,但是最好从一个简单的模型开始。


 var report = CreateChart({ title: "   - " }, type: "lineChart", sourceUrl: "/reports/data/0" ); report.addLine({ dataIndex:0, title: "", color: "green" }); report.addLine({ dataIndex:1, title: "", color: "red" }); report.render($("#reportPlaceholder1")); var report = CreateChart({ title: "   -  " }, type: "lineChart", sourceUrl: "/reports/data/1"); report.addLine({ dataIndex:0, title: "Hello Kitty", color: "#000" }); report.addLine({ dataIndex:1, title: "PokemonGo", color: "#222" }); report.addLine({ dataIndex:2, title: "Mustache", color: "#333" }); report.render($("#reportPlaceholder2")); 

在这里,我们看到页面上有一个从N到N的线图图表,每个图表都有自己的数据源,标题和指标列表。 Modelka:


 def get_model(): return { "charts": [ { "divId": "#reportPlaceholder1", "title": "   - ", "sourceUrl": "/reports/data/0", "series": [ {"dataIndex": 0, "title": "", "color": "green"}, {"dataIndex": 1, "title": "", "color": "red"}, ] }, { "divId": "#reportPlaceholder2", "title": "   -  ", "sourceUrl": "/reports/data/1", "series": [ {"dataIndex": 0, "title": "Hello Kitty", "color": "#000"}, {"dataIndex": 1, "title": "PokemonGo", "color": "#111"}, {"dataIndex": 2, "title": "Mustache", "color": "#222"}, ] } ] } 

好了,模板:


 {{#charts}} var report = CreateChart({ title: "{{title}}" }, type: "lineChart", sourceUrl: "{{sourceUrl}}" ); {{#series}} report.addLine({ dataIndex:{{dataIndex}}, title: "{{title}}", color: "{{color}}" }); {{/series}} report.render($("{{divId}}")); {{/charts}} 

请注意:这种“直接”标准化方法需要单独的工作来筛选模型中的值。 如果在系列[0] .title中,我们得到一个逗号或引号-“ Hello Kitty \”“-生成的文件的语法将崩溃。因此,编写筛选函数并在创建模型时使用它们。如果模板引擎知道如何使用格式化程序。




第三个骰子飞过门,敲门弹跳。 也不好 有趣 但是可以滚动立方体,使其滑到门下并到达走廊的尽头吗? 可以3D打印橡胶吗? 还是用充满空气的小二十面体填充它更好?


SQL查询


挑剔的读者会说这也是代码生成,即将概念从一种编程语言转换为另一种编程语言。 我们将向挑剔的读者回答,使用SQL或使用任何其他数据库查询语言是一个稍微独立的编程领域,并且对于每个人来说都不是显而易见的,如果js脚本可以由模板生成,那么SQL也可以。 因此,我们将在另一种情况下发出请求。


为了使挑剔的读者不会感到厌烦,我们将在本文中仅保留一些查询的示例。 您自己可以在此处找出更适合的模型和模板。 在github上的示例中,您可以看到我做了什么。


 SELECT * FROM hosts WHERE firmware_id=1 AND bmc_login='admin' ORDER BY ip DESC; SELECT * FROM hosts ORDER BY name LIMIT 3; SELECT host_type_id, COUNT(*) FROM hosts GROUP BY host_type_id; 

模板(包括用于SQL的模板)和代码示例可以在github上找到。

Source: https://habr.com/ru/post/zh-CN454418/


All Articles