问题描述
我有时需要生成文本文件。到目前为止的案例是纯文本/文本电子邮件和配置文件。在前一种情况下,您必须精确,您不能逃避,“您知道,这些是生成的,即使这里和那里有额外的空间,它们仍然可读。”在后者中你可以,但有一个可读的结果是很好的。
现在,我如何使结果精确(就空格而言),并且模板也可读?比以下内容更具可读性。
使用 jinja
我可以做到这一点:
{%- if order.name -%}
Name: {{ order.name + '\n' -}}
{%- endif -%}
Phone: {{ order.phone + '\n' -}}
{%- if order.branch or order.address -%}
{{- '\n' -}}
{%- if order.branch -%}
Branch: {{ order.branch + '\n' -}}
{%- endif -%}
{%- if order.address -%}
Address: {{ order.address + '\n' -}}
{%- endif -%}
{%- endif -%}
{%- for pvxo in order.productvariantxorders.all() -%}
{{- '\n' -}}
Product: {{ (pvxo.productvariant.product.name
if pvxo.productvariant
else pvxo.product.name) + '\n' -}}
{%- endfor -%}
可能产生的结果:
Name: ...
Phone: ...
Address: ...
Product: ...
Product: ...
但是我花了一段时间才弄清楚如何让 jinja
以这种方式表现。
使用 Javascript (_.template
):
const _ = require('lodash');
const tpl =
'<% if (order.name) { %>'
+ 'Name: <%= order.name %>\n'
+ '<% } %>'
+ 'Phone: <%= order.phone %>\n'
+ '<% if (order.branch || order.address) { %>'
+ '\n'
+ '<% if (order.branch) { %>'
+ 'Branch: <%= order.branch %>\n'
+ '<% } %>'
+ '<% if (order.address) { %>'
+ 'Address: <%= order.address %>\n'
+ '<% } %>'
+ '<% } %>'
+ '<% order.productvariantxorders.forEach(pvxo => { %>'
+ '\n'
+ 'Product: <%= pvxo.productvariant'
+ ' ? pvxo.productvariant.product.name'
+ ' : pvxo.product.name %>\n'
+ '<% }) %>';
console.log(_.template(tpl)({
order: {
name: '...',phone: '...',address: '...',productvariantxorders: [
{productvariant: {product: {name: '...'}}},{product: {name: '...'}},],}
}));
哪个更直接。
并且这两个不包括您需要缩进的情况。这些仍然是我能想出的最佳解决方案。似乎没有很多选择。这个问题与语言无关。您可以指向提供更好结果的某些特定模板引擎。或者只是提出这种语法的想法。
顺便说一句,这是我检查过的somewhat related question。
解决方法
注意。我希望我找到了更好的东西,但我失败了。
现在我选择了 Javascript 解决方案,因为它更容易理解(更直接)。模板示例:
module.exports =
'server {\n'
+ ' server_name'
+ '<% domains.forEach(d => { %>'
+ ' <%= d %>'
+ '<% }) %>'
+ ';\n'
+ ' location / {\n'
+ ' return 301 https://<%= domains[0] %>$request_uri;\n'
+ ' }\n'
+ ' location /.well-known {\n'
+ ' root <%= ssl_docroot %>;\n'
+ ' }\n'
+ '}\n'
+ '\n'
+ 'server {\n'
+ ' server_name'
+ '<% domains.forEach(d => { %>'
+ ' <%= d %>'
+ '<% }) %>'
+ ';\n'
+ ' listen 443 ssl;\n'
+ '<% const d = (simp_le ? "/etc/certs/" : "/etc/letsencrypt/live/") + domains[0] %>'
+ ' ssl_certificate <%= d %>/fullchain.pem;\n'
+ '<% const f = simp_le ? "key.pem" : "privkey.pem" %>'
+ ' ssl_certificate_key <%= d %>/<%= f %>;\n'
+ '\n'
+ ' access_log /var/log/nginx/<%= domains[0] %>-access.log;\n'
+ ' error_log /var/log/nginx/<%= domains[0] %>-error.log;\n'
+ '\n'
+ ' client_max_body_size 50m;\n'
+ '\n'
+ ' # https://raw.githubusercontent.com/h5bp/server-configs-nginx/3.3.0/h5bp/web_performance/compression.conf\n'
+ ' gzip on;\n'
+ ' gzip_comp_level 5;\n'
+ ' gzip_min_length 256;\n'
+ ' gzip_proxied any;\n'
+ ' gzip_vary on;\n'
+ ' gzip_types\n'
+ ' application/atom+xml\n'
+ ' application/geo+json\n'
+ ' application/javascript\n'
+ ' application/x-javascript\n'
+ ' application/json\n'
+ ' application/ld+json\n'
+ ' application/manifest+json\n'
+ ' application/rdf+xml\n'
+ ' application/rss+xml\n'
+ ' application/vnd.ms-fontobject\n'
+ ' application/wasm\n'
+ ' application/x-web-app-manifest+json\n'
+ ' application/xhtml+xml\n'
+ ' application/xml\n'
+ ' font/eot\n'
+ ' font/otf\n'
+ ' font/ttf\n'
+ ' image/bmp\n'
+ ' image/svg+xml\n'
+ ' text/cache-manifest\n'
+ ' text/calendar\n'
+ ' text/css\n'
+ ' text/javascript\n'
+ ' text/markdown\n'
+ ' text/plain\n'
+ ' text/xml\n'
+ ' text/vcard\n'
+ ' text/vnd.rim.location.xloc\n'
+ ' text/vtt\n'
+ ' text/x-component\n'
+ ' text/x-cross-domain-policy;\n'
+ '\n'
+ ' charset utf-8;\n'
+ '\n'
+ ' location / {\n'
+ ' proxy_pass http://<%= lxc_ip %>;\n'
+ ' proxy_set_header Host $http_host;\n'
+ ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n'
+ ' proxy_set_header X-Forwarded-Proto https;\n'
+ ' }\n'
+ '<% if (websockets) { %>'
+ '\n'
+ ' location /ws {\n'
+ ' proxy_pass http://<%= lxc_ip %>;\n'
+ ' proxy_set_header Host $http_host;\n'
+ ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n'
+ ' proxy_set_header X-Forwarded-Proto https;\n'
+ '\n'
+ ' proxy_http_version 1.1;\n'
+ ' proxy_set_header Upgrade $http_upgrade;\n'
+ ' proxy_set_header Connection Upgrade;\n'
+ ' }\n'
+ '<% } %>'
+ '\n'
+ ' location /.well-known {\n'
+ ' root <%= ssl_docroot %>;\n'
+ ' }\n'
+ '}\n';
它可以在 sh
脚本中使用,如下所示:
cat <<CODE | node - "$tpl" "$vars"
const _ = require('lodash');
const tpl = require('./files/' + process.argv[2] + '.tpl');
const vars = JSON.parse(process.argv[3]);
console.log(_.template(tpl)(vars));
CODE