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 the >>> jQuery >>> > > > > calls. >>> > > > > > > If >>> > > > > > > > > that were the case, then yes it would definitely be my >>> > > > > responsibility >>> > > > > > > to >>> > > > > > > > > properly sanitize it. >>> > >>> > > > > > > > > Have to say this feels like a loss of backward >>> compatibility >>> > > to >>> > > > > me. >>> > > > > > > I've >>> > > > > > > > > got a fair amount of code in this app that uses that >>> technique; >>> > > > > it's >>> > > > > > > already >>> > > > > > > > > inherently messy because of the indirection involved in >>> code >>> > > > > > > generation. >>> > > > > > > > > Wrapping it all in XML calls just adds to the mess. >>> Hope >>> > > there's >>> > > > > a >>> > > > > > > way to >>> > > > > > > > > refine the security fix so that it's confined to the >>> areas that >>> > > > > matter. >>> > >>> > > > > > > > > Cheers, >>> > > > > > > > > Mike >>> > >>> > > > > > > > > On Fri, Jul 23, 2010 at 1:56 PM, mr.freeze < >>> > > nat...@freezable.com> >>> > > > > > > wrote: >>> > >>> > > > > > > > >> It was probably introduced as a security fix. You can >>> do: >>> > > > > > > > >> {{ >>> > > > > > > > >> schartoptions = XML("""{ >>> > > > > > > > >> type: 'bar', >>> > > > > > > > >> barColor: 'green', >>> > > > > > > > >> chartRangeMin: '%d', >>> > > > > > > > >> chartRangeMax: '%d' >>> > > > > > > > >> } >>> > > > > > > > >> """%(chartmin,chartmax)) >>> > > > > > > > >> }} >>> > >>> > > > > > > > >> and it won't be escaped. >>> > >>> > > > > > > > >> On Jul 23, 12:39 pm, Michael Ellis < >>> michael.f.el...@gmail.com >>> > >>> > > > > wrote: >>> > > > > > > > >> > I've got an app with views that generate jQuery code >>> on the >>> > > fly. >>> > > > > > > This >>> > > > > > > > >> was >>> > > > > > > > >> > all working fine until recently, i.e. sometime after >>> 1.92. >>> > > With >>> > > > > > > more >>> > > > > > > > >> recent >>> > > > > > > > >> > builds, single and double quotes in strings are now >>> escaped >>> > > and >>> > > > > it >>> > > > > > > > >> breaks >>> > > > > > > > >> > the javascript. Here's an example >>> > >>> > > > > > > > >> > The view has (with much snipped out): >>> > >>> > > > > > > > >> > {{ >>> > > > > > > > >> > 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}}, >>> > > > > > > > >> {{=schartoptions}} >>> > > > > > > > >> > </script> >>> > >>> > > > > > > > >> > With an earlier web2py, it produces the desired >>> result, >>> > >>> > > > > > > > >> > $("#solution0").sparkline(data.s.solution0, { >>> > > > > > > > >> > type: 'bar', >>> > > > > > > > >> > barColor: 'green', >>> > > > > > > > >> > chartRangeMin: '0', >>> > > > > > > > >> > chartRangeMax: '1' >>> > > > > > > > >> > } >>> > > > > > > > >> > ); >>> > >>> > > > > > > > >> > but now (at tip) I get >>> > >>> > > > > > > > >> > $("#solution0").sparkline(data.s.solution0, { >>> > > > > > > > >> > type: 'bar', >>> > > > > > > > >> > barColor: 'green', >>> > > > > > > > >> > chartRangeMin: '0', >>> > > > > > > > >> > chartRangeMax: '1' >>> > > > > > > > >> > } >>> > > > > > > > >> > ); >>> > >>> > > > > > > > >> > Was this change intentional? If so, what's the >>> recommended >>> > > > > > > workaround? >>> > >>> > > > > > > > >> > Thanks, >>> > > > > > > > >> > Mike >>> >> >> >