We have already seen a few examples for SVG with Perl, and we had a few articles using PSGI. Let's combine the two. This will make it easier to play with SVG as we can see our results immediately.

This is the basic script:

examples/svg.psgi

#!/usr/bin/perl
use strict;
use warnings;


use SVG;
 
my $app = sub {
    my $svg = SVG->new(
        width  => 200,
        height => 200,
    );
    $svg->title()->cdata('I am a title');

    # add a circle
    my $red = $svg->circle(
        cx => 100,
        cy => 100,
        r  => 50,
        id => 'red_circle',
        #style => {
        #    'fill'         => '#FF0000',
        #    #'fill-opacity' => 0.5,
        #}
    );

    return [
        '200',
        [ 'Content-Type' => 'image/svg+xml' ],
        [ $svg->xmlify ],
    ];
};

You can run it using plackup -r svg.psgi

it will print this to the console:

Watching ./lib svg.psgi for file updates.
HTTP::Server::PSGI: Accepting connections at http://0:5000/

and then you can visit the page at http://127.0.0.1:5000/

You will see a black circle.

black circle

Now edit the svg.psgi file removing the # from the lines, (for now keep the fill-opacity line commented out), and then reload the page. You don't even need to stop and restart the script as plackup using the -r flag will automatically reload the script after you saved it.

The page now shows a red circle.

red circle

Then, as another example, let's remove the # from the 'fill-opacity' => 0.5, line as well. The results in the following:

red circle

You can then go on, make changes to the Perl script and keep checking the result in your browser.

Explanation

A little explanation might be needed. PSGI requires that the application return a 3-element array reference. The first element is the HTTP status code. In our example that's 200 meaning everything is fine. The second element is the header. Here we set the Content-type to be image/svg+xml. This will tell the browser what to do with the content we are sending as the 3rd element which, in our case, is the XML generated by the SVG module.