webpy: how to override content of basic template? - python

I'm using webpy with a basic template
render = web.template.render(basedir + 'templates/', base='layout', globals=globals_vars_custom)
in layout.html I have something like:
$def with (content)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>PAGE TITLE</title>
<!-- Some CSS and some javascript -->
</head>
<body>
$:content
</body>
</html>
This basic template works fine for the 90% of my site, but I have a page in which I need to insert some other data inside the <head> (some meta tags).
How can I do this? How can I put the <head> inside a structure that I can easily override inside a template?
Thanks!

It was easier than I tought:
You can create a variable in a template:
in page.html you can define a variable
$var title = 'specific title'
in the base template layout.html you can call the varable:
$def with (content)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>$content.get("title","DEFAULT TITLE")</title>
<!-- Some CSS and some javascript -->
</head>
<body>
$:content
</body>
</html>
I hope this answer can be useful also for other people.

Related

Use Python String with HTML

Say I have some string in a python file like:
myString = "Hello StackOverflow"
How I could access and use it in a separate html file like this generic template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
You really should use one of the many existing template libraries (Jinja being one of the most popular).
You can simply read in your template as a string and .format() it like any other, but this is error prone and you will run into many difficulties.
http://jinja.pocoo.org/docs/2.10/
https://www.makotemplates.org/
https://genshi.edgewall.org/

python web.py write in template html file error

use web.py to write a python program:
class user_name_friend_sub:
def POST(self):
u_n = web.input()
u_name = u_n.user_name
u_id = u_n.user_id
user_friends_list = self.user_info_page(u_name,u_id)
return render.user_friends(user_friends_list)
user_friends_list is a list containing many dic,like:
[{'user_id': '1146214671', 'user_name': 'Xiaohong Xu', 'user_unit': 'Toronto, Ontario'},
...
...
{'user_id': '668347108', 'user_name': 'Lynn Zou', 'user_unit': 'Lead Software Engineer I at American Institutes for Research (AIR)'}]
and the template html file - user_friends.html is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style>
h1 {
text-align: center;
font-size:30px;
}
</style>
</head>
<body>
<h1>User friends data</h1>
$def with (user_friends_list)
<ul>
$for user_friend in user_friends_list:
<li>$user_friend["user_name"]</li>
</ul>
</body>
</html>
when running,it errors:
File "templates\user_friends.html", line 21
def with (user_friends_list)
^
SyntaxError: invalid syntax
Template traceback:
File 'templates\\user_friends.html', line 21
</html>
however, when I delete almost all the html element, the user_friends.html become:
$def with (user_friends_list)
<ul>
$for user_friend in user_friends_list:
<li>$user_friend["user_name"]</li>
</ul>
it runs ok,
could you please tell me the reason
Python is a server-side language. This means it cannot be executed via a webpage directly, as it runs on a server (hidden from user visibility.) You must declare python code in .py files. Your HTML code could submit elements to a cgi end point, for example, which then allows the python to digest and return values: www.tutorialspoint.com/python/python_cgi_programming.htm

Django render_to_string <body><head> tag

I'm my django app I would like to load a static html page into a main template. This static html page is an email template. My goal is to edit this email in my main template. The email html page don't have a view in url.py. I don't use include in main template and I don't want to use iframe. The problem is that I would like to load ALL the html email tag (like
<html>
<head>
<body>
) but when I do the page's render this tag is deleted (or I don't see them in main template...). This is my code:
view.py
def my_view(request):
file_name = "/templates/path/emailtemplate.html"
htmlblock = render_to_string(file_name, {})
return render_to_response('main_template.html', {
'htmlblock': htmlblock,
},
context_instance = RequestContext(request))
main_template.html
<html>
<head>
....
<head>
<body>
<div id="content">
{{htmlblock}}
</div>
</body>
</html>
this is what I would like to have:
<html>
<head>
....
<head>
<body>
<div id="content">
<html>
<head>
....
</head>
<body>
...
</body>
</html>
</div>
</body>
</html>
Is this possible without iframe? Thanks a lot for your help.
EDIT
My goal is to have the
<html>
<head>
<body>
tag into
<div id="content">
where I load the email template.
My goal is to edit this email in my main template.
You can read the template into string by
with open('/templates/path/emailtemplate.html', 'r') as content_file:
content = content_file.read()
You can use the same as a value to an edit field and it will be visible as usual. This can be used as.
return render_to_response('main_template.html', {
'htmlblock': content,
}, context_instance = RequestContext(request))
You can further use the same in edit field as:
<textarea value={{htmlblock}}>
Or render the same normally in
<div id="content">{{htmlblock}}</div>

Jinja2 weird encoding error

I have been fighting this for a whole night...
I'm trying to use Python markdown to generate HTML files from .md files and embed them into some other HTML files.
Here is the problematic snippet:
md = markdown.Markdown(encoding="utf-8")
input_file = codecs.open(f, mode="r", encoding="utf-8") # f is the name of the markdown file
text = input_file.read()
html = md.convert(text) # html generated from the markdown file
context = {
'css_url': url_for('static', filename = 'markdown.css'),
'contents': html
}
rendered_file = render_template('blog.html', **context)
output = open(splitext(f)[0] + '.html', 'w') # write the html to disk
output.write(rendered_file)
output.close()
Here is my "blog.html" template , which is really simple:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>blog</title>
<link rel="stylesheet" href="{{ css_url }}" type="text/css" />
</head>
<body>
{{ contents }}
</body>
</html>
And yet this is what I get:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>blog</title>
<link rel="stylesheet" href="/static/markdown.css" type="text/css" />
</head>
<body>
<li>People who love what they are doing</li>
<li></li>
</ol>
</body>
</html>
So I'm getting those weird "&gt", "&lt" stuff, even though I've already specified the encoding to be 'utf-8'. What could possibly go wrong?
Thank you!
<> has nothing to do with encoding. These are HTML entities that represent your input. You should mark it as safe so that jinja will not automatically escape it.
{{ contents|safe }}

Python Pyramid - Add multiple chameleon base templates

I am using this procedure to use a base template which the other templates can derive from.
How can I create multiple base templates?
Just register them both:
from pyramid.renderers import get_renderer
def add_base_template(event):
base = get_renderer('templates/base.pt').implementation()
base2 = get_renderer('templates/base2.pt').implementation()
event.update({'base': base, 'base2': base2})
And then choose which to use in your template for each page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
metal:use-macro="base">
<tal:block metal:fill-slot="content">
My awesome content.
</tal:block>
</html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
metal:use-macro="base2">
<tal:block metal:fill-slot="content">
Content on a totally different page.
</tal:block>
I believe a template doesn't have to be the whole HTML element, so you could instead expand 2 macros into the same final template
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<body>
<div metal:use-macro="section1">
<tal:block metal:fill-slot="content">
Content for template "section1".
</tal:block>
</div>
<div metal:use-macro="section2">
<tal:block metal:fill-slot="content">
Content for template "section2".
</tal:block>
</div>
</body>

Categories