Here's what I ended up writing for use in my controller.  It's a bit
verbose, but it fits in with how I was doing things anyway.  That is,
I was already using FormEncode for other stuff, and I already had a
create_exception_response function for other things:

class JSONPValidator(formencode.Schema):

    """Allow the user to specify a jsonp parameter."""

    allow_extra_fields = True
    filter_extra_fields = True
    jsonp = validators.Regex(r'^[a-zA-Z0-9_]*$', strip=True, if_missing='')


@decorator
def jsonpify(f, *args, **kargs):
    """Add support for jsonp.

    This wraps the existing jsonify decorator.  If the parameter jsonp
    is defined, it uses it to wrap the json.

    See also: http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/

    """
    jsonp = ''
    try:
        form_result = JSONPValidator.to_python(request.params)
        jsonp = form_result['jsonp']
    except formencode.Invalid, e:

        # Complain to the user instead of calling f.

        (f, args, kargs) = (create_exception_response, (e,), {})

    # The syntax for wrapping a decorator is a bit weird.

    result = jsonify(f)(*args, **kargs)
    if jsonp:
        result = "%s(%s)" % (jsonp, result)
    return result


def create_exception_response(e, status_code=httplib.BAD_REQUEST):
    """Given an exception, return an appropriate response.

    Also, set the response.status_code.  The default status code is
    httplib.BAD_REQUEST simply because that's the most common case.

    """
    response.status_code = status_code
    return dict(exception=e.__class__.__name__,
                errorMessage=str(e))

Here's what it looks like if I try it out.  If I add &jsonp=foo to my
URL, I get:

foo({...})

If I leave it off, I get:

{...}

If I add &jsonp=^^ to my URL, I get:

{
  "errorMessage": "jsonp: The input is not valid",
  "exception": "Invalid"
}

My controller looks like:

    @jsonpify
    def myaction(self):
        ...

It'd be easier for me if Pylons provided this functionality so that I could say:

    @jsonify(allow_jsonp=True)
    def myaction(self):
        ...

But I was able to meet my own need.

Happy Hacking!
-jj

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to