I try to substitue strings with variables using locals() in python but I can find a way to use the % character inside the string without error. Here is a concrete example :
color = colors_generator() #the function return a color
html = """<html><head>
<style>#square{color:%(color)s;width:100%;height:100%;}</style>
</head> <body> <div id="square"> </div>
</body></html>""" % locals()
print "Content-Type: text/html\n"
print html
Result : TypeError: not enough arguments for format string
The problem is the % character in 100%. How can I escape it?
escape % with %
html = """<html><head>
<style>#square{color:%(color)s;width:100%%;height:100%%;}</style>
</head> <body> <div id="square"> </div>
</body></html>""" % locals()
Virhilo has already answered your direct question, but if you find you are building quite big/complicated templates it might be worth looking at a full blown template engine instead:
http://docs.python.org/library/string.html
http://jinja.pocoo.org/
http://www.makotemplates.org/
Related
I've this view in my view
def terms(request):
d = getVariables(request,dictionary={'page_name': "Jack's Terms of Service"})
return render(request, 'jack/terms.html', d)
I'm rendering this as a page title in the templates
<title>{{ page_name }}</title>
But for some reason it prints the page_ name like this
<title>Jack's Terms of Service</title>
I don't know why it's not printing the apostrophe in the string.
Use safe. It marks a string as not requiring further HTML escaping prior to output.
<title>{{ page_name|safe }}</title>
Documentation here: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#safe
I'm trying to find a nice way of wrapping html tags in html comments without writing 5 functions and 50 lines of code. Using an example code :
<section class="left span9">
### Test
</section>
I need to transform it to :
<!--<section class="left span9">-->
### Test
<!--</section>-->
I have a regex to find the tags
re.findall('<.*?>', str)
but in the last years I wasn't using lambdas too often so now I'm having a hard time getting it to work.
btw any ideas for the reverse of this process - decommenting the tags ?
You can comment/uncomment using simple replace like this
myString = '<section class="left span9">'
print myString.replace("<", "<!--<").replace(">", ">-->")
print myString.replace("<!--", "").replace("-->", "")
Output:
<!--<section class="left span9">-->
<section class="left span9">
Note: This works because, a valid HTML document should have < and > only in the HTML tags. If they should appear, as they are, in the output, they have to be properly HTML escaped with > and <
Ok, so temporarily I've ended up using two functions and re.sub for that :
def comment(match):
return '<!--'+match.group(0)+'-->'
def uncomment(html):
return html.replace('<!--', '').replace('-->', '')
commented_html = re.sub('<.*?>', comment, html_string)
uncommented_html = uncomment(commented_html)
I'm trying to do something that I imagine must be trivial in mako, but I just can't figure out how I should procede and I'm finding the documentation pretty useless. I'm quite familiar with Python and DTL, but I just don't understand why this code is throwing a syntax error.
Basically, all I want to do is take in a datum object (just a small dictionary) and differently generate a link based on where the request is coming from. I know it would be trivial to do this in straight python and pass it in as context, but I'm really trying to warm up to mako. Any help would be hugely appreciated.
<%def name="courseware_link(datum)">
% if courseware in ${request.url}:
<a href=${request.url}[:${request.url}.find("courseware")+len("courseware")+1]+datum["url"]>
% else:
<a href=${request.host}+"/courses/"+datum["org"]+"/"+datum["course_ids"]+"/#/courseware/"+datum["url"]
% endif
</%def>
More specifically the syntax error is this:
(SyntaxError) invalid syntax (<unknown>, line 1) (u'if courseware in ${request.url}:pass') in file '/file' at line: 70 char: 1
and line 70 is the second line % if courseware...
You are mixing ${} with regular python in the if conditional and both a tags. Also, you cannot nest ${} inside ${}. You should probably refactor this code to be either out of the template or into a <% %> block, but something like this should work:
%if "courseware" in request.url:
<a href="${request.url[:request.url.find('courseware')+len('courseware')+1]+datum['url']}">
%else:
<a href="${request.host + '/courses/' + datum['org'] + '/' + datum['course_ids'] + '/#/courseware/' + datum['url']}">
%endif
Here is a refactored version:
<%def name="courseware_link(datum)">
<%
if "courseware" in request.url:
url = request.url[:request.url.find("courseware")+len("courseware")+1]
url += datum["url"]
else:
url = request.host + "/courses/" + datum["org"] + "/"
url += datum["course_ids"] + "/#/courseware/" + datum["url"]
%>
<a href="${url}">
</%def>
Furthermore you might want to use a routing package to generate your urls instead of building them manually like this, Django should provide something to automatically construct urls.
I was looking at the code from this site, for a basic google app engine calculator. I am just as inexperienced with GAE as I am with HTML, so when I saw the code bellow I was a little confused. Mostly with the last line </html>""" % (result, buttons)). What is the % for and how does it relate result and buttons to the html code?
result = ""
try:
result = f[operator](x, y)
except ValueError:
result = "Error: Incorrect Number"
except ZeroDivisionError:
result = "Error: Division by zero"
except KeyError:
pass
# build HTML response
buttons = "".join(["<input type='submit' name='operator' value='"
+ o + "'>" for o in sorted(f.keys())])
self.response.out.write("""<html>
<body>
<form action='/' method='get' autocomplete='off'>
<input type='text' name='x' value='%s'/><br/>
<input type='text' name='y'/><br/>
%s
</form>
</body>
</html>""" % (result, buttons))
The % is for formatting strings in Python. See a good explanation at Dive Into Python. In your example they are used to replace the '%s' characters with the values from variables.
Modifying your example:
A modified version your example, hardcoding values of result and buttons.
result = "THIS IS MY RESULT"
buttons = "AND MY BUTTON"
output = """
<html>
<body>
<form action='/' method='get' autocomplete='off'>
<input type='text' name='x' value='%s'/><br/>
<input type='text' name='y'/><br/>
%s
</form>
</body>
</html>
""" % (result, buttons)
print output
would yield:
<html>
<body>
<form action='/' method='get' autocomplete='off'>
<input type='text' name='x' value='THIS IS MY RESULT'/><br/>
<input type='text' name='y'/><br/>
AND MY BUTTON
</form>
</body>
</html>
In your example buttons holds more Html, and format strings make more sense in a context where the values would actually change, but the above should illustrate the basic principle.
A simpler example:
The code below:
result = "THIS IS MY RESULT"
buttons = "AND MY BUTTON"
print "%s ... %s!" % (result, buttons)
Would yield:
THIS IS MY RESULT ... AND MY BUTTON!
How it relates to App Engine:
Both examples above say print: this prints the output to "stdout"—your console.
In your original example, it says self.response.out.write, which is how you tell App Engine to write the text (which is Html) to your browser.
Concretely, if you change:
result = "THIS IS MY RESULT"
buttons = "AND MY BUTTON"
print "%s ... %s!" % (result, buttons)
to:
result = "THIS IS MY RESULT"
buttons = "AND MY BUTTON"
self.response.out.write("%s ... %s!" % (result, buttons))
the text will appear in your browser when you visit the page instead of on the console.
References:
Dive Into Python, also linked above is a great resource for learning Python. The whole book is good if you're new to Python. As are the Udacity courses.
The Python documentation on format strings is a good reference for format strings specifically.
The book "Using Google App Engine" is a great resource for learning Python, Html, and App Engine all at once. I can honestly recommend it, having read it myself. It's very accessible, but it is a few years old now.
Have fun!
How do I insert a variable into an HTML email I'm sending with python? The variable I'm trying to send is code. Below is what I have so far.
text = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1><% print code %></h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
"""
Use "formatstring".format:
code = "We Says Thanks!"
html = """\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>{code}</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
""".format(code=code)
If you find yourself substituting a large number of variables, you can use
.format(**locals())
Another way is to use Templates:
>>> from string import Template
>>> html = '''\
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>$code</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
'''
>>> s = Template(html).safe_substitute(code="We Says Thanks!")
>>> print(s)
<html>
<head></head>
<body>
<p>Thank you for being a loyal customer.<br>
Here is your unique code to unlock exclusive content:<br>
<br><br><h1>We Says Thanks!</h1><br>
<img src="http://example.com/footer.jpg">
</p>
</body>
</html>
Note, that I used safe_substitute, not substitute, as if there is a placeholder which is not in the dictionary provided, substitute will raise ValueError: Invalid placeholder in string. The same problem is with string formatting.
use pythons string manipulation:
http://docs.python.org/2/library/stdtypes.html#string-formatting
generally the % operator is used to put a variable into a string, %i for integers, %s for strings and %f for floats,
NB: there is also another formatting type (.format) which is also described in the above link, that allows you to pass in a dict or list slightly more elegant than what I show below, this may be what you should go for in the long run as the % operator gets confusing if you have 100 variables you want to put into a string, though the use of dicts (my last example) kinda negates this.
code_str = "super duper heading"
html = "<h1>%s</h1>" % code_str
# <h1>super duper heading</h1>
code_nr = 42
html = "<h1>%i</h1>" % code_nr
# <h1>42</h1>
html = "<h1>%s %i</h1>" % (code_str, code_nr)
# <h1>super duper heading 42</h1>
html = "%(my_str)s %(my_nr)d" % {"my_str": code_str, "my_nr": code_nr}
# <h1>super duper heading 42</h1>
this is very basic and only work with primitive types, if you want to be able to store dicts, lists and possible objects I suggest you use cobvert them to jsons http://docs.python.org/2/library/json.html and https://stackoverflow.com/questions/4759634/python-json-tutorial are good sources of inspiration
Hope this helps