Make doc navigation extensible

Change-Id: I6fffb2e33439d6c539d05bb65a3b81d4e2267f57
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 8cf581f..ef8dab7 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -78,11 +78,8 @@
       });
   };
 
-  # Load Kalamar configuration
-  my $kalamar_conf = $self->config('Kalamar');
-
   # Check for API endpoint and set the endpoint accordingly
-  if ($kalamar_conf->{api}) {
+  if ($conf->{api}) {
 
     # The api endpoint should be defined as a separated path
     # and version string
@@ -94,14 +91,14 @@
 
   # Set from environment variable
   elsif ($ENV{'KALAMAR_API'}) {
-    $kalamar_conf->{api} = $ENV{'KALAMAR_API'};
+    $conf->{api} = $ENV{'KALAMAR_API'};
   }
 
   # API is not yet set - define
   else {
 
-    $kalamar_conf->{api} =
-      Mojo::URL->new($kalamar_conf->{api_path})->path('v' . ($kalamar_conf->{api_version} // $API_VERSION) . '/')->to_string;
+    $conf->{api} =
+      Mojo::URL->new($conf->{api_path})->path('v' . ($conf->{api_version} // $API_VERSION) . '/')->to_string;
   };
 
   # Add development path
@@ -193,7 +190,13 @@
 
   # Configure documentation navigation
   my $navi = Mojo::File->new($self->home->child('templates','doc','navigation.json'))->slurp;
-  $self->config(navi => decode_json($navi)) if $navi;
+  $navi = $navi ? decode_json($navi) : [];
+
+  if ($conf->{navi_ext}) {
+    push @$navi, @{$conf->{navi_ext}};
+  };
+
+  $self->config(navi => $navi);
 
   $self->log->info('API expected at ' . $self->config->{Kalamar}->{api});
 
@@ -211,8 +214,8 @@
 
   # Documentation routes
   $r->get('/doc')->to('documentation#page', page => 'korap')->name('doc_start');
-  $r->get('/doc/:page')->to('documentation#page', scope => undef);
-  $r->get('/doc/*scope/:page')->to('documentation#page')->name('doc');
+  $r->get('/doc/:page')->to('documentation#page')->name('doc1');
+  $r->get('/doc/*scope/:page')->to('documentation#page')->name('doc2');
 
   # Contact route
   $r->get('/contact')->to('documentation#contact');
diff --git a/lib/Kalamar/Controller/Documentation.pm b/lib/Kalamar/Controller/Documentation.pm
index ab314b4..7444d57 100644
--- a/lib/Kalamar/Controller/Documentation.pm
+++ b/lib/Kalamar/Controller/Documentation.pm
@@ -27,11 +27,14 @@
   );
 
   # Render template
-  return $c->render(
-    sidebar_active => 1,
-    main_class     => 'tutorial',
-    documentation => 1,
-    template       => $c->loc('Template_' . join('_', @path), join('/', @path))
+  $c->stash(sidebar_active => 1);
+  $c->stash(main_class => 'tutorial');
+  $c->stash(documentation => 1);
+
+  return $c->render_maybe(
+    template => $c->loc('Template_' . join('_', @path), join('/', @path))
+  ) || $c->render(
+    template => $c->loc('Template_' . join('_', 'custom', @path), join('/', 'custom', @path))
   );
 };
 
diff --git a/lib/Kalamar/Plugin/KalamarHelpers.pm b/lib/Kalamar/Plugin/KalamarHelpers.pm
index f5e995b..85c65bf 100644
--- a/lib/Kalamar/Plugin/KalamarHelpers.pm
+++ b/lib/Kalamar/Plugin/KalamarHelpers.pm
@@ -4,6 +4,12 @@
 use Mojo::ByteStream 'b';
 use Mojo::Util qw/xml_escape deprecated/;
 
+# TODO:
+#   Add documentation plugin to programmatically
+#   create documentation navigation as a content_block
+#   so custom routes to custom templates can easily
+#   be configured
+
 sub register {
   my ($plugin, $mojo) = @_;
 
@@ -47,12 +53,7 @@
 
       ($page, my $fragment) = split '#', $page;
 
-      my $url = $c->url_with(
-        'doc',
-        scope => $scope,
-        page => $page
-      );
-
+      my $url = $c->doc->url($scope, $page);
       $url->fragment($fragment) if $fragment;
 
       return $c->link_to(
@@ -87,7 +88,7 @@
       my $scope = shift;
       my $url;
       if ($page) {
-        $url = $c->url_for('doc', page => $page, scope => $scope);
+        $url = $c->doc->url($scope, $page);
         $url->path->canonicalize;
       }
       else {
@@ -98,6 +99,26 @@
   );
 
 
+  $mojo->helper(
+    'doc.url' => sub {
+      my $c = shift;
+      my $page = pop;
+      my $scope = shift;
+      if ($scope) {
+        return $c->url_with(
+          'doc2',
+          page => $page,
+          scope => $scope
+        );
+      };
+
+      return $c->url_with(
+        'doc1',
+        page => $page
+      );
+    }
+  );
+
   # Documentation navigation helper
   $mojo->helper(
     doc_navi => sub {
@@ -122,12 +143,7 @@
           my $id = $_->{id};
           $id =~ s/^#//;
 
-          $url = $c->url_with(
-            'doc',
-            'scope' => $part_scope,
-            'page' => $page
-          );
-
+          $url = $c->doc->url($part_scope, $page);
           $url->fragment($id);
         }
 
@@ -140,11 +156,7 @@
           };
 
           # Generate url with query parameter inheritance
-          $url = $c->url_with(
-            'doc',
-            'scope' => $scope,
-            'page' => $_->{id}
-          );
+          $url = $c->doc->url($scope, $_->{id});
 
           # Canonicalize (for empty scopes)
           $url->path->canonicalize;
diff --git a/t/docembed.t b/t/docembed.t
new file mode 100644
index 0000000..24503f7
--- /dev/null
+++ b/t/docembed.t
@@ -0,0 +1,25 @@
+use Mojo::Base -strict;
+use Mojolicious::Lite;
+use Test::More;
+use Test::Mojo;
+use utf8;
+
+my $t = Test::Mojo->new('Kalamar' => {
+  Kalamar => {
+    api => 'xyz',
+    navi_ext => [
+      {
+        title => 'Privacy',
+        id => 'privacy'
+      }
+    ]
+  }
+});
+
+$t->get_ok('/doc')
+  ->text_is('nav > ul.nav > li.active a', 'KorAP')
+  ->text_is('nav > ul.nav > li:last-child a', 'Privacy')
+  ->element_exists('nav > ul.nav > li:last-child a[href=/doc/privacy#tutorial-top]')
+  ;
+
+done_testing;
diff --git a/t/docnavi.t b/t/docnavi.t
index e01c047..576db84 100644
--- a/t/docnavi.t
+++ b/t/docnavi.t
@@ -11,7 +11,8 @@
 push(@{$app->plugins->namespaces}, 'Kalamar::Plugin');
 
 # Establish test route
-$app->routes->get('/doc/*scope/:page')->to(cb => sub {})->name('doc');
+$app->routes->get('/doc/:page')->to(cb => sub {})->name('doc1');
+$app->routes->get('/doc/*scope/:page')->to(cb => sub {})->name('doc2');
 
 # Load plugin to test
 $app->plugin('KalamarHelpers');
@@ -261,6 +262,9 @@
      'Path matches FAQ');
 
 
+is($app->doc_link_to('privacy', 'privacy'), '<a class="doc-link" href="/doc/privacy">privacy</a>');
+is($app->doc_link_to('privacy', 'korap', 'privacy'), '<a class="doc-link" href="/doc/korap/privacy">privacy</a>');
+
 done_testing;
 
 __END__