Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Perl structure to Javacript-ready JSON

by ikegami (Patriarch)
on Nov 25, 2014 at 16:31 UTC ( [id://1108372]=note: print w/replies, xml ) Need Help??


in reply to Perl structure to Javacript-ready JSON

The following isn't JSON:

{"abc":"abc\'abc"}

What are you trying to do? You might be trying to generate a JavaScript string literal from JSON, but then you'd want something like the following.

'{"abc":"abc\'abc"}'

If that's what you want, you can use the following:

{ my %translations = ( "\r" => "\\r", "\n" => "\\n", "'" => "\\'", "\\" => "\\\\", ); my $meta_chars_class = join '', map quotemeta, keys %translations; my $meta_chars_re = qr/([$meta_chars_class])/; sub text_to_jslit { my $text = shift; $text =~ s/$meta_chars_re/$translations{$1}/g; return "'$text'"; } }

As a Template-Toolkit plugin:

package Template::Plugin::JavaScriptLiteral; use strict; use warnings; use Template::Plugin::Filter qw( ); our @ISA = 'Template::Plugin::Filter'; my %translations = ( "\r" => "\\r", "\n" => "\\n", "'" => "\\'", "\\" => "\\\\", ); my $meta_chars_class = join '', map quotemeta, keys %translations; my $meta_chars_re = qr/([$meta_chars_class])/; sub init { my $self = shift; $self->install_filter('jslit'); return $self; } sub filter { my ($self, $text) = @_; $text =~ s/$meta_chars_re/$translations{$1}/g; return "'$text'"; } 1;

For example,

// PARAMS: { data => { abc => "abc'abc" } } [% USE JSON %] [% USE JavaScriptLiteral %] var json = [% data | json | jslit %]; alert(json); // {"abc":"abc'abc"}

However, one usually wants to assign the JSON to a JS var, not a string representation of it.

// PARAMS: { data => { abc => "abc'abc" } } [% USE JSON %] var data = [% data | json %]; alert(data.abc); // abc'abc

Replies are listed 'Best First'.
Re^2: Perl structure to Javacript-ready JSON
by Jeppe (Monk) on Nov 26, 2014 at 08:21 UTC
    Thanks! I guess my statement was a bit wooly. I'm really trying to do create a javascript literal that I can include like this:
    var data = JSON.parse('{"abc":"abc\'abc"}');
    .. and must therefore escape the string. I've written code that's essentially like in proposal one. Thanks!
      If you know the JSON is valid, var data = {"abc":"abc'abc"}; is equivalent.
        To expand on this ...

        > If you know the JSON is valid

        ...even if there is a doubt about it's validity, he can wrap your approach into a try/catch expression.

        Cheers Rolf

        (addicted to the Perl Programming Language and ☆☆☆☆ :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1108372]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-19 17:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found