Por un lado, el tema era de hecho cuadrado. Por otro lado, era redondo. Pero en el tercer lado, con el que debería estar el triángulo, el objeto salió curvado y oblicuo.
- ¿Alyoshenka va a la sala de reuniones? - Lenochkina atrapado en la puerta con cara de interesado.
- Alyoshenka no asistirá a la reunión. Aleshenka escribe un artículo.
- ¿Sobre los cubos?
- ¿Qué otros cubos? - Bajé los ojos, en mis manos y la verdad era un cubo desafortunado. Eso es una pelota. Eso es un rombo.
- No se trata de cubos! Y no sobre pelotas. Sobre plantillas.
"¡Les diré eso!" Patrón, ah. - Helen ya estaba corriendo por el pasillo.
"Sobre plantillas. Incluso sobre tres plantillas diferentes". Más precisamente, hay tres razones para usar plantillas en el código del servidor. Y ninguna de estas razones será sobre HTML.
En los ejemplos, utilicé la sintaxis de Moustache , debido a la sintaxis lacónica y la presencia de implementaciones para todo lo que se mueve. Moustache prácticamente no se permite ninguna libertad, a diferencia de, por ejemplo, .Net Razor, que le permite codificar dentro de la plantilla, lo que constituye un mal ejemplo para los desarrolladores débiles.
Los ejemplos de código estarán en python. La implementación de Moustache para Python se llama pystache .
Entonces, tres razones para dejar entrar patrones tu vida tu código
Artefactos de texto
Si tiene un sistema dentro del cual existen algunos datos, por ejemplo, datos en una base de datos relacional o datos obtenidos a través de llamadas API, a veces necesita crear artefactos basados en estos datos.
El artefacto puede ser, por ejemplo, JSON o archivo de texto sin formato, archivo adjunto, respuesta HTTP. Lo principal: un artefacto es esencialmente el resultado de aplicar una función de una parte relativamente compacta de los datos en su sistema. Y el artefacto tiene su propia sintaxis.
El artefacto puede ser un extracto bancario en formato de texto para cargarlo en el sistema heredado. El artefacto puede ser la descarga de un cheque electrónico en forma de un archivo .json, que se enviará como un archivo adjunto al cliente por correo.
En todos estos casos, simplificará enormemente su vida utilizando plantillas de artefactos.
¿Qué es un motor de plantillas? Esta es una biblioteca que tomará un modelo de objetos (contexto), tomará una plantilla, se aplicará uno al otro y dará el resultado. El modelo de objetos y la plantilla son preparados por el programador. El resultado final lo prepara el motor de plantillas.
Ejemplo: intente crear un mensaje de texto sobre el pedido.
Primero, prepare el modelo de objeto:
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
El código es puramente falso. En el código real, puede haber una consulta en la base de datos, algún tipo de lógica para calcular valores (por ejemplo, calculamos el valor de total.amount en función de los artículos del pedido).
Presta atención a algunas cosas:
- Este NO es un modelo de objeto del pedido, es algo más simple, preparado para su uso en la plantilla. Los valores "sumRub" y "total.amount" en el modelo de negocio real no deben ser textuales, el valor de "coma" de la matriz de líneas en el modelo de objetos no pertenece, solo es necesario simplificar la representación (pystache no puede entender que el elemento de la lista sea el último y después no hay necesidad de poner una coma.
- El tipo de campo "cantidad" es el texto y este texto está formateado para salida en la plantilla. Si su motor de plantillas admite formateadores (algo así como "... {someValue | asMoney}"), no es necesario formatear directamente en el modelo.
- El texto en la plantilla debería verse ligeramente diferente para los clientes de Uryupinsk (el gerente corrió en el último momento y pidió agregar: el negocio realmente preguntó, de repente comenzaron una campaña de marketing para la ciudad). Por lo tanto, agregamos el valor booleano "posInUrupinsk" al modelo y lo usamos en la plantilla.
- Es mejor no usar el modelo nuevamente desde la plantilla, excepto para representar otras plantillas
El texto de la plantilla de bigote se ve así:
{{#posInUrupinsk}} ! 100 . {{/posInUrupinsk}} {{^posInUrupinsk}} : {{/posInUrupinsk}} {{#lines}} #{{no}} ... {{itemtext}}: {{sumRub}} {{#comma}};{{/comma}}{{^comma}}.{{/comma}} {{/lines}} : {{total.amount}} --------------------------- N : {{documentId}} {{checkDate}}
Vemos en la plantilla que el encabezado del documento para pedidos en Uryupinsk es diferente de otras ciudades. También vemos que al final de la última línea con la posición de los productos básicos hay un punto, y en todas las primeras posiciones hay un punto y coma. El atributo "coma" y el método "add_comma" en el generador de modelos son responsables de esto.
El código que aplica el contexto a la plantilla es trivial:
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)
Resultado:
! 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
Otro consejo: si la tarea lo permite, guarde el modelo con la plantilla renderizada (por ejemplo, en formato JSON). Esto ayudará con la depuración y la resolución de problemas.
La impresora chirrió tres veces, emitiendo un nuevo modelo. El lado triangular ahora era un triángulo perfecto. Los otros dos lados eran cuadrados. La red neuronal vivió su propia vida y se negó a dar un modelo modelo primitivo en todos los aspectos.
"Le daré un cubo a Helen". Pensé Deja que se regocije.
Generación de código
Es posible que deba crear JavaScript en tiempo de ejecución desde el back-end. Por qué Para crear informes del lado del navegador, por ejemplo. O obtenga un script en F # desde un programa Go. O el código de Kotlin desde ReactJS (no puedo imaginar por qué esto podría ser necesario, pero de repente tienes inclinaciones tan específicas).
En el caso de la generación de código, es mejor escribir primero con sus manos el código resultante (lo que queremos generar) y solo luego dividirlo en una plantilla y modelo. Este enfoque nos salvará de anhelo excesiva complejidad del modelo. Nunca es demasiado tarde para complicar un modelo, pero es mejor comenzar con uno simple.
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"));
Aquí vemos que tenemos de uno a N gráficos de gráficos de líneas en la página, cada uno de los cuales tiene su propia fuente de datos, título y lista de indicadores. 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"}, ] } ] }
Bueno, la plantilla:
{{#charts}} var report = CreateChart({ title: "{{title}}" }, type: "lineChart", sourceUrl: "{{sourceUrl}}" ); {{#series}} report.addLine({ dataIndex:{{dataIndex}}, title: "{{title}}", color: "{{color}}" }); {{/series}} report.render($("{{divId}}")); {{/charts}}
Tenga en cuenta que este enfoque "frontal" de la estandarización requiere un esfuerzo por separado para evaluar los valores en el modelo. si una coma o comilla "Hello Kitty \" "aparece en la serie [0] .title, la sintaxis del archivo resultante se desmorona. Por lo tanto, escriba las funciones de detección y úselas al crear modelos. Utilice formateadores si el motor de plantillas puede hacerlo.
El tercer dado voló a través de la puerta y rebotó con un golpe. Tampoco es bueno. Interesante pero ¿puedes rodar el cubo para que se deslice debajo de la puerta y llegue al final del pasillo? ¿Es posible imprimir caucho en 3D? ¿O es mejor llenarlo con icosaedros tan pequeños llenos de aire? ...
Consultas SQL
El lector exigente dirá que esto también es generación de código, traducción de conceptos de un lenguaje de programación a otro. A lo que responderemos al lector exigente que trabajar con SQL o con cualquier otro lenguaje de consulta de base de datos es un área de programación ligeramente separada y no es obvio para todos que si las plantillas pueden generar scripts js, entonces SQL también es posible. Por lo tanto, emitiremos solicitudes en un caso separado.
Y para que el lector exigente no se aburra, dejaremos en el artículo solo ejemplos de algunas consultas. Usted mismo puede averiguar qué modelo y qué plantilla se adaptan mejor aquí. En los ejemplos en el github puedes ver lo que hice.
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;
Se pueden encontrar plantillas (incluso para SQL) y ejemplos de código en el github .