package VNDB::Util::LayoutHTML; use strict; use warnings; use TUWF ':html', 'uri_escape'; use Exporter 'import'; use Encode 'decode_utf8'; use VNDB::Func; our @EXPORT = qw|htmlHeader htmlFooter|; sub htmlHeader { # %options->{ title, noindex, search, feeds, svg, metadata } my($self, %o) = @_; my $skin = $self->reqGet('skin') || $self->authPref('skin') || $self->{skin_default}; $skin = $self->{skin_default} if !$self->{skins}{$skin} || !-d "$VNDB::ROOT/static/s/$skin"; # heading lit ''; tag 'html', lang => 'en'; head prefix => 'og: http://ogp.me/ns#'; title $o{title}; Link rel => 'shortcut icon', href => '/favicon.ico', type => 'image/x-icon'; Link rel => 'stylesheet', href => $self->{url_static}.'/s/'.$skin.'/style.css?'.$self->{version}, type => 'text/css', media => 'all'; Link rel => 'search', type => 'application/opensearchdescription+xml', title => 'VNDB VN Search', href => $self->reqBaseURI().'/opensearch.xml'; if($self->authPref('customcss')) { (my $css = $self->authPref('customcss')) =~ s/\n/ /g; style type => 'text/css', $css; } Link rel => 'alternate', type => 'application/atom+xml', href => "/feeds/$_.atom", title => $self->{atom_feeds}{$_}[1] for ($o{feeds} ? @{$o{feeds}} : ()); if(exists $o{metadata}) { # Required fields as per http://op.me/#metadata: og:title, og:type, og:image, og:url if(exists $o{metadata}{'og:title'}) { $o{metadata}{'og:site_name'} = 'The Visual Novel Database'; $o{metadata}{'og:type'} ||= 'object'; $o{metadata}{'og:image'} ||= $self->{placeholder_img}; $o{metadata}{'og:url'} ||= $self->reqURI(); } for my $k (keys %{$o{metadata}}) { next if !$o{metadata}{$k} and $o{metadata}{$k} ne '0'; $o{metadata}{$k} =~ s/\R/ /g; meta property => "$k", content => $o{metadata}->{$k}, undef; } } meta name => 'robots', content => 'noindex, follow', undef if $o{noindex}; end; body; div id => 'bgright', ' '; div id => 'header'; h1; a href => '/', 'the visual novel database'; end; end; _menu($self, %o); div id => 'maincontent'; } sub _menu { my($self, %o) = @_; div id => 'menulist'; div class => 'menubox'; h2; txt 'Menu'; end; div; a href => '/', 'Home'; br; a href => '/v/all', 'Visual novels'; br; b class => 'grayedout', '> '; a href => '/g', 'Tags'; br; a href => '/r', 'Releases'; br; a href => '/p/all', 'Producers'; br; a href => '/s/all', 'Staff'; br; a href => '/c/all', 'Characters'; br; b class => 'grayedout', '> '; a href => '/i', 'Traits'; br; a href => '/u/all', 'Users'; br; a href => '/hist', 'Recent changes'; br; a href => '/t', 'Discussion board'; br; a href => '/d6', 'FAQ'; br; a href => '/v/rand','Random visual novel'; end; form action => '/v/all', method => 'get', id => 'search'; fieldset; legend 'Search'; input type => 'text', class => 'text', id => 'sq', name => 'sq', value => $o{search}||'', placeholder => 'search'; input type => 'submit', class => 'submit', value => 'Search'; end; end; end 'div'; # /menubox div class => 'menubox'; if($self->authInfo->{id}) { my $uid = sprintf '/u%d', $self->authInfo->{id}; my $nc = $self->authInfo->{notifycount}; h2; a href => $uid, ucfirst $self->authInfo->{username}; end; div; a href => "$uid/edit", 'My Profile'; br; a href => "$uid/list", 'My Visual Novel List'; br; a href => "$uid/votes",'My Votes'; br; a href => "$uid/wish", 'My Wishlist'; br; a href => "$uid/notifies", $nc ? (class => 'notifyget') : (), 'My Notifications'.($nc?" ($nc)":''); br; a href => "$uid/hist", 'My Recent Changes'; br; a href => '/g/links?u='.$self->authInfo->{id}, 'My Tags'; br; br; if($self->authCan('edit')) { a href => '/v/add', 'Add Visual Novel'; br; a href => '/p/add', 'Add Producer'; br; a href => '/s/new', 'Add Staff'; br; a href => '/c/new', 'Add Character'; br; } br; a href => "$uid/logout", 'Logout'; end; } else { h2 'User menu'; div; my $ref = uri_escape $self->reqPath().$self->reqQuery(); a href => "/u/login?ref=$ref", 'Login'; br; a href => '/u/newpass', 'Password reset'; br; a href => '/u/register', 'Register'; br; end; } end 'div'; # /menubox div class => 'menubox'; h2 'Database Statistics'; div; dl; dt 'Visual Novels'; dd $self->{stats}{vn}; dt 'Releases'; dd $self->{stats}{releases}; dt 'Producers'; dd $self->{stats}{producers}; dt 'Characters'; dd $self->{stats}{chars}; dt 'Staff'; dd $self->{stats}{staff}; dt 'VN Tags'; dd $self->{stats}{tags}; dt 'Character Traits';dd $self->{stats}{traits}; dt 'Users'; dd $self->{stats}{users}; dt 'Threads'; dd $self->{stats}{threads}; dt 'Posts'; dd $self->{stats}{posts}; end; clearfloat; end; end; end 'div'; # /menulist } sub htmlFooter { # %options => { pref_code => 1 } my($self, %o) = @_; div id => 'footer'; my $q = $self->dbRandomQuote; if($q && $q->{vid}) { lit '"'; a href => "/v$q->{vid}", style => 'text-decoration: none', $q->{quote}; txt '"'; br; } txt "vndb $self->{version} | "; a href => '/d7', 'about us'; txt ' | '; a href => 'irc://irc.synirc.net/vndb', '#vndb'; txt ' | '; a href => "mailto:$self->{admin_email}", $self->{admin_email}; txt ' | '; a href => $self->{source_url}, 'source'; end; end 'div'; # /maincontent # Abuse an empty noscript tag for the formcode to update a preference setting, if the page requires one. noscript id => 'pref_code', title => $self->authGetCode('/xml/prefs.xml'), '' if $o{pref_code} && $self->authInfo->{id}; script type => 'text/javascript', src => $self->{url_static}.'/f/vndb.js?'.$self->{version}, ''; end 'body'; end 'html'; # write the SQL queries as a HTML comment when debugging is enabled if($self->debug) { lit "\n\n"; } } 1;