Skip to content

Commit

Permalink
Add enough code so this module becomes usable.
Browse files Browse the repository at this point in the history
  • Loading branch information
racke committed May 8, 2011
1 parent 5727b79 commit 7affa4d
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 17 deletions.
1 change: 1 addition & 0 deletions MANIFEST
Expand Up @@ -3,6 +3,7 @@ MANIFEST
Makefile.PL
README
lib/Dancer/Plugin/Wiki/Toolkit.pm
lib/Dancer/Plugin/Wiki/Toolkit/Object.pm
t/00-load.t
t/manifest.t
t/pod-coverage.t
Expand Down
3 changes: 3 additions & 0 deletions Makefile.PL
Expand Up @@ -13,6 +13,9 @@ WriteMakefile(
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
'Wiki::Toolkit' => 0,
'Dancer' => 0,
'Dancer::Plugin::Database' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Dancer-Plugin-Wiki-Toolkit-*' },
Expand Down
176 changes: 159 additions & 17 deletions lib/Dancer/Plugin/Wiki/Toolkit.pm
Expand Up @@ -3,49 +3,191 @@ package Dancer::Plugin::Wiki::Toolkit;
use warnings;
use strict;

use Dancer ':syntax';
use Dancer::Plugin;
use Dancer::Plugin::Database;

use Wiki::Toolkit;
use Dancer::Plugin::Wiki::Toolkit::Object;

=head1 NAME
Dancer::Plugin::Wiki::Toolkit - The great new Dancer::Plugin::Wiki::Toolkit!
Dancer::Plugin::Wiki::Toolkit - Wiki::Toolkit plugin for Dancer
=head1 VERSION
Version 0.01
Version 0.0001
=cut

our $VERSION = '0.01';
our $VERSION = '0.0001';


=head1 SYNOPSIS
Quick summary of what the module does.
use Dancer;
use Dancer::Plugin::Wiki::Toolkit;
=head1 CONFIGURATION
Perhaps a little code snippet.
=over 4
use Dancer::Plugin::Wiki::Toolkit;
=item C<db_connection_name> (optional)
my $foo = Dancer::Plugin::Wiki::Toolkit->new();
...
We use L<Dancer::Plugin::Database> to obtain database connections. This option
allows you to specify the name of a connection defined in the config file to
use. See the documentation for L<Dancer::Plugin::Database> for how multiple
database configurations work. If this is not supplied or is empty, the default
database connection details in your configuration file will be used - this is
often what you want, so unless your application is dealing with multiple
databases, you probably won't need to worry about this option.
=head1 EXPORT
=back
=head2 DEFINING FORMATTERS
L<Wiki::Toolkit> can use more than one formatter at the same time.
A list of functions that can be exported. You can delete this section
if you don't export anything, such as for a purely object-oriented module.
Parameters can be passed to the formatters as follows:
Wiki::Toolkit:
formatters:
UseMod:
extended_links: 1
allowed_tags: [pre]
=head1 SUBROUTINES/METHODS
=head2 function1
=head2 wiki
=cut

sub function1 {
my $wiki_tk_obj;

sub _setup_wiki_toolkit {
my ($driver, $class, $settings, $store_object);

# retrieve settings
$settings = plugin_setting;

# determine database driver
$driver = database->{Driver}->{Name};

# check whether Wiki::Toolkit supports this driver
if ($driver eq 'mysql') {
$class = 'Wiki::Toolkit::Store::MySQL';
}
elsif ($driver eq 'Pg') {
$class = 'Wiki::Toolkit::Store::Pg';
}
elsif ($driver eq 'SQLite') {
$class = 'Wiki::Toolkit::Store::SQLite';
}
else {
Dancer::Logger::error("Database driver unsupported by Wiki::Toolkit: " . $driver);
return;
}

# create an storage object
eval "require $class";

if ($@) {
die "Failed to load $class: $@\n";
}
eval {
$store_object = $class->new(dbh => database)
};
if ($@) {
die "Failed to instantiate $class: $@\n";
}

# now formatters
my (@formatters, $fmt_object, $object, %parms);

if (exists $settings->{formatters}) {
if (ref($settings->{formatters}) eq 'HASH') {
@formatters = keys(%{$settings->{formatters}});
}
else {
@formatters = split(',', $settings->{formatters});
}

for (@formatters) {
my $fmt;

$fmt->{class} = "Wiki::Toolkit::Formatter::$_";
$fmt->{options} = $settings->{formatters}->{$_} || {};

$object = _load_formatter($fmt, $store_object);
$parms{$_} = $object;
}

if (@formatters > 1) {
require Wiki::Toolkit::Formatter::Multiple;

$fmt_object = Wiki::Toolkit::Formatter::Multiple->new(%parms);
}
else {
$fmt_object = $object;
}
}

# finally object
$wiki_tk_obj = Wiki::Toolkit->new(store => $store_object,
formatter => $fmt_object);

# register Wiki::Toolkit plugins
# ...

bless $wiki_tk_obj, 'Dancer::Plugin::Wiki::Toolkit::Object';
}

=head2 function2
=cut

sub function2 {
register wiki => sub {
my ($arg, %opts) = @_;

unless ($wiki_tk_obj) {
# setup Wiki::Toolkit object
_setup_wiki_toolkit();
}

$opts{function} ||= 'display';

if ($opts{function} eq 'save') {
return $wiki_tk_obj->modify_page($arg, $opts{content}, $opts{checksum});
}

# display page
return $wiki_tk_obj->display_page($arg, $opts{version}, $opts{format});
};

register_plugin;

sub _load_formatter {
my ($fmt, $store_object) = @_;
my ($edit_prefix);

eval "require $fmt->{class}";
if ($@) {
die "Failed to load $fmt->{class}: $@\n";
}

# we are passing an empty string to node_prefix to override the
# default of the formatter in order to use <wiki>/MyPage URL for
# MyPage

eval {
$edit_prefix = join('&amp;', '?action=edit', 'page=');
$fmt->{object} = $fmt->{class}->new (store => $store_object,
node_prefix => '',
edit_prefix => $edit_prefix,
%{$fmt->{options}});
};
if ($@) {
die "Failed to instantiate $fmt->{class}: $@\n";
}

return $fmt->{object};
}

=head1 AUTHOR
Expand Down
105 changes: 105 additions & 0 deletions lib/Dancer/Plugin/Wiki/Toolkit/Object.pm
@@ -0,0 +1,105 @@
package Dancer::Plugin::Wiki::Toolkit::Object;

use warnings;
use strict;

use Wiki::Toolkit;
use base qw(Wiki::Toolkit);

# defaults
use constant FRONT_PAGE => 'FrontPage';

=head1 NAME
Dancer::Plugin::Wiki::Toolkit::Object;
=head1 DESCRIPTION
Subclassed Wiki::Toolkit::Object with added convenience methods.
=cut

=head1 METHODS
=head2 list_pages
List available pages.
=cut

sub list_pages {
my ($wiki_object, $metadata) = @_;
my (@pages);

if ($metadata) {
@pages = $wiki_object->list_nodes_by_metadata(%$metadata);
}
else {
@pages = $wiki_object->list_all_nodes();
}

return @pages;
}

=head2 display_page
Displays page with the name PAGE.
=cut

sub display_page {
my ($wiki_object, $page, $version, $format) = @_;
my (%node);

$page ||= FRONT_PAGE;

if ($wiki_object->node_exists($page)) {
if ($version) {
%node = $wiki_object->retrieve_node({name => $page, version => $version});
} else {
%node = $wiki_object->retrieve_node($page);
}
}
else {
# dummy node
%node = (content => '', checksum => undef, metadata => {});
}

unless (defined $format && $format eq 'raw') {
my $ret;

$ret = $wiki_object->format($node{content}, $node{metadata});

return $ret;
}

# just return whole node
return %node;
}

=head2 modify_page
Creates or modifies page.
=cut

sub modify_page {
my ($wiki_object, $page, $content, $checksum, $metadata) = @_;
my ($ret);

$page ||= FRONT_PAGE;

if (defined $checksum && $checksum !~ /\S/) {
$checksum = undef;
}

$ret = $wiki_object->write_node($page, $content, $checksum, $metadata);

unless ($ret) {
die "Conflict editing node $page.";
}

return 1;
}

1;

0 comments on commit 7affa4d

Please sign in to comment.