Search code examples
pythonpostgresqlzopedtml

Zope PostgreSQL variable with HTML and DTML


I have a postgresql db table called blog_post and in that table a column called post_main. That column stores the entire blog post article, including various HTML and DTML tags.

For reference (and yes, I know it's old), this is Zope 2.13 with PostgreSQL 8.1.19

For example:

<p>This is paragraph 1</p>

<dtml-var "blog.sitefiles.post.postimg1(_.None, _)">

<p>This is paragraph 2</p>

The dtml-var tag is telling Zope to insert the contents of the dtml-document postimg1 between the two paragraphs.

OK, no problem. I am storing this data without issue in the postgres db table, exactly as it was entered, and I am running a ZSQL Method via a <dtml-in zsqlmethod> tag that surrounds the entire dtml-document, in order to be able to call to the variables I need in the page.

Normally, and without either HTML code OR especially without DTML tags, it's no issue to insert the data into the web page. You do this via &dtml-varname; if you have no html tags and just want a plain text output, OR you do <dtml-var varname> if you want the data to be rendered and shown as proper html.

Here's the problem

Zope is just posting the <dtml-var "blog.sitefiles.post.postimg1(_.None, _)"> line to the html page instead of processing it like when I type it into the dtml-doc directly.

What I need:

I need the code stored in the post_main column (referenced above as varname) to be processed as if I typed it directly into the dtml-document, so that the <dtml-var> tags work the way they are supposed to work.


Solution

  • So, you have a variable that contains a DTML Document, and you want to execute that document and insert the results?

    To be honest, I'm not sure that's possible in DTML alone, as it generally users don't want to execute code contained in strings. This is the same danger as exposing eval() or exec() of user supplied strings, as if someone can control the string they have arbitrary code execution on the Zope instance. It's the equivalent of storing PHP code in your database and executing that.

    Frankly, I'm surprised you're using DTML on Zope 2.13 at all, rather than PageTemplates, but I assume you've got a good reason for it.

    If you want to interpret the value of a DTML variable rather than just insert it, you'll need to explicitly do the interpreting, using something like:

    from DocumentTemplate.DT_HTML import HTML
    return HTML(trusted_dtml_string)
    

    The problem with this is that you can't do it in a Script (Python) through the web, because of the security concerns. If you do this as an external method or filesystem code it's very likely that you'll allow arbitrary code execution on your server.

    I'm afraid my only recommendation is to avoid doing this, it's very difficult to get it right and errors can be catastrophic. I'd strongly suggest you do not store DTML tags as part of your blog articles.

    As an alternative, if you have a fixed number of delegations to DTML methods, I recommend writing a Python script, such as:

    ## Script (Python) "parse_variables"
    ##bind container=container
    ##bind context=context
    ##bind namespace=
    ##bind script=script
    ##bind subpath=traverse_subpath
    ##parameters=post, _
    ##title=
    ##
    post = post.replace("##POST_IMAGE##", context.postimg(None, _))
    return post
    

    And then calling that with your variable that contains the user-supplied data, like <dtml-var expr="parse_variables(data, _)">