Skip to content

Partials are acting weird #1037

Closed
dsx opened this Issue Jun 28, 2013 · 15 comments

4 participants

@dsx
dsx commented Jun 28, 2013

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
Pylons Project member

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
dsx commented Jun 28, 2013

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

@mcdonc
Pylons Project member
mcdonc commented Jun 28, 2013

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

@dsx
dsx commented Jun 28, 2013

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

@blaflamme
Pylons Project member

@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
Pylons Project member

@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
Pylons Project member

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
Pylons Project member

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

@blaflamme
Pylons Project member

@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
Pylons Project member
mcdonc commented Aug 13, 2013

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

@blaflamme
Pylons Project member

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
Pylons Project member

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
Pylons Project member
mcdonc commented Aug 14, 2013

That would be good.

@blaflamme
Pylons Project member
@blaflamme blaflamme closed this Aug 14, 2013
@mmerickel
Pylons Project member

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.