sqlalchemy / mako

Mako Templates for Python
https://www.makotemplates.org
MIT License
353 stars 60 forks source link

Allow restricting the use of template data as magical globals #231

Open sqlalchemy-bot opened 10 years ago

sqlalchemy-bot commented 10 years ago

Migrated issue, originally created by eevee (@eevee)

For big projects with big collections of big templates, having a set of super-global variables that aren't documented and might vary by caller starts to get really thorny and confusing. There are a few features that partially help this problem:

I don't see how to fix this outside of Mako without doing something really gross, but on the other hand Mako tries really hard not to be too opinionated.

I think the least-intrusive, most-helpful thing would be to add an argument to <%page> (opaque, maybe?) that does two things: shadows the context data when a function declared in that template is called, and doesn't populate the context with extra kwargs when body is rendered directly. So this would fail:

mako.template.Template(filename='a.mako').render(request=...)

# a.mako
<%namespace name="lib" file="lib.mako" />
${lib.print_link("hello world")}

# lib.mako
<%page opaque />

<%def name="print_link(title)">
<a href="${request.route_url(...)}">${title}</a>
</%def>

...because request doesn't exist inside print_link.

Then you could opt in on a per-template basis; for example, keep the default behavior for templates that render entire pages (which is reasonable), but use opaque for shared code where the callers aren't all immediately obvious.

Doesn't cover the case of a Python module imported as a namespace, but at least in that case it's plainly obvious when you're relying on non-arguments.

I think I could implement this, if the idea is okay.

sqlalchemy-bot commented 10 years ago

Michael Bayer (@zzzeek) wrote:

OK.... im sort of grokking it. you just want <%page> to block anything that isn't passed in directly, is that it? propagate_context=False maybe?

sqlalchemy-bot commented 10 years ago

eevee (@eevee) wrote:

Yeah, but opt-in (so as to not break everyone's existing templates), with an argument on <%page> within the template itself.