how to split a string based on delimiter in go html template - html

I am using go html templates for alerting through bosun using prometheus queries .
Below is the use case in my promql result I get instance name as instancename:9100 (example - xyz.com:9100) while setting up alerts I just need xyz.com , below is the snippet that I used using split function but that is not working . can someone please help here
result from promql would be like below
{dc="IN",env="production",instance="xyz.com:9100",job="node-exporter",service="test"}
code snippet used using go html templates
<table style="border-spacing:0; border-collapse:collapse;">
<tr>
<td><b>Host</b></td>
<td><b>Used Memory (%)</b></td>
{{ range $v := .LeftJoin .Alert.Vars.result .Alert.Vars.result}}
{{ $res := index $v 0 }}
<td>{{(split ":" $res.Group.instance)._0 }}</td>
<td>{{$res.Group.value}}</td>
{{
<td>

Related

Query input data from HTML to flask mysql

I am both new to flask and posting here.
I am trying to query a MySQL database with a variable input from HTML to Flask.
If I fix the query from the python code, it works. However, trying to query my database using the input variable doesn't give any result.
Here is my HTML code for the input variable :
<div class="search">
<form action="{{ url_for('search') }}" method="POST">
<input type=text name="search"></br>
<div class="actions"><input type=submit value="Search"></div>
</form>
</div>
Here is the python code for the search query:
#app.route('/search', methods=["POST" , "GET"])
def search() :
if request.method == "POST" :
search = request.form["search"]
cursor=mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute( '''SELECT * FROM sites WHERE SITE_CODE=(%s)''', (search,))
data=cursor.fetchall()
return render_template("search.html", data=data , search=search )
else :
return render_template("search.html")
here is the jinja2 code for the output :
<table>
<td>Site Code</td>
<td>OM VLAN id</td>
<td>IuB VLAN id</td>
<td>Abis VLAN id</td>
<td>S1X2 VLAN id</td>
</tr>
{% for sites in data %}
<tr>
<td>{{sites.SITE_CODE}}</td>
<td>{{sites.OM_VLAN_id}}</td>
<td>{{sites.IuB_VLAN_id}}</td>
<td>{{sites.Abis_VLAN_id}}</td>
<td>{{sites.S1X2_VLAN_id}}</td>
</tr>
{% endfor %}
</table>
I have a fully ready to use database(I do not have to change anything in it, I just need to query searched data from it) note that everything is working fine when I try to show all the data from the table :
#app.route("/")
#app.route('/IP_PLAN',methods=['GET','POST'])
def IP_PLAN():
cursor=mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("SELECT * FROM sites")
data=cursor.fetchall()
return render_template("IP_PLAN.html",data=data)
UPDATE:
everything actually works, I just need to type the exact name of the "SITE_CODE". is there any way to get a result without doing it? I want to get as an output all the sites that contain an A in their SITE_CODE for example.
Thanks
UPDATE 2:
I finally achieved what I wanted to do, I just had to change the cursor.execute command :
cursor.execute( 'SELECT * FROM sites WHERE SITE_CODE LIKE %s', ['%' + search + '%'])

Flask generate dynamic table where number of rows and columns depends on number of elements in the list

Dear stackoverflow users,
I am creating a website with flask as a backend. It will fetch some data from different systems e.x. jenkins.
one of the "data packs" will be a list of Jenkins jobs
the main .py file will include route to a page
#app.route("/simplejenkins")
def simple_jenkins():
return render_template('simplejenkins.html', job_list=job_list)
and the simplejenkins.html will iterate over the job_list and list them
{% for job in jobs_list %}
<tr>
<td>{{ job }}</td>
<td>
<p>Successful!</p>
</td>
</tr>
{% endfor %}
the idea is that the number of elements in the list will change over time.
and I want to put them in the table - each element (job) in different cell. And let's say I want to have 6 columns (depends on the screen resolution, but let's ignore this for now). So in case of 44 jobs I should have 7 full rows and 2 more job in 8th row.
and my question is, how to achieve this?
the script below generates a table with dynamic number of rows and columns but how to populate the cells using jinja?
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Dynamic Table</title>
<script>
window.onload = createTable;
function createTable()
{
rn = window.prompt("Input number of rows", 1);
cn = window.prompt("Input number of columns",1);
for(var r=0;r<parseInt(rn,10);r++)
{
var x=document.getElementById('myTable').insertRow(r);
for(var c=0;c<parseInt(cn,10);c++)
{
var y= x.insertCell(c);
y.innerHTML="Row-"+r+" Column-"+c;
}
}
}
</script>
<style type="text/css">
body {margin: 30px;}
</style>
</head>
<body>
<table id="myTable" border="1">
</table><form>
</form>
</body>
</html>
i don't expect full solution of course, a link to existing similar case should be more than enough... somehow i cannot find one
thanks in advance for help
regards
Mariusz
To use that JS script all you need is an ajax call, once the page is ready, the ajax call will retrieve the data (jobs) from your flask route as JSON data and insert it in the table, with no need for jinja at all.
Or if it's not necessary for you to use a table, you can use the inline display in your frontend where your jobs will float next to each other as long as there is space, otherwise they will fall to the next line, you will loop over those jobs exactly as you did, but instead of having rows and cells you will have divs or something like that.
would you mind trying this ?
<table>
{% max_columns = 6 %}
{% interval = jobs_list|length / max_columns }
{% rows = interval|int + 1 } # +1 for the last/incomplete row
{% for p in range(rows) %}
<tr>
{% for n in range(max_columns) %}
{% cell_pos = (p * max_columns) + n }
<td>{{ jobs_list[cell_pos] }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

How to render HTML with golang data in golang gin web frame?

I am trying to place a golang array (also slice, struct, etc.) to HTML so I can use array element in HTML Element content when returning HTML from golang gin web framework. Another problem is how to render these data with loop? Such as Flask jinja
works in this way.
{% block body %}
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
Usually you have a folder with template files so first you need to tell the gin where these templates are located:
router := gin.Default()
router.LoadHTMLGlob("templates/*")
Then in handler function you simply pass template name the data to HTML function like this:
func (s *Server) renderIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", []string{"a", "b", "c"})
}
In index.tmpl you can the loop the data like this:
{{range .}}
{{.}}
{{end}}
The . is always the current context so in first line . is the input data and inside the range loop . is the current element.
Template example: https://play.golang.org/p/4_IPwD3Y84D
Documentation about templating: https://golang.org/pkg/text/template/
Great examples: https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html

Mailjet: Array value provided through vars makes email being blocked on sending

I’m working on an email template for Mailjet written in MJML that uses an array value provided through Vars to generate a list of items the sender wants to receive from the mail recipient. All values in the array are plain text values.
The data passed to the API request looks like this:
{
"FromEmail":"sender#email.com",
"FromName":"Chris Crumble",
"Subject":"Data Request",
"MJ-TemplateID":"200000",
"MJ-TemplateLanguage":true,
"Recipients":[
{
"Email":"recipient#email.com",
"Name":"Hans Henson"
}
],
"Vars":{
"mailTitle":"Data Request",
"userName":"Chris Crumble",
"imageUrl":"http://my.host.com/image.jpg",
"userBirthDate":"1.3.1982",
"recipientName":"Hans Henson",
"uploadUrl":"https://my.upload.com/",
"authVideoUrl":"https://my.authvideo.com",
"records":["Document A","Document B"],
"authPhone":"113777840097"
}
}
The template uses var:records like this:
...
</mj-text>
<mj-raw> {% if var:records:false %} </mj-raw>
<mj-text>
<p>
I, <strong>{{var:userName}}, born on {{var:userBirthDate}}</strong> am asking you to provide the following documents:
</p>
</mj-text>
<mj-raw> {% for item in var:records %} </mj-raw>
<mj-text>
{{item}}
</mj-text>
<mj-raw> {% endfor %} </mj-raw>
<mj-raw> {% else %} </mj-raw>
<mj-text>
<p>
I, <strong>{{var:userName}}, born on {{var:userBirthDate}}</strong>, am asking you to provide all my existing documents.
</p>
</mj-text>
<mj-raw> {% endif %} </mj-raw>
<mj-text>
...
As long as var:records isn’t set in the data sent with the request, the mail is sent as expected. As soon as an (not empty) array value is provided with the request, the mail is blocked by Mailjet on sending without giving any further information on the reason.
No idea how to get this working.
UPDATE:
Thanks to Zhivko’s hint to the error reporting mechanism provided by Mailjet I was able to gain a little more insight into the problem.
The template produces the following error:
expression parsing error ## Unknown identifier: var:records:false ## near ## var:records:false ##
This still doesn’t make any sense to me as the line mentioned is an if condition with a default value of false defined for the case that no value for var:records is provided with the api request.
Also the template only produces this error when the value is explicitely set in Vars and is not empty.
My tests so far make me guess that it may have to do with the provided value being an array value as the line doesn’t cause any problems if the value is plain string.
I had the same problem and after asking the MJML team on their Slack I add an answer. Just use the defined() method :
Example :
{% if defined(var:employees) %}
My employees :
<ul>
{% for employee in var:employees %}
<li>{{employee.firstname}} {{employee.lastname}}</li>
{% endfor %}
</ul>
{% endif %}
This method is correct and a core maintainer of MJML just says :
It's not publicly documented yet
PS : Their Slack is a good place to ask this kind of question and I had a response in minutes. (mjml.slack.com)
The message is probably blocked due to an error in the template language. To receive details about the error, enable the error reporting mechanism. If you have troubles debugging the error message, open a support ticket with Mailjet for in depth investigation for the specific template.
As far as I know, Mailjet doesn't allow arrays as a personalized var.
DataType: the type of data that is being stored (this can be either a
str, int, float or bool)
https://dev.mailjet.com/guides/#manage-contacts
Solution:
<% if(typeof bar !== 'undefined') { %>
variable 'bar' is defined in payload:
<b><%= bar %></b>
<% } else {%>
variable 'bar' is not defined in payload
<% }%>

build an includable template as string [django]

I want to build a list of clickable links for my nav, and because these are links to my site, I want to use the url-tag. I get a list of dictonaries which knows all names for the links and create a template string with them with this function:
def get_includable_template(links):
output = '<ul>'
for link in links:
output = output + '<li><a href="{% url' + get_as_link(link) + '%}>" + link['shown'] + '</a></li>'
output = output + '</ul>
links looks like this:
links = [
{'app': 'app1', 'view': 'index', 'shown': 'click here to move to the index'},
{'app': 'app2', 'view': 'someview', 'shown': 'Click!'}
]
get_as_link(link) looks like this:
def get_as_link(link):
return "'" + link['app'] + ':' + link['view'] + "'"
The first method will return a template, which looks like this (but it's all in the same code line):
<ul>
<li>click here to move to the index</li>'
<li>Click!</li>
</ul>
I want this to be interpreted as template and included to another template.
But how to include this?
Let's say, my other template looks like this:
{% extends 'base.html' %}
{% block title %}App 1 | Home{% endblock %}
{% block nav %}INCLUDE THE TEMPLATE HERE{% endblock %}
{% block content %}...{% endblock %}
What I have already tried:
make the template string a variable - doesn't work, because it doesn't interpret template language in variables (I couldn't find a template tag similar to safe which not only interprets HTML code but also template code.
Building HTMl code in my methods (Isn't best-practice at all, because I needed to use absolute paths)
Is there a good solution about this?
You are making this more complicated than it needs to be.
Firstly, it seems that the only reason you need this to be interpreted as a template is so that it parses the url tag. But there is already a way of creating links in Python code, and that is the reverse() function. You should use that instead.
Secondly, the way to dynamically generate content for use inside a template is to use a custom template tag.