plerd-cli - an interactive tool for Plerd


My self-imposed Twitter exile has already paid off with the creation of this little program: plerd-cgi. This is designed to be an interactive tool to “manage” your plerd instance. Currently, the tool can regenerate all your content or from your sources directory or just a single post. This is very helpful when you are on the host running plerd and you are changing stylesheets or other settings.

I will ping the plerd development team (hi, Jmac) and see if there is interest in adding this tool to the plerd/bin directory (which is where I have it).

Increasing, my version of plerd is drifting from the released version. When plerd gets tags (jmac’s re-implementation of a feature I contributed), then I will try to merge these codebases together again.

From previous post, you can see that I am experimenting with managing photos. Plerd’s killer feature is its integration with Dropbox. This really enables a powerful and flexible blogging platform for those used to composing in text editors, like me.

#!/usr/bin/env perl

use warnings;
use strict;

use FindBin;
use lib ("$FindBin::Bin/../lib");

use Cwd ('abs_path');
use File::Basename;
use Getopt::Long;
use Path::Class::File;
use YAML qw( LoadFile );

use Plerd;

our %gKnownCommands =
    ('regen_all' => \&cmd_regenerate_all, 'regen' => \&cmd_regenerate_file, 'help' => \&cmd_help);


# Subs
sub main {
    my $opts = usage();

    my $plerd = init_plerd();

    # Only do one command
    while (my ($command, $action) = each %gKnownCommands) {
        if (defined $opts->{$command}) {
            return $action->($plerd, $opts);

} # end sub main

sub usage {
    my %opts;

        "help"        => \$opts{help},
        "R|regen-all" => \$opts{regen_all},
        "r|regen:s"   => \$opts{regen},
        "v|verbose"   => \$opts{verbose},

    if ($opts{help}) {

    my $has_command = 0;
    for my $command (keys %gKnownCommands) {
        $has_command |= defined $opts{$command};

    if (!$has_command) {
        die("No command given.  See --help for details.\n");

    return \%opts;
} # end sub usage

sub dump_usage {
    print <<"EOT";
$0 - command line interface to plerd


  $0 [OPTIONS]


  --help           # this screen
  --verbose        # provide more verbose output
  --regen-all      # regenerate all HTML files from known sources
  --regen FILE     # regenerate just this source file


} # end sub dump_usage

sub init_plerd {
    my ($opts) = @_;

    my $conf_file = "$FindBin::Bin/../conf/plerd.conf";
    if (!-e $conf_file) {
        die("Cannot find '$conf_file'\n");

    my $config_ref = LoadFile($conf_file);
    my $plerd      = Plerd->new($config_ref);

    return $plerd;
} # end sub init_plerd

sub cmd_help {
    my ($plerd, $opts) = @_;
} # end sub cmd_help

sub cmd_regenerate_all {
    my ($plerd, $opts) = @_;

    my $start = time();
    if ($opts->{verbose}) {
        print("Regenerating all content.  This may take a while.\n");


    if ($opts->{verbose}) {
        printf("Regeneratation completed in %0.2f minutes.\n", (time() - $start) / 60);

} # end sub cmd_regenerate_all

sub cmd_regenerate_file {
    my ($plerd, $opts) = @_;

    my $source_file = abs_path($opts->{regen});

    if (!-e $source_file) {
        die("Cannot find '$source_file'\n");

    # is the source file within the source_directory?
    my $dirname = dirname($source_file);
    if ($dirname ne $plerd->source_directory) {
                "File '%s' does not appear to be in the source directory '%s'\n",
                $source_file, $plerd->source_directory

    if ($opts->{verbose}) {
        print("Publishing '$source_file'\n");

    my $post = Plerd::Post->new(
        source_file => Path::Class::File->new($source_file),
        plerd       => $plerd
    eval {
    } or do {
        die(sprintf("Could not publish '%s': %s\n", $source_file, $@));

    # Publishing this new post triggers updates on these other pages
    for my $action (
        'publish_tag_indexes', 'publish_archive_page',
        'publish_recent_page', 'publish_rss',
    ) {
        if ($opts->{verbose}) {
            print("-> $action\n");

    if ($opts->{verbose}) {
        printf("View your new post here: %s\n", $post->uri);

} # end sub cmd_regenerate_file

UPDATE: I spoke to Jmac about this and he pointed out his intention for the exisiting plerdall program to fill this niche. Additionally, the publish all functionality is already there. So I will talk a crack at porting what I have here when I am up and running with the current tip of plerd.