Skip to content

Commit

Permalink
feature/configurable plugin system (#286)
Browse files Browse the repository at this point in the history
* add configurable plugin system

* add missing new line

* run tests

* cleanup code

* more readable plugin example

* update doc/README for plugin
  • Loading branch information
mziescha authored and ufobat committed Dec 31, 2017
1 parent 8ca2987 commit d63d1a6
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,3 +2,4 @@
/data/
.precomp
.idea/
lib/Bailador/tmp*
1 change: 1 addition & 0 deletions META6.json
Expand Up @@ -65,6 +65,7 @@
"Bailador::Log" : "lib/Bailador/Log.pm",
"Bailador::Log::Adapter" : "lib/Bailador/Log/Adapter.pm",
"Bailador::Log::Formatter" : "lib/Bailador/Log/Formatter.pm",
"Bailador::Plugins" : "lib/Bailador/Plugins.pm",
"Bailador::Request" : "lib/Bailador/Request.pm",
"Bailador::Request::Multipart" : "lib/Bailador/Request/Multipart.pm",
"Bailador::Response" : "lib/Bailador/Response.pm",
Expand Down
22 changes: 22 additions & 0 deletions doc/README.md
Expand Up @@ -19,6 +19,7 @@
- [`redirect(Str $location)`](#redirectstr-location)
- [`renderer(Bailador::Template $renderer)`](#rendererbailadortemplate-renderer)
- [`config()`](#config)
- [`plugins()`](#plugins)
- [`set(Str $key, $value)`](#setstr-key-value)
- [`baile()`](#baile)
- [Subroutines that should only be used inside the Code block of a Route](#subroutines-that-sould-only-be-used-inside-the-code-block-of-a-route)
Expand Down Expand Up @@ -207,6 +208,23 @@ Sets the Renderer that's being used to render your templates. See the [Templates
Returns the configuration. You can influence how sessions work, the mode, port and host of your Bailador app.
See the [Sessions](#sessions) and [Configuration](#configuration) sections for details.

#### `plugins()`

Returns the object from the collection class Bailador::Plugins it contains all configured and loaded plugins.
See [Configuration](#configuration) sections for how to configure a plugin.
Following methods are available:

```perl6
# public method to add a plugin on runtime.
app.plugins.add('Example', Bailador::Plugin::Example.new(config => {param => 'Test'}) );

# public method to get a plugin by name
app.plugins.get('Example');

# public method to detect configured plugins and add it to collection via the containing public method add
app.plugins.detect(app.config);
```

#### `set(Str $key, $value)`

This is a simple way to set values in the config.
Expand Down Expand Up @@ -417,6 +435,10 @@ For now, Bailador only allows you to use YAML formatted configuration files. The
# settings.yaml
mode: "development"
port: 8080

plugins:
Example:
foo: bar
```

Bailador will now generate 2 more config file variants and process the settings from there. In our example `settings-local.yaml` and, depending on our `config.mode` which is development, a file named `settings-development.yaml`. If our mode was production Bailador would have used `settings-production.yaml`.
Expand Down
17 changes: 17 additions & 0 deletions examples/plugins/app.pl
@@ -0,0 +1,17 @@
#!/usr/bin/env perl6

use v6.c;
use lib 'lib';
use lib 'examples/plugins/lib';
use Bailador;
use Bailador::Plugin::Example;
use Data::Dump;

get '/' => sub {
template 'index.tt', {
title => 'Plugin Example',
plugin_text => app.plugins.get('Example').sample
};
}

baile();
14 changes: 14 additions & 0 deletions examples/plugins/lib/Bailador/Plugin/Example.pm
@@ -0,0 +1,14 @@
use v6.c;

use Bailador::Plugins;

class Bailador::Plugin::Example:ver<0.001000> is Bailador::Plugin {

method sample{

# Because of the inheritage from Bailador::Plugin
# %.config the config for this plugin Example is available.
my $param = %.config{'param'};
return 'Hello I am a sample!';
}
}
4 changes: 4 additions & 0 deletions examples/plugins/settings.yaml
@@ -0,0 +1,4 @@

plugins:
Example:
param: 1
17 changes: 17 additions & 0 deletions examples/plugins/views/index.tt
@@ -0,0 +1,17 @@
% my ($h) = @_;
<!DOCTYPE html>
<html>
<head>
<title>Bailador App</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.3/handlebars.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<h1>Bailador App</h1>
<div>
Version <%= $h<version> %>
</div>
</body>
</html>
6 changes: 4 additions & 2 deletions lib/Bailador/App.pm
Expand Up @@ -13,6 +13,7 @@ use Bailador::Context;
use Bailador::Exceptions;
use Bailador::Log::Adapter;
use Bailador::Log::Formatter;
use Bailador::Plugins;
use Bailador::Route;
use Bailador::Route::AutoHead;
use Bailador::Sessions;
Expand All @@ -28,6 +29,7 @@ class Bailador::App does Bailador::Routing {
has Bailador::Sessions $!sessions;
has Bailador::Configuration $.config = Bailador::Configuration.new;
has Bailador::Commands $.commands = Bailador::Commands.new;
has Bailador::Plugins $.plugins = Bailador::Plugins.new;
has Bailador::Log::Adapter $.log-adapter = Bailador::Log::Adapter.new;
has %.error_handlers;

Expand Down Expand Up @@ -137,7 +139,6 @@ class Bailador::App does Bailador::Routing {
# Configure logging system
use Bailador::Log;
init( config => self.config, p6w-adapter => self.log-adapter );

self!generate-head-routes(self);
}

Expand Down Expand Up @@ -275,6 +276,7 @@ class Bailador::App does Bailador::Routing {
} else {
die 'cannot detect command';
}

self.baile($command);
}

Expand All @@ -285,11 +287,11 @@ class Bailador::App does Bailador::Routing {

$.config.load-from-args(@args);
my $cmd = $.commands.get-command($command);

die 'can only baile once' if $!started;
$!started = True;

$.before-run();
$.plugins.detect($!config);
$cmd.run(app => self );
}

Expand Down
1 change: 1 addition & 0 deletions lib/Bailador/Configuration.pm
Expand Up @@ -18,6 +18,7 @@ class Bailador::Configuration {
has Int $.port is rw = 3000;
has Str $.views is rw = 'views';
has Str $.layout is rw;
has Hash $.plugins is rw;

# https and tls stuff
has Bool $.tls-mode is rw = False;
Expand Down
30 changes: 30 additions & 0 deletions lib/Bailador/Plugins.pm
@@ -0,0 +1,30 @@
use v6.c;

use Bailador::Configuration;

role Bailador::Plugin {
has %.config;
}

class Bailador::Plugins {
has %!plugins = {};

method add(Str:D $name, Bailador::Plugin:D $plugin) {
%!plugins.{$name} = $plugin;
}

method get(Str:D $name) {
return %!plugins.{$name};
}

method detect(Bailador::Configuration $config) {
for $config.plugins.keys -> $name {
my $plugin_conf= $config.plugins{$name};
my $package = 'Bailador::Plugin::' ~ $name;
try {
require ::($package);
$.add($name, ::($package).new(config => $plugin_conf));
}
}
}
}

0 comments on commit d63d1a6

Please sign in to comment.