Skip to content

Instantly share code, notes, and snippets.

@anazawa
Created November 21, 2012 09:06
Show Gist options
  • Select an option

  • Save anazawa/4123914 to your computer and use it in GitHub Desktop.

Select an option

Save anazawa/4123914 to your computer and use it in GitHub Desktop.
Blosxom plugin: json
package js;
use strict;
use warnings;
use parent 'Blosxom::Plugin::Web';
use Carp qw/croak/;
use Encode;
use HTTP::Date qw/time2isoz/;
our $VERSION = '0.01';
our ( $callback, $updated_at );
sub start {
my $self = shift;
$self->merge_data_section_into( \%blosxom::template );
$blosxom::flavour eq $self;
}
sub head {
my $self = shift;
my $handler = $self->request->param('callback') || 'handleFeed';
if ( $handler =~ /^[a-zA-Z0-9\.\_\[\]]+$/ ) {
$callback = $handler;
}
else {
croak "Invalid callback parameter '$handler'";
}
my @strings = do {
package blosxom;
\( $blog_title, $blog_description, $blog_language );
};
_encode( $_ ) for @strings;
return;
}
sub date { $updated_at = time2isoz($_[3]) }
sub story { _encode($_) for @_[4, 5] }
sub end { undef $callback; $_[0]->SUPER::end }
# copied and rearranged from JSON::PP
my $utf8 = find_encoding( 'utf-8' );
my %escape = (
"\n" => '\n', "\r", => '\r', "\t" => '\t', "\f", => '\f',
"\b" => '\b', "\"", => '\"', "\\" => '\\\\', "\'" => '\\\'',
);
sub _encode {
my $ref = shift;
my $str = $utf8->decode( $$ref );
$str =~ s/([\x22\x5c\n\r\t\f\b])/$escape{$1}/g;
$str =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
# encode ascii
$str = join('',
map {
$_ <= 127 ?
chr($_) :
$_ <= 65535 ?
sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
} unpack('U*', $str)
);
$$ref = $utf8->encode( $str );
return;
}
sub _encode_surrogates { # from perlunicode
my $uni = $_[0] - 0x10000;
return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00);
}
1;
__DATA__
@@ content_type.js
text/javascript
@@ head.js
$js::callback({
version: "$js::VERSION",
generator: "blosxom/$version",
feed: {
title: "$blog_title",
link: "$url",
description: "$blog_description",
language: "$blog_language",
entries: [
@@ date.js
@@ story.js
{
title: "$title",
link: "$url$path/$fn.$default_flavour",
content: "$body",
updated_at: "$js::updated_at",
},
@@ foot.js
],
},
});
package json;
use strict;
use warnings;
use parent 'Blosxom::Plugin::Web';
use Carp qw/croak/;
use CGI::Header;
use JSON;
__PACKAGE__->mk_accessors(
header => sub { CGI::Header->new($blosxom::header) },
feed => sub {
package blosxom;
return +{
title => $blog_title,
description => $blog_description,
language => $blog_language,
link => $url,
entries => [],
};
},
);
sub start {
my $self = shift;
$self->merge_data_section_into( \%blosxom::template );
$blosxom::flavour eq $self;
}
sub story {
my ( $self, $path, $fn, $story, $title, $body ) = @_;
push @{ $self->feed->{entries} }, {
title => $$title,
link => "$blosxom::url$path/$fn.$blosxom::default_flavour",
body => $$body,
};
}
sub last {
my $self = shift;
$self->header->set( 'Access-Control-Allow-Origin' => '*' );
$blosxom::output = to_json( $self->feed );
return;
}
1;
__DATA__
@@ content_type.json
application/javascript
@@ head.json
@@ story.json
@@ date.json
@@ foot.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment