]> iEval git - gruntmaster-page.git/blob - lib/Gruntmaster/Page/Base.pm
Change "Problem list" to "Problems"
[gruntmaster-page.git] / lib / Gruntmaster / Page / Base.pm
1 package Gruntmaster::Page::Base;
2
3 use 5.014000;
4 use strict;
5 use warnings;
6
7 use Encode qw/encode/;
8 use File::Slurp qw/read_file/;
9 use HTML::Template::Compiled;
10
11 ##################################################
12
13 use POSIX ();
14 use Gruntmaster::Data ();
15 use List::Util ();
16
17 sub import {
18 my $caller = caller;
19 my ($self, $name, $title) = @_;
20
21 Gruntmaster::Data->export_to_level(1, $caller);
22 List::Util->export_to_level(1, $caller, qw/sum/);
23
24 no strict 'refs';
25 *{"${caller}::strftime"} = \&POSIX::strftime;
26 *{"${caller}::NAME"} = sub () { $name };
27 *{"${caller}::TITLE"} = sub () { $title };
28 *{"${caller}::debug"} = sub {
29 local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
30 $_[0]->({qw/level debug message/ => $_[1]})
31 };
32 }
33
34 ##################################################
35
36 my %orig_header_templates = (
37 en => <<'HTML',
38 <!DOCTYPE html>
39 <title>TITLE_GOES_HERE</title>
40 <meta charset="utf-8">
41 <meta name="viewport" content="width=device-width, initial-scale=1.0">
42
43 <link rel="stylesheet" href="/css/cyborg" id="stylesheet">
44 <script src="/js" type="text/javascript"></script>
45
46 <nav class="navbar navbar-default navbar-static-top" role="navigation">
47 <div class="container-fluid">
48 <div class="navbar-header">
49 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
50 <a class="navbar-brand" href="/">Gruntmaster 6000</a>
51 </div>
52
53 <div class="collapse navbar-collapse">
54 <ul class="nav navbar-nav">
55 <li><a href="/pb/">Problems</a>
56 <li><a href="/ct/">Contests</a>
57 <li><a href="/account">Account</a>
58 </ul>
59
60 <ul class="nav navbar-nav navbar-right">
61 <li><a class="dropdown-toggle" data-toggle="dropdown"> Theme <span class="caret"></span></a>
62
63 <ul class="dropdown-menu" role="menu">
64 <li><a href="#" id="theme_slate">Gunmetal gray</a>
65 <li><a href="#" id="theme_cyborg">Black</a>
66 <li><a href="#" id="theme_cerulean">White</a>
67 <li><a href="#" id="theme_cosmo">Metro</a>
68 </ul>
69
70 <li><a href="/log/">Job log</a>
71 </ul>
72 </div>
73 </div>
74 </nav>
75
76 <div class="container-fluid">
77
78 <div id="subtitle">TITLE_GOES_HERE</div>
79
80 HTML
81 );
82
83 my %orig_footer_templates = (
84 en => <<'HTML',
85
86 <footer>
87 Dilmom: Why don't you call your product the Gruntmaster 6000?
88 Dilbert: What kind of product do you see when you imagine a Gruntmaster 6000?
89 Dilmom: Well, it's a stripped-down version of the Gruntmaster 9000, of course. But it's software-upgradeable.
90 </footer>
91 HTML
92 );
93
94 sub patch_templates {
95 my $root = $ENV{GRUNTMASTER_TEMPLATE_ROOT} or return %{$_[0]};
96 my ($templates, $name) = @_;
97 my %out = %$templates;
98 for (<$root/$name.*>) {
99 m/\.(.+)$/;
100 $out{$1} = read_file $_
101 }
102
103 %out
104 }
105
106 sub reload_templates (){ $ENV{GRUNTMASTER_RELOAD_TEMPLATES} }
107
108 my %header_templates = patch_templates \%orig_header_templates, 'header';
109 my %footer_templates = patch_templates \%orig_footer_templates, 'footer';
110
111 sub header{
112 my ($language, $title) = @_;
113 %header_templates = patch_templates \%orig_header_templates, 'header' if reload_templates;
114 $header_templates{$language} =~ s/TITLE_GOES_HERE/$title/ger;
115 }
116
117 sub footer{
118 %footer_templates = patch_templates \%orig_footer_templates, 'footer' if reload_templates;
119 $footer_templates{$_[0]};
120 }
121
122 sub cook_templates {
123 my ($templates, $name, $title) = @_;
124
125 my %out = patch_templates $templates, $name;
126 $out{$_} = header ($_, $title) . $out{$_} for keys %out;
127 $out{$_} .= footer $_ for keys %out;
128
129 %out
130 }
131
132 ##################################################
133
134 my %templates;
135
136 sub generate{
137 my ($self, $lang, @args) = @_;
138
139 $templates{$self} = { cook_templates $self->TEMPLATES, $self->NAME => $self->TITLE } if !exists $templates{$self} or reload_templates;
140
141 my $htc = HTML::Template::Compiled->new(scalarref => \$templates{$self}{$lang}, default_escape => 'HTML',);
142 $self->_generate($htc, $lang, @args);
143 [200, ['Content-Type' => 'text/html', 'Content-Language' => $_[1], 'Vary' => 'Accept-Language'], [ encode 'UTF-8' => $htc->output ] ]
144 }
145
146 sub _generate {}
147
148 sub variants {
149 [ map { [ $_, 1, 'text/html', undef, undef, $_, undef ]} keys $_[0]->TEMPLATES ]
150 }
151
152 1
This page took 0.049549 seconds and 5 git commands to generate.