Posts

Showing posts with the label perl5

Template Toolkit Debugging inside of Perl Dancer

The other day someone was asking how to enable Template Toolkit debugging inside of Perl Dancer in the #dancer IRC channel, it seemed like a good time for a write up. The template engine configuration directive supports passing through various options like start_tag and stop_tag as explained in Dancer::Template::TemplateToolkit POD. And alludes to being able to pass other options. How To pass TT options like those found in Template::Constants , there must be a DEBUG section in engines -> template_toolkit , usually found in config.yml . Example Snippet Here is an example: A few notes Remove leading DEBUG_ from TT constants. The option DEBUG_PLUGINS becomes plugins . Multiple options can be separated with a comma. Example: DEBUG: "provider,plugins" . Be warned, some of these options can lead to tons of information :) __END__

New CPAN Module: WWW::DirectAdmin::API

New module for interacting with DirectAdmin 's API: WWW::DirectAdmin::API It currently supports User level functions only. More to come later __END__

Accessing Dancer config settings inside of a template

As I continue to work more and more with Perl Dancer , I run into situations where I need to pull in application configuration data inside of the template system. Dancer provides access to this config in your template system with the template token settings . What caught me the other day was my desire to use it in the same way as the in the app's DSL: setting . This was my misreading of the documentation. To access settings in Template Toolkit , you must grab sub areas as hash keys. Example: (you can see this in the generated new app code) App name: [% settings.appname %] I did have a case where I wanted to pull in a value that was located in the plugin section. The plugin (like some of them) are named with double colons (::) and I couldn't get the hash key lookup to work so I used TT 's item virtual method. This example dumps out RSS version: Using RSS Output Version: [% settings.plugins.item('XML::RSS').output %] Disclaimer: Of course in the case of so...

Dancer::Plugin internal sharing

I've been creating quite a few  Dancer  plugins recently. The nice part of a Dancer plugin is that it gives a small new set of keywords. In some cases, I've want to provide a generic keyword interface to an object but then provide smarter business level keywords. I've found a quirk in the Dancer::Plugin interface. I couldn't find it documented anywhere but I'm sure it is. If you want to access keywords from the same space that they are registered you need to use a different format than the: register keyword => sub {}; You need to use the pattern: sub keyword { # do stuff } register keyword => \&keyword; register_plugin actually stuffs the symbols into the namespace therefore you need to share the sub names before that happens to use them.

Perl Module Versions in dotcloud

I just realized that I was running an older version in my dotcloud service. There was an update due to a security issue so it was kind of important. I found that I needed to update (or put) a version number in the Makefile.PL . Here is an example of mine. Before: use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'leecarmichael', AUTHOR => q{Lee Carmichael }, VERSION_FROM => 'lib/leecarmichael.pm', ABSTRACT => 'Home Site', ($ExtUtils::MakeMaker::VERSION >= 6.3002 ? ('LICENSE'=> 'perl') : ()), PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, 'YAML' => 0, 'XML::RSS' => 0, 'URI' => 0, 'Date::Parse' => 0, 'Digest::MD5' => 0, 'Plack' => 0, ...

Making sure dotcloud serves static files not Dancer

Dancer is a great framework. It does a great job making a default development work out of the box. Its a nice alternative to some of the heavier ones that require quite a bit of setup (actually most Perl web frameworks do a great job of this). Also it makes sure to serve static content (to avoid deployment issues, I assume). But compared to nginx or apache it is much slower at serving this (not a big surprise). In my dotcloud deployments I've found this to be a bit confusing to make sure nginx handles it instead of Dancer . My first pass at this was setting up these symlinks in my source tree: static/css --> ../public/css static/javascripts --> ../public/javascripts and such. It felt wrong to have this inside source control so I dug around a bit and ran into the postinstall script that is supported by the deploy dotcloud command option. I added the following link commands to mine to create those nice symlinks: #!/bin/sh # used for dotcloud deployment...

nginx include(s)

