The new template system supports custom lexers, if web2py would expose the correct interface, it would allow you to define something like
{{:PT}} Which would translate to response.write(XML(simplejson.dumps(PT), escape=False) We can add as many of these custom named commands as we would like... It could even be a word {{json_dump PT}} Which just gave me an idea. I could implement a wildcard named command, which will perform a lookup on helpers, if a helper by that name exists it will attempt to use it. {{XML PT}} {{DIV PT}} {{P PT}} Not sure if this is something we want to do, since you can do the same with an equal sign and two parenthesis later. -- Thadeus On Sun, Jul 25, 2010 at 9:02 AM, Scott <blueseas...@gmail.com> wrote: > I agree that it should be available in either context, which means > including the helper. If folks wish to implement it in the view, they > could continue to do so... > > On Jul 24, 10:40 pm, Michael Ellis <michael.f.el...@gmail.com> wrote: >> I'm of two minds on this. It's a one-liner to implement as I've done it, >> but my implementation hides the rich argument set available in >> simplejson.dumps(): >> >> dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, >> allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', >> default=None, use_decimal=False, **kw) >> >> It also hides the arguments available to XML(). >> >> If implemented, I think it would be good to provide as many of the >> arguments as make sense for its use as a helper -- which probably means all >> of them. >> >> Regarding controller vs view, I think it should be available, like all the >> other helpers, in either context. >> >> Whether we implement it or not, I think the technique of passing python >> objects into javascript at render time with json serialization is quite >> useful and merits an example in the next revision of the book. >> >> Cheers, >> Mike >> >> >> >> >> >> >> >> On Sat, Jul 24, 2010 at 9:18 PM, Scott <blueseas...@gmail.com> wrote: >> > I think the JSON helper function should be implemented. This logic >> > should be contained within the controller and not within the view as I >> > would deem it business logic and not rendering logic. >> >> > On Jul 24, 7:52 pm, mdipierro <mdipie...@cs.depaul.edu> wrote: >> > > Should we have a JSON helper (same as you JD)? >> >> > > On Jul 24, 1:15 pm, Michael Ellis <michael.f.el...@gmail.com> wrote: >> >> > > > Something good has come out of this: while looking for a workaround I >> > > > learned about simplejson.dumps(). So now I've defined my own little >> > helper >> > > > JD() >> >> > > > import simplejson >> > > > def JD(obj): >> > > > return XML(simplejson.dumps(obj,indent=4)) >> >> > > > In my view (or controller) I can lump into one variable everything I'm >> > going >> > > > to need to pass into my js at render time, e.g. >> >> > > > PT = dict( >> > > > updatenow=False, >> > > > schartoptions = dict( >> > > > type ='bar', >> > > > barColor ='green', >> > > > chartRangeMin = chartmin, >> > > > chartRangeMax = chartmax, >> > > > ) >> > > > ## add more objects here ... >> > > > ) >> >> > > > then put a single line at the top of my js script and reference >> > everything >> > > > as part of that namespace, e.g. >> > > > <script type="text/javascript"> >> > > > ... >> > > > var PT = {{=JD(PT)}}; >> > > > ... >> >> > > > $(#something).sparkline( ..., PT.schartoptions); >> > > > ... >> > > > </script> >> >> > > > The JD(PT) expands to a nicely indented js declaration, e.g. >> >> > > > var PT = { >> > > > "updatenow": false, >> > > > "schartoptions": { >> > > > "chartRangeMin": 0, >> > > > "barColor": "green", >> > > > "type": "bar", >> > > > "chartRangeMax": 1 >> > > > } >> >> > > > }; >> >> > > > What's also cool is that if all or part of that declaration corresponds >> > to >> > > > data coming in from a getJSON() loop after the page is loaded, then >> > > > everything's already defined and initialized. >> >> > > > This feels like a definite improvement over what I was doing before. >> > Far >> > > > less clutter and definitely DRY'er. >> >> > > > Cheers, >> > > > Mike >> >> > > > On Sat, Jul 24, 2010 at 9:34 AM, Phyo Arkar <phyo.arkarl...@gmail.com >> > >wrote: >> >> > > > > I am also doing more and more in JS for views. Even search engine for >> > > > > tables, i am using JQGrid's local search (at latest version if >> > JQGrid).It >> > > > > dont need server side at all for search to work, which make it a lot >> > faster >> > > > > + lesser hit on server performance. >> >> > > > > On Sat, Jul 24, 2010 at 7:53 PM, Michael Ellis < >> > michael.f.el...@gmail.com>wrote: >> >> > > > >> My bad. It does work. In my earlier attempt to use it I forgot >> > that a >> > > > >> for loop variable isn't an object reference when looping over a list >> > of >> > > > >> strings. So the value of schartoptions wasn't being altered at all, >> > just >> > > > >> the loop variable. >> >> > > > >> I'm still in favor of an alternate operator, though. As it is now, >> > I've >> > > > >> moved all my chart options inside the script tag e.g. >> >> > > > >> var schartoptions = { >> > > > >> type: 'bar', >> > > > >> barColor: 'green', >> > > > >> chartRangeMin: '{{=chartmin}}', >> > > > >> chartRangeMax: '{{=chartmax}}' >> > > > >> }; >> >> > > > >> and substitute only the things that have to be determined at run >> > time >> > > > >> rather than clutter up my expressions by wrapping them in XML(). >> >> > > > >> I'd much rather code in python than js, but I'm beginning to feel >> > that >> > > > >> using more js and less python in views makes a lot of sense. >> >> > > > >> Thanks, >> > > > >> Mike >> >> > > > >> On Sat, Jul 24, 2010 at 8:40 AM, mdipierro <mdipie...@cs.depaul.edu >> > >wrote: >> >> > > > >>> I am confused: >> > > > >>> Does this now work? >> >> > > > >>> {{ >> > > > >>> schartoptions = """{ >> > > > >>> type: 'bar', >> > > > >>> barColor: 'green', >> > > > >>> chartRangeMin: '%d', >> > > > >>> chartRangeMax: '%d' >> > > > >>> } >> > > > >>> """%(chartmin,chartmax) >> >> > > > >>> }} >> >> > > > >>> and later on I use the variables within a script tag, e.g. >> >> > > > >>> <script type="text/javascript"> >> > > > >>> /* <![CDATA[ */ >> > > > >>> $("#{{=ks+kc}}").sparkline(data.wsc.{{=ks}}.{{=kc}}, >> > > > >>> {{=XML(schartoptions)}} >> > > > >>> </script> >> >> > > > >>> If not, what are chartmin and chartmax, are they themselves >> > helpers? >> >> > > > >>> On Jul 24, 7:28 am, Michael Ellis <michael.f.el...@gmail.com> >> > wrote: >> > > > >>> > Massimo, I'm not following you. I tried using XML (see earlier >> > post) >> > > > >>> and it >> > > > >>> > had no effect. Does it only work if applied immediately before >> > the = >> > > > >>> > operator? >> >> > > > >>> > Also, I think ":=" or something similar is much cleaner than >> > wrapping >> > > > >>> > everything in a function call. >> >> > > > >>> > Cheers, >> > > > >>> > Mike >> >> > > > >>> > On Sat, Jul 24, 2010 at 8:19 AM, mdipierro < >> > mdipie...@cs.depaul.edu> >> > > > >>> wrote: >> > > > >>> > > This >> >> > > > >>> > > {{:=never_escaped}} >> >> > > > >>> > > would be the same as >> >> > > > >>> > > {{=XML(ever_escaped)}} >> >> > > > >>> > > so why introduce new syntax? >> >> > > > >>> > > On Jul 24, 7:14 am, Michael Ellis <michael.f.el...@gmail.com> >> > wrote: >> > > > >>> > > > I could happily live with a solution that adds a 'no escape' >> > > > >>> operator to >> > > > >>> > > the >> > > > >>> > > > template language, e.g. >> >> > > > >>> > > > {{:=never_escaped}} >> >> > > > >>> > > > vs >> >> > > > >>> > > > {{=always_escaped}} >> >> > > > >>> > > > 1. Backward compatible, >> >> > > > >>> > > > 2. Safe by default, >> >> > > > >>> > > > 3. Allows designer to decide what's safe and what isn't, >> >> > > > >>> > > > 4. Seems like an easier fix than trying to make the >> > rendering code >> > > > >>> smart >> > > > >>> > > > enough to always distinguish js from html strings. >> >> > > > >>> > > > Just a thought, >> > > > >>> > > > Mike >> >> > > > >>> > > > On Sat, Jul 24, 2010 at 4:02 AM, mdipierro < >> > > > >>> mdipie...@cs.depaul.edu> >> > > > >>> > > wrote: >> > > > >>> > > > > Thadeus, >> >> > > > >>> > > > > This was a security fix. We had a a security review and >> > this was >> > > > >>> > > > > determined to be a weakness. The code by Mike Ellis broke >> > not >> > > > >>> because >> > > > >>> > > > > of the fix but because it incorrectly implicitly assumed >> > that >> > > > >>> the >> > > > >>> > > > > strings were HTML/XML and therefore needed escaping when, >> > in >> > > > >>> reality, >> > > > >>> > > > > they were JS strings. >> >> > > > >>> > > > > If we had a review board, would you have opposed to this >> > change? >> >> > > > >>> > > > > Massimo >> >> > > > >>> > > > > On Jul 23, 5:28 pm, Thadeus Burgess <thade...@thadeusb.com >> >> > > > >>> wrote: >> > > > >>> > > > > > I also agree that this is a break in backwards >> > compatibility. >> > > > >>> It is >> > > > >>> > > also >> > > > >>> > > > > a >> > > > >>> > > > > > change that was never considered for longer than 15 >> > minutes >> > > > >>> before >> > > > >>> > > the >> > > > >>> > > > > > decision to make the change was implemented. >> >> > > > >>> > > > > > I really wish we would put certain things such as this >> > under a >> > > > >>> review >> > > > >>> > > > > board >> > > > >>> > > > > > so they don't get into web2py and break things! >> >> > > > >>> > > > > > -- >> > > > >>> > > > > > Thadeus >> >> > > > >>> > > > > > On Fri, Jul 23, 2010 at 2:33 PM, MikeEllis < >> > > > >>> > > michael.f.el...@gmail.com >> > > > >>> > > > > >wrote: >> >> > > > >>> > > > > > > Typo: 2 sentence in prior message should read >> >> > > > >>> > > > > > > " ... after XML() supplies the unescaped string." >> >> > > > >>> > > > > > > On Jul 23, 3:28 pm, Michael Ellis < >> > michael.f.el...@gmail.com >> >> > > > >>> > > wrote: >> > > > >>> > > > > > > > Urgh! FWIW, putting XML() around the strings doesn't >> > seem >> > > > >>> to >> > > > >>> > > work. >> > > > >>> > > > > > > Looks >> > > > >>> > > > > > > > like the escaping is applied after XML() supplies the >> > > > >>> unquoted >> > > > >>> > > > > string. >> >> > > > >>> > > > > > > > I tried >> > > > >>> > > > > > > > {{ >> > > > >>> > > > > > > > for optstring in (schartoptions, countpieoptions, >> > > > >>> cchartoptions): >> > > > >>> > > > > > > > optstring = XML(optstring) >> > > > >>> > > > > > > > debug("opstring=%s"%optstring) >> > > > >>> > > > > > > > pass}} >> >> > > > >>> > > > > > > > after assigning the strings and before they are used >> > in >> > > > >>> inside >> > > > >>> > > the >> > > > >>> > > > > > > <script> >> > > > >>> > > > > > > > tags. >> >> > > > >>> > > > > > > > The debug() calls show the strings with the single >> > quotes >> > > > >>> > > unescaped, >> > > > >>> > > > > but >> > > > >>> > > > > > > > they still end up being escaped in what gets sent to >> > > > >>> browser. >> >> > > > >>> > > > > > > > On Fri, Jul 23, 2010 at 2:16 PM, Michael Ellis < >> > > > >>> > > > > > > michael.f.el...@gmail.com>wrote: >> >> > > > >>> > > > > > > > > Thanks, Nathan. That's certainly a possibility. >> > It's >> > > > >>> just that >> > > > >>> > > I'm >> > > > >>> > > > > not >> > > > >>> > > > > > > > > sure what security issue this change actually >> > fixes. >> > > > >>> There are >> > > > >>> > > no >> > > > >>> > > > > > > > > user-supplied strings in what I'm using to generate >> >> ... >> >> read more » >