Lots of fixes to pagination, l10n, tutorial, css ...
diff --git a/Makefile.PL b/Makefile.PL
index 0fa8bc5..6517dce 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -19,15 +19,11 @@
'Mojolicious::Plugin::Notifications' => 0.04,
'Mojolicious::Plugin::MailException' => 0.18,
'Mojolicious::Plugin::CHI' => 0.09,
+ 'Cache::FastMmap' => 0,
# Currently only on GitHub
'Mojolicious::Plugin::Search' => 0.04,
- 'Cache::FastMmap' => 0,
- 'Mojolicious::Plugin::Number::Commify' => '0.022',
- 'Mojolicious::Plugin::AssetPack' => 0.23,
- 'JavaScript::Minifier::XS' => 0.09,
- 'CSS::Minifier::XS' => 0.09,
- 'CSS::Sass' => '0.8.1'
+ 'Mojolicious::Plugin::Localize' => 0.08
},
test => {
TESTS => 't/*.t'
diff --git a/dev/scss/main/kwic.scss b/dev/scss/main/kwic.scss
index 3676663..7284311 100644
--- a/dev/scss/main/kwic.scss
+++ b/dev/scss/main/kwic.scss
@@ -5,7 +5,7 @@
#search {
position: relative;
- margin-bottom: 44px;
+ margin-bottom: 30px;
overflow: visible;
&.match {
@@ -84,7 +84,7 @@
// @include light-noise;
position: relative;
> div {
- min-height: 42pt;
+ min-height: 20pt;
> div.snippet {
background-color: $light-orange;
> * {
diff --git a/dev/scss/main/logos.scss b/dev/scss/main/logos.scss
index 1512a56..c2caa70 100644
--- a/dev/scss/main/logos.scss
+++ b/dev/scss/main/logos.scss
@@ -44,7 +44,8 @@
font-size: 85%;
right: 0;
width: 100%;
- margin-left: $standard-margin;
+ margin-left: ($standard-margin / 2);
+
padding-left: 60%;
> div {
border-top: 26px solid $dark-orange;
@@ -103,10 +104,3 @@
text-align: center;
width: 100%;
}
-
-/*
-#leibniz-logo, #ids-logo {
- height: (130 / 20) + em;
-}
-
-*/
\ No newline at end of file
diff --git a/dev/scss/main/pagination.scss b/dev/scss/main/pagination.scss
index d057dd0..ef5eb34 100644
--- a/dev/scss/main/pagination.scss
+++ b/dev/scss/main/pagination.scss
@@ -25,8 +25,8 @@
*/
font-size: 0;
position: fixed;
- right: 20px;
- bottom: 24px;
+ right: ($standard-margin / 4);
+ bottom: ($standard-margin / 2);
z-index: 400;
padding: 0;
height: auto;
diff --git a/dev/scss/main/resultinfo.scss b/dev/scss/main/resultinfo.scss
index 8717f72..93b1714 100644
--- a/dev/scss/main/resultinfo.scss
+++ b/dev/scss/main/resultinfo.scss
@@ -17,3 +17,16 @@
font-weight: bold;
}
+#no-results {
+ margin: 0 auto;
+ text-align: center;
+ code {
+ &::before {
+ content : open-quote;
+ }
+ &::after {
+ content : close-quote;
+ }
+ font-weight: bold;
+ }
+}
diff --git a/kalamar.conf b/kalamar.conf
index 2375936..ae026dc 100644
--- a/kalamar.conf
+++ b/kalamar.conf
@@ -1,6 +1,17 @@
+# Based on Mojolicious::Plugin::Number::Commify
+my $THOUSAND_SEP_RE = qr/(
+ ^[-+]? # beginning of number.
+ \d+? # first digits before first comma
+ (?= # followed by, (but not included in the match) :
+ (?>(?:\d{3})+) # some positive multiple of three digits.
+ (?!\d) # an *exact* multiple, not x * 3 + 1 or whatever.
+ )| # or:
+ \G\d{3} # after the last group, get three digits
+ (?=\d) # but they have to have more digits after them.
+)/x;
+
{
Kalamar => {
-# 'api-0.1' => 'http://10.0.10.13:8888/api/v0.1/'
'api-0.1' => 'http://10.0.10.13:7070/api/v0.1/'
},
Notifications => {
@@ -14,11 +25,6 @@
api => 'http://10.0.10.13:7070/api/v0.1/'
},
CHI => {
-# session_cache => {
-# driver => 'FastMmap',
-# root_dir => app->home . '/cache/session',
-# cache_size => '3m'
-# },
default => {
driver => 'FastMmap',
root_dir => app->home . '/cache/data',
@@ -32,17 +38,24 @@
proxy => 1
},
'TagHelpers-Pagination' => {
- prev => '<span><i class="fa fa-caret-left"></i></span>',
- next => '<span><i class="fa fa-caret-right"></i></span>',
- ellipsis => '<span><i class="fa fa-ellipsis-h"></i></span>',
+ prev => '<span><span><</span></span>',
+ next => '<span><span><</span></span>',
+ ellipsis => '<a class="ellipsis"><span><span>...</span></span></a>',
separator => '',
- current => '<span>{current}</span>',
- page => '<span>{page}</span>'
+ current => '<span>{current}</span>',
+ page => '<span>{page}</span>'
},
Localize => {
dict => {
_ => sub { $_->locale },
de => {
+ numf => sub {
+ shift;
+ my %val = @_;
+ my $num = $val{number} or return 0;
+ $num =~ s/$THOUSAND_SEP_RE/$1\./g;
+ return $num;
+ },
about => 'Über KorAP',
login => 'Anmelden',
searchtitle => 'KorAP: Finde "<%= $q %>" (<%= $ql %>)',
@@ -56,14 +69,25 @@
tutorial => 'Einführung',
pubOn => 'veröffentlicht am',
matchCount => 'Treffer',
+ noMatches => 'Es wurden keine Treffer für <code><%= stash("q") %></code> gefunden.',
jsFile => 'kalamar-<%= $Kalamar::VERSION %>-en.js',
korap => {
-short => 'KorAP',
- long => 'KorAP - Korpusanalyseplattform der nächsten Generation',
+ desc => 'KorAP - Korpusanalyseplattform der nächsten Generation',
overview => 'KorAP - Übersicht',
},
+ template => {
+ intro => 'de/intro'
+ }
},
-en => {
+ numf => sub {
+ shift;
+ my %val = @_;
+ my $num = $val{number} or return 0;
+ $num =~ s/$THOUSAND_SEP_RE/$1\,/g;
+ return $num;
+ },
about => 'About KorAP',
login => 'Login',
go => 'Go!',
@@ -74,13 +98,14 @@
with => 'with',
pubOn => 'published on',
matchCount => '<%= num($found, "match", "matches") %>',
+ noMatches => 'There were no matches for <code><%= stash("q") %></code>.',
glimpse => 'Sample',
faq => 'F.A.Q.',
tutorial => 'Tutorial',
jsFile => 'kalamar-<%= $Kalamar::VERSION %>-en.js',
korap => {
-short => 'KorAP',
- long => 'KorAP - Corpus Analysis Platform',
+ desc => 'KorAP - Corpus Analysis Platform',
overview => 'KorAP - Overview'
}
}
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index aea95f5..d5fb248 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -36,7 +36,6 @@
'Search', # Abstract Search framework
'CHI', # Global caching mechanism
'TagHelpers::Pagination', # Pagination widget
- 'Number::Commify', # Localize numbers
'KalamarHelpers' # Specific Helpers for Kalamar
) {
@@ -74,3 +73,11 @@
__END__
+
+=pod
+
+To get started, you'll need npm. Then you can install and run grunt:
+
+sudo npm install -g grunt-cli
+npm install
+grunt
diff --git a/lib/Kalamar/Controller/Search.pm b/lib/Kalamar/Controller/Search.pm
index 09ab580..13af8c5 100644
--- a/lib/Kalamar/Controller/Search.pm
+++ b/lib/Kalamar/Controller/Search.pm
@@ -10,7 +10,7 @@
# No query
unless ($query) {
- return $c->render(template => 'intro');
+ return $c->render(template => $c->loc('template_intro', 'intro'));
};
# Base parameters for remote access
diff --git a/lib/Kalamar/Plugin/KalamarHelpers.pm b/lib/Kalamar/Plugin/KalamarHelpers.pm
index 5434cd1..be86f56 100644
--- a/lib/Kalamar/Plugin/KalamarHelpers.pm
+++ b/lib/Kalamar/Plugin/KalamarHelpers.pm
@@ -32,6 +32,8 @@
);
# Documentation link
+ # TODO: Support opener mechanism, so the link will open the embedded
+ # documentation in case it's not there.
$mojo->helper(
doc_link_to => sub {
my $c = shift;
@@ -53,6 +55,24 @@
}
);
+ $mojo->helper(
+ doc_opener => sub {
+ my $c = shift;
+ my $cb = pop;
+ my $page = pop;
+ my $scope = shift;
+ my $url;
+ if ($page) {
+ $url = $c->url_for('doc', page => $page, scope => $scope);
+ $url->path->canonicalize;
+ }
+ else {
+ $url = $c->url_for('doc_start');
+ };
+ return $c->link_to($cb->($c), $url);
+ }
+ );
+
# Documentation navigation helper
$mojo->helper(
@@ -180,6 +200,14 @@
$c->stash('kalamar.test_port' => 0);
return 0;
});
+
+ # Create links in the tutorial that make sure the current position is preserved,
+ # in case the tutorial was opened embedded
+ $mojo->helper(
+ kalamar_tut_link_to => sub {
+ return '[TODO]';
+ }
+ );
};
diff --git a/t/doc.t b/t/doc.t
new file mode 100644
index 0000000..476d4bf
--- /dev/null
+++ b/t/doc.t
@@ -0,0 +1,27 @@
+use Mojo::Base -strict;
+use lib '../lib', 'lib';
+use Test::More;
+use Test::Mojo;
+
+# Test the documentation
+
+my $t = Test::Mojo->new('Kalamar');
+
+$t->get_ok('/doc/ql/poliqarp-plus')
+ ->status_is(200)
+ ->text_like('title', qr/poliqarp/i)
+ ->element_exists('aside.active')
+ ->element_exists('main.tutorial')
+ ->element_exists('header')
+ ->element_exists('aside nav')
+ ->content_is('');
+
+$t->get_ok('/doc/ql/poliqarp-plus?embedded=true')
+ ->status_is(200)
+ ->text_like('title', qr/poliqarp/i)
+ ->element_exists('aside.active')
+ ->element_exists('main.tutorial')
+ ->element_exists_not('header');
+
+
+done_testing();
diff --git a/t/docnavi.t b/t/docnavi.t
new file mode 100644
index 0000000..a9dc149
--- /dev/null
+++ b/t/docnavi.t
@@ -0,0 +1,211 @@
+use Mojo::Base -strict;
+use lib '../lib', 'lib';
+use Mojolicious::Lite;
+use Test::More;
+use Test::Mojo;
+
+my $t = Test::Mojo->new;
+my $app = $t->app;
+
+# Add additional plugin path
+push(@{$app->plugins->namespaces}, 'Kalamar::Plugin');
+
+# Establish test route
+$app->routes->get('/doc/(*scope)/:page')->to(cb => sub {})->name('doc');
+
+# Load plugin to test
+$app->plugin('KalamarHelpers');
+
+my $navi = [
+ {
+ id => 'korap',
+ title => 'KorAP'
+ }
+];
+
+my $render = $app->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!KorAP!, 'Title matches');
+
+$navi = [
+ {
+ id => 'korap',
+ title => 'KorAP'
+ },
+ {
+ id => 'krill',
+ title => 'Krill'
+ }
+];
+
+$render = $app->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!KorAP!, 'Title matches');
+like($render, qr!/doc/krill!, 'Path matches doc/krill');
+like($render, qr!Krill!, 'Title matches');
+
+$navi = [
+ {
+ id => 'korap',
+ title => 'KorAP',
+ items => [
+ {
+ id => 'krill',
+ title => 'Krill',
+ }
+ ]
+ },
+ {
+ id => 'faq',
+ title => 'F.A.Q.'
+ }
+];
+
+$render = $app->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!/doc/korap/krill!, 'Path matches korap/krill');
+like($render, qr!/doc/faq!, 'Path matches doc/faq');
+
+$navi = [
+ {
+ id => 'korap',
+ title => 'KorAP',
+ items => [
+ {
+ id => 'krill',
+ title => 'Krill',
+ },
+ {
+ id => 'koral',
+ title => 'Koral'
+ }
+ ]
+ },
+ {
+ title => 'Query Languages',
+ id => 'ql',
+ items => [
+ {
+ title => 'Cosmas II',
+ id => 'cosmas2'
+ },
+ {
+ 'title' => 'Poliqarp+',
+ 'id' => 'poliqarp-plus',
+ items => [
+ {
+ "title" => "Simple Segments",
+ "id" => "#segments"
+ },
+ {
+ "title" => "Complex Segments",
+ "id" => "#complex"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id => 'faq',
+ title => 'F.A.Q.'
+ }
+];
+
+$render = $app->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!/doc/korap/krill!, 'Path matches korap/krill');
+like($render, qr!/doc/korap/koral!, 'Path matches korap/koral');
+like($render, qr!/doc/ql!, 'Path matches doc/ql');
+like($render, qr!/doc/ql/cosmas2!, 'Path matches doc/ql/cosmas2');
+like($render, qr!/doc/ql/poliqarp-plus!, 'Path matches doc/ql/poliqarp-plus');
+like($render, qr!/doc/ql/poliqarp-plus#segments!,
+ 'Path matches doc/ql/poliqarp-plus#segments');
+like($render, qr!/doc/ql/poliqarp-plus#complex!,
+ 'Path matches doc/ql/poliqarp-plus#complex');
+like($render, qr!/doc/faq!, 'Path matches doc/faq');
+
+
+my $c = $app->build_controller;
+$c->stash(page => 'korap');
+$render = $c->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!/doc/korap/krill!, 'Path matches korap/krill');
+like($render, qr!/doc/ql!, 'Path matches doc/ql');
+like($render, qr!/doc/ql/poliqarp-plus#segments!,
+ 'Path matches doc/ql/poliqarp-plus#segments');
+like($render, qr!/doc/ql/poliqarp-plus#complex!,
+ 'Path matches doc/ql/poliqarp-plus#complex');
+like($render, qr!class="active".*?KorAP!, 'Active value for KorAP');
+
+$c->stash(page => 'poliqarp-plus');
+$render = $c->doc_navi($navi);
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!/doc/korap/krill!, 'Path matches korap/krill');
+like($render, qr!/doc/ql!, 'Path matches doc/ql');
+like($render, qr!/doc/ql/poliqarp-plus#segments!,
+ 'Path matches doc/ql/poliqarp-plus#segments');
+like($render, qr!/doc/ql/poliqarp-plus#complex!,
+ 'Path matches doc/ql/poliqarp-plus#complex');
+like($render, qr!class="active".*?Poliqarp\+!, 'Active value for Poliqarp+');
+
+
+$navi = [
+ {
+ id => 'korap',
+ title => 'KorAP',
+ items => [
+ {
+ id => 'krill',
+ title => 'Krill',
+ },
+ {
+ id => 'koral',
+ title => 'Koral'
+ }
+ ]
+ },
+ {
+ title => 'Query Languages',
+ id => 'ql',
+ items => [
+ {
+ title => 'Cosmas II',
+ id => 'cosmas2'
+ },
+ {
+ 'title' => 'Poliqarp+',
+ 'id' => 'poliqarp-plus',
+ 'class' => 'folded',
+ items => [
+ {
+ "title" => "Simple Segments",
+ "id" => "#segments"
+ },
+ {
+ "title" => "Complex Segments",
+ "id" => "#complex"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ id => 'faq',
+ title => 'F.A.Q.'
+ }
+];
+$render = $c->doc_navi($navi);
+
+like($render, qr!/doc/korap!, 'Path matches doc/korap');
+like($render, qr!/doc/korap/krill!, 'Path matches korap/krill');
+like($render, qr!/doc/ql!, 'Path matches doc/ql');
+like($render, qr!/doc/ql/poliqarp-plus#segments!,
+ 'Path matches doc/ql/poliqarp-plus#segments');
+like($render, qr!/doc/ql/poliqarp-plus#complex!,
+ 'Path matches doc/ql/poliqarp-plus#complex');
+like($render, qr!class="folded active".*?Poliqarp\+!, 'Active and folded value for Poliqarp+');
+
+done_testing;
+
+__END__
+
diff --git a/templates/partial/header.html.ep b/templates/partial/header.html.ep
index a994af1..d33e45d 100644
--- a/templates/partial/header.html.ep
+++ b/templates/partial/header.html.ep
@@ -1,7 +1,6 @@
<header>
<a href="/"
- class="logo"
- title="<%= title %>"><h1><span><%= title %></span></h1></a>
+ class="logo"><h1><span><%= title() // loc('korap_desc') %></span></h1></a>
<div class="button top">
<!--
<a href="#"
diff --git a/templates/search.html.ep b/templates/search.html.ep
index b6f8d4d..eeb65a9 100644
--- a/templates/search.html.ep
+++ b/templates/search.html.ep
@@ -1,19 +1,19 @@
% layout 'main', title => loc('searchtitle', q => search->query, ql => search->query_language);
<div class="resultinfo">
-%# <div id="pagination"><%= pagination(search->start_page, $pages, $url) =%></div>
+ <div id="pagination"><%= pagination(search->start_page, search->total_pages, url_with->query(['p' => '{page}'])) =%></div>
% my $found = search->total_results;
% if ($found != -1) {
-% my $found_text = $found;
+% my $found_text = loc('numf', number => $found);
% if (search->time_exceeded) {
-% $found_text = '> ' . $found;
+% $found_text = '> ' . $found_text;
% };
<p class="found"><span id="total-results"><%= $found_text %></span> <%= loc('matchCount', found => $found) %></p>
+%# <% if (search->benchmark) { %> (~ <%= search->benchmark %>)<% } %>
% } else {
<p></p>
% };
-%# <% if (search->benchmark) { %> in <%= search->benchmark %><% } %>
</div>
% if (search->total_results != 0 && search->results->size) {
@@ -24,4 +24,6 @@
% end
</ol>
</div>
+% } else {
+<p id="no-results"><%== loc 'noMatches', q => search->query %></p>
% }