As part of my ongoing exploration with dotcloud , I've had to do a bit of learning about nginx . I've never worked with nginx before but i needed to add some rewrite rules into my dotcloud deployment. I wanted to make sure that static content like images and css files where being served by the nginx instead of my app ( Dancer is pretty nice about making sure public content gets served during requests ). I found that after changing a nginx include that the server needs to be restarted or reloaded after a change to the include. I spent a few hours trying to figure out if a restart was required since I wasn't sure if I had screwed up the rules due to a bug (now fixed) with dotcloud deployment not restarting it after a push as expected for Perl deployments. dotcloud provides server restart as: udo /etc/init.d/nginx restart __END__

My First Custom Dancer app deployment on dotcloud

I'm in the process of rewriting my site www.leecarmichael.com . I really wanted a reason to build a small but real app with (Perl) Dancer . I really like most of Dancer 's approach to routing and layout. It fits well with my way of thinking of web apps. At the same time I stumbled onto Dot Cloud , a very well thought out and incredible nice deployment provider. They are part of the current cloud shift in which individual application stack layers are hosted instead of a full OS stack. Here are the few gotchas that I found: They deploy using PSGI and Plack, very cool. But its deployed with an environment of 'deployment'. This means you must have a deployment configuration file. Example: application_root /environments/deployment.yml . I found this confusing since i expected it to follow the Dancer approach of production (my own bad assumption) Unfortunately, runtime errors are not logged to the standard web server error log (or anywhere else). Therefore you need t...

Using Dancer's Request HTTP Env shortcuts

As I was working on a small application that allowed editing of pages, I really wanted to grab the referring page to redirect after the page was updated or the edit session was cancelled by the user. It wasn't very clear to me how to grab the referer from Dancer 's POD documentation on Dancer::Request . Basically I could grab it either of 2 ways. request->referer - nice. This applies to other env options as well forwarded_for_address which pulls in X_FORWARDED_FOR request->env->{HTTP_REFERER} - feels more lower level. I read the documentation as request->env->{referer} which is not correct at all. In the end it is much easier and I think prettier than the several options I tried :) __END__

Dancer and TT config

Quick note to self (and anyone that might be listening): When setting config options different than start and end tag for TT such as PRE_PROCESS in Dancer , you must make them all caps. e.g. config.yaml: # template engine template: "template_toolkit" engines: template_toolkit: encoding: 'utf8' start_tag: '[%' end_tag: '%]' PRE_PROCESS: 'config.tt'

Mouse and Moose in Perl - Walking in a winter wonderland... kinda

I like Moose but I work heavily in non-persistent applications. Sadly this makes Moose 's start up expense too much. But recently I revisited Mouse (thanks to a friend). The last time I looked at it, I misread the documentation and it sounds like it was no longer being supported by the original developer. But not anymore, w00t! The one part I really like about Mouse (and Moose) is the declarative nature of creating accessors (and therefore attributes). I really like this because it reduces the number of simple accessor tests that you need to write (saving time, tendium and kittens). I used to use Class::Accessor but I always ran into inheritance and validation issues (which I used Params::Validate but this caused lots of custom magic for inheritance). I think the Mouse / Moose syntax is significantly cleaner. Compare Class::Accessor: package User; use strict; use warnings; use Carp; use base qw( Class::Accessor ); __PACKAGE__->mk_accessors( qw( id username pass...

A journey through whitespace cleanup - Perl5 and split

