How to include a variable html file?

13 views
Skip to first unread message

billf

unread,
Oct 7, 2008, 5:29:15 PM10/7/08
to web2py Web Framework
What I want to do is include a variable html file (an html fragment)
in the middle of my page. I suppose I could use a server-side include
(SSI) but it seems easier to keep it in web2py.

I have my template that defines header, footer, whatever and in a
central content pane: let's call it static.html.

I want to include the html from a file, e.g. my_fragment.html. I can
see 2 options:

1. a static.py controller that accepts a variable, gets the html (not
sure how you do that yet) and returns it as a dict(file=my_html) to
static.html and the view includes the contents of the variable.

2. a static.py controller that returns the variable file name to
static.html view and the view gets the file and includes it.

Either way, it seems that I need the view to contain something like
{{include =file}} and I can't find an example of this or get it to
work by trial and error. {{include 'specific_file.html'}} works fine
but not what I want and I can't use an if...else...else as I don't
know all the possible files.

Am I barking up the wrong tree or is there a simple solution?

Bill

mdipierro

unread,
Oct 7, 2008, 5:34:01 PM10/7/08
to web2py Web Framework
file file contains pure HTML, not {{ }} code you can do:

{{=XML(open(filename).read())}}

if filename is a constains {{ }} code you must do

{{include 'filename.html'}}

You can also do

{{include filename}}

where filename is a variable but you would not be able to bytecode
compile your app because views are parsed only once before byte-code
compilation.

Massimo

billf

unread,
Oct 7, 2008, 8:54:29 PM10/7/08
to web2py Web Framework
Massimo

Thanks for the info. With a little extra that I finally found in the
examples, I now have a working solution that I include below in case
it helps anyone else.

Controller function
def static():
filename='applications/%s/static/html/%s.html'%
(request.application,request.vars.key)
try:
htmlfile=open(filename).read()
return dict(htmlfile=XML(htmlfile)) # works if html does not
contain {{ }}
except:
response.view="error.html"
return dict(message="Unable to open static html file
%s"%filename)

View - static.html
{{extend 'my_layout.html'}}

{{def sidepanel():}} <!-- not necessary for this particular problem --
>
{{include 'sidepanel.html'}}
{{return}}

{{def mainpanel():}} <!-- if not containing static file then amend as
required -->
<div id="content">
{{=htmlfile}}
</div>
{{return}}

Usage is:
a request like "http://blah/my_application/my_controller/static?
key=puppy"
should return a page based on my_layout.html including a sidepanel
from views/sidepanel.html
and a main panel from my_application/static/html/puppy.html

If there is an error reading the target file then the response view is
"error.html" and it is passed a suitable message.

As I'm new to web2py and python I'd be interested in any feedback.

Bill

mdipierro

unread,
Oct 7, 2008, 10:57:49 PM10/7/08
to web2py Web Framework
This is very dangerous!

Your app is opening a file and its filename is passed by the client
and not validated (request.vars.key). This allows any visitor of your
app to do "directory traversal attacks" and read almost any file off
you machine, including perhaps files that contain account info.

At least you should do:

import re
if not re.compile('\w+').match(request.vars.key): raise HTTP(400)

Massimo

billf

unread,
Oct 8, 2008, 4:41:07 AM10/8/08
to web2py Web Framework
Massimo

Thanks for the warning. I can be a bit naive about breaking into
sites.

I believe that I am ok in my own particular case as I force ".html" to
be added to any user input. Testing seems to confirm this as well as
confirming that without forcing ".html" the user can traverse
directories!

If have amended my code as suggested but the final version
distinguishes between "invalid" and "not found" more completely.
re.compile('\w+').match(request.vars.key) is True if key starts with a-
zA-Z0-9_. Adding "if m and m.group(0)== request.vars.key" ensures
that the whole name only contains the valid characters.

def static():
m=re.compile('\w+').match(request.vars.key)
if m and m.group(0)==request.vars.key:
filename='applications/%s/static/html/%s.html' %
(request.application,request.vars.key)
try:
htmlfile=open(filename).read()
return dict(htmlfile=XML(htmlfile))
except:
message='Static html file %s not found' % request.vars.key
else:
message='Invalid static file name %s' % request.vars.key
response.view="general/error.html"

Thanks again, Bill

mdipierro

unread,
Oct 8, 2008, 11:26:31 AM10/8/08
to web2py Web Framework
With the security fix, this is a nice example on what you can do with
views.

Massimo
Reply all
Reply to author
Forward
0 new messages