Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Partials are acting weird #1037

Closed
dsx opened this Issue · 15 comments

4 participants

@dsx

Consider this example:

# URLs
http://127.0.0.1:6543/the_good/some/fancy/stuff
http://127.0.0.1:6543/the_bad/some/more/fancy/stuff
# Route configuration
add('blah', '/blah/{who}/{stuff:.*$}')

# View:
class BlahViews(object):
    def __init__(self, request):
        self.request = request
        self.match = self.request.matchdict

    @view_config(route_name='blah', renderer='project:templates/blah.mako', http_cache=0)
    def blah(self):
        who = self.match.get('who')
        stuff = self.match.get('stuff')

        print(who, stuff)  # DEBUG

        return (who, dict(stuff=stuff))
# Template:
<%def name='the_good(stuff)'>
    Good stuff: ${stuff}
</%def>

<%def name='the_bad(stuff)'>
    Bad stuff: ${stuff}
</%def>

Depending on which URL has been opened first, both URLs will continue rendering same part of template even though the debug output is correct.

Pyramid 1.4.2, Python 3.3, Mako 0.8.1.

@mmerickel
Owner

For completeness @dsx and I tinkered with this in irc and things work fine using the declarative routing.

import os
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.view import view_config
here = os.path.dirname(os.path.abspath(__file__))

class BlahView(object):
    def __init__(self, request):
        self.request = request
        self.match = request.matchdict

    @view_config(route_name='blah',
                 match_param='who=the_bad',
                 renderer='blah#the_bad.mako')
    @view_config(route_name='blah',
                 match_param='who=the_good',
                 renderer='blah#the_good.mako')
    def blah(self):
        who = self.match.get('who')
        stuff = self.match.get('stuff')

        print(who, stuff)  # DEBUG

        return dict(stuff=stuff)

if __name__ == '__main__':
    settings = {}
    settings['mako.directories'] = os.path.join(here,'templates')
    config = Configurator(settings=settings)
    config.add_route('blah','/{who}/{stuff:.*}')
    config.scan()
    app = config.make_wsgi_app()
    server = make_server('', 8080, app)
    server.serve_forever()

I think his final solution was to use render_to_response('blah#{}.mako'.format(who), {}, request=request).

@dsx

Yes, render_to_response() is used for now and works just fine.

@mcdonc
Owner

So there's still a bug in the tuple-return case?

@dsx

Yes, it is still there. render_to_response() or multiple view_config() decorators are just workarounds.

@blaflamme
Owner

@dsx is the problem still there. I'm running @mmerickel example with your template file and get the right partial rendered each time. Am I missing something?

@mmerickel
Owner

@blaflamme my example is one I verified to work while talking to him on irc. However his example which uses the old "return a tuple" does not work.

@blaflamme
Owner

Oh ok I see, @dsx is using the «wrong» tuple way. I think we should deprecate it and just use the «official» way supported by both mako and chameleon. Do you know if pyramid_jinja supports it?

@mmerickel
Owner

I'm pretty certain that pyramid_jinja2 does not support the tuple syntax after briefly looking at the source.

@blaflamme
Owner

@mmerickel I was thinking about jinja rendering the «official» partial way, and I think it does, right? This is why I think we should deprecate the tuple thing. It was done at some point to mimics the pylons «the web framework» mako renderer and before we officially supported partials.

@mcdonc
Owner

Whether or not we deprecate the tuple syntax, I think we probably should chase this down.

@blaflamme
Owner

Actually the problem lies in the fact defname is None only first and then after uses the previous value:

https://github.com/Pylons/pyramid/blob/master/pyramid/mako_templating.py#L218

If I remove the conditional tests are running fine and the template result is right. OTOH I don't know if it breaks something because I can't figure out why the conditional is there ?

if self.defname is None:
    if isinstance(value, tuple):
        self.defname, value = value
    else:
        if isinstance(value, tuple):
            _, value = value

Would just be

if isinstance(value, tuple):
    self.defname, value = value
@blaflamme
Owner

I can add also add a test that loads two defname in a row and verify the second doesn't use the first one.

@mcdonc
Owner

That would be good.

@blaflamme
Owner
@blaflamme blaflamme closed this
@mmerickel
Owner

it might be wise to backport this to the 1.4.x series

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.