Running through some older Perl5 code, I found someone using grep with a split to cleanup white space on some incoming data. Found, this seemed confusing to me with lots of extra complexity: my @line = grep { s/\s*$// } split /\|/, $_; First Pass: my @line = split /\|\s*/, $_; But my guess is that all wrapping white space should be removed: my @line = split /\s*\|\s*/, $_; Even better (and more readable), use the Perl magic context: my @line = split /\s*\|\s*/; I would love to make that a cleaner regex but that will have to be another day...

Super Sweet CSV parsing with Perl

Today, everyday, every other day I need to pull in CSV files and write others out. After awhile, I was ready for a better solution. Lucky for me, the Perl community is amazing. For some amazing parsing options look no further than Text::CSV_XS , it provides a super sweet parsing interface. No talking just pure Perl code: use strict; use warnings; use Text::CSV_XS; my $csv = Text::CSV_XS->new( {eol => "\n"} ); # eol has nothing to do with parsing wait until later :) my $input = shift || die "Missing filename\n"; open my $fh, ' or die "Failed to open $input: $!\n"; # assume no file header while ( my $columns = $csv->getline($fh) ) { print $columns->[0], $columns->[1], "\n"; # or whatever you want to do } close $csv; That's for parsing. You can do some other super cool stuff too, with bind_columns . Lets' assume the file has the format of 'first name, last name, email address'. Here the parsing loop updated ...

Recommended way to build URLs in Template Toolkit

On the mailing list, Andy Wardey recommended using the URL plugin as the best way to build URLs in Template Toolkit (TT) . Since this is very helpful but sometimes hard to dig out of the TT documentation, I wanted to make a quick note here. The URL plugin will make sure to properly HTML and URI encode your link(s). Here my quick example In your template: [% USE profile = URL( '/profile', show_picture = 1 ) %] <a href="[% profile( slayer = 'buffy' ) %]">Buffy's Profile</a> <a href="[% profile( vampire = 'spike' ) %]">Spike's Profile</a> This will render validly encoded html like: <a href="/profile?show_picture=1&amp;slayer=buffy">Buffy's Profile</a> <a href="/profile?show_picture=1&amp;vampire=spike">Spike's Profile</a> Notice the & not a '&' which makes the html validation much happier. This is much easier than trying to do it yourse...

perltidy and block labels

perltidy has its own mind at times. Most of the time, its mind is better than my hands reformatting code. But I've been writing lots of test code recently and found that I use blocks and labels, along with nested blocks with labels. Stuff that looks like: USER: { my $shared_db_thingy = create_db_thingy( %params ); SKIP: { # create user tests skip 'DB Thingy not created', $test_count unless $shared_db_thingy; lives_ok { $shared_db_thingy->create_user( %user_parameters ) } 'create_user'; } SKIP: { # retrieve user tests } } Frustratingly, perltidy likes to tidy this into: USER: { SKIP: { } SKIP: { } } I had to do some real digging into perltidy to find the -ola that outdents labels. Setting the -nola fixes it. And doesn't having any (seen) side effects. w00t!

vim productive note

When writing tests for Perl objects (or modules), I like to store the name of the module in a named buffer/register in vim. I usually visually highlight the object(or module) name, then put it in the "n" buffer. Yank into n: "ny Paste out of n: "np I guess the m or n buffer might make sense. If you forget like I do what buffer your using you can dump them in vim with: registers So it was...

3 ways to disable auto typing in SOAP::Lite client

Often SOAP::Lite will try to autotype a parameter in a request and it does it wrongly (or correctly) causing the SOAP server to fail badly (for so many reasons). SOAP::Lite provides three ways to disable this typing. Two of the ways work at the client object level and the other does it at the SOAP::Data object level. Client Level The following options disable autotyping for all data items in a request: autotype method. After creating a SOAP::Lite client you can disable autotyping by $soapclient->autotype(0) . Example: my $soap = SOAP::Lite->uri($xmlns)->proxy($proxy) ->on_action( sub {"$action?type=$reqname&ns=$xmlns"} ); $soap->autotype(0); Overriding the typelookup method. You can override the typelookup to run undef/false/etc. Example: sub typelookup { return undef; } Data object SOAP::Data object provide a type method. This allows manually typing of the object. When this is set to an empty string no type is set nor is it autotyped by serializer. No...

Template Toolkit virtual methods with less mess

Template Toolkit has a very cool feature called Virtual Methods . It provide methods on native Perl5 data types. An example is this (In TT syntax): [% listy = [ 47, -47, 42, -55, 4, -24 ] %] [% listy.size %] [% listy.join(', ') %] Often its called autoboxing . Well TT allows you to define your own. The details are available in the TT VMethod Manual . In that page there is a TODO about a method called define_vmethod . Since I like to use TT from CGI::Application and I don't like to actually see its guts. I choose to find a way to add a vmethod without the unpretty $Template::Stash::LIST_OPS->{} syntax. I think that is quite unfriendly to TT noobs like most of my coworkers. I found that define_vmethod is available off the TT Context object. This is available with $tt->context or in my case off plugin TT object in CGI App $self->tt_obj->context . The parameters are context->define_vmethod( $type, $name, \&implementation ) $type - data type, 'scalar...