I had some pyramid code that used 'request.route_path()' in the 'href=' portion of an anchor tag to open a slide-in on my webpage. In the view handler I had a check for 'request.is_xhr' which called 'render_to_response()' so I could change my renderer appropriately. This worked correctly when the view was accessed via the request.route_path().
I now need to change the functionality a bit so I can first check if the user is on a mobile device via jQuery. So the 'href=' now invokes a javascript function which then uses Ajax to access the view handler. Basically, I had request.route_path('slide_in', arg1=data, arg2=data2) and now have an ajax call where the url is '/slide_in/data/data2'. This seems to work as the view handler is invoked and the request.is_xhr check is set to True, as it should be. The problem I have is that the call to render_to_response() doesn't fail, but doesn't seem to do anything either because I end up with a blank page when using Ajax. It works fine with the original 'request.route_path()'.
Does anyone have insight as to why this might be? The headers and everything are identical in both situations and the request object is valid, but the Ajax initiated call results in a blank page. Thanks for any thoughts as I am new to this and have tried LOTS of different ideas but am quite stuck.
Have a look at this my almost rant-like answer to this question. Point is - your application generates a blob of text, which includes the output of request.route_path()
, which is just a string. JavaScript has no way of telling whether that string was generated by some function or not.
There's absolutely no way the fact that the URL has been generated by request.route_path()
or simply typed manually can have any effect on the behaviour of a Pyramid view which is invoked by that URL - unless the URLs are actually different. Which can easily be checked by comparing those URLs.
A couple of suggestions:
Pyramid has an xhr
view predicate which may allow you to avoid doing manual checks and render_to_response
- instead you can have two separate functions with different renderers.
@view_config(..., xhr=True, renderer='json')
def serve_json(...):
...
return {"hello": "world"}
@view_config(..., xhr=False, renderer='mytemplate.mak')
def serve_html(...):
...
return {"hello": "world"}
There is a nice user-agents Python library which would allow you to do the check in Python, so maybe you don't need that Ajax at all. You may even create a custom view predicate using that library.