diff options
author | Yorhel <git@yorhel.nl> | 2019-09-23 11:01:17 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2019-09-23 11:01:17 +0200 |
commit | 9ccafba60b8de37b0c2a202d22df5c3e25b78026 (patch) | |
tree | ae150b0c25282a646e1d71868022ad4a5789e60a /lib/VNWeb/Docs | |
parent | 4542d952f782ee193dbf279cd8186cba0e9d87a4 (diff) |
v2rw: Convert doc pages + add framework for item fetching & display & revisions
This bumps the minimum Perl version to 5.26 in order to make use of
lexical subroutines - a feature I've been wanting for a while. This
should be the last version bump, 5.26 is the highest version in Ubuntu
LTS at the moment. Not that I use Ubuntu, but it's used by the Docker
container and it's a sensible reference.
I merged the 'maintabs' and 'hiddenmsg' features into the primary
framework_ function; It fits quite well there, removes a little bit
of boilerplate from the DB entry page code and reduces the reliance on
common "dbSomethingGet()" methods.
I was hoping I'd be able to reduce the boilerplate required for defining
revisions, but I don't think that's going to happen. What I did do was
reimplement the diffing to handle item and text diffs separately, with
sensible defaults for the old split/join/diff options. Diffing is now
performed on the raw structured data rather than on formatted HTML,
which, combined with the db_entry() functions, ought to be less brittle.
Diffstat (limited to 'lib/VNWeb/Docs')
-rw-r--r-- | lib/VNWeb/Docs/Lib.pm | 90 | ||||
-rw-r--r-- | lib/VNWeb/Docs/Page.pm | 67 |
2 files changed, 157 insertions, 0 deletions
diff --git a/lib/VNWeb/Docs/Lib.pm b/lib/VNWeb/Docs/Lib.pm new file mode 100644 index 00000000..eed1afc0 --- /dev/null +++ b/lib/VNWeb/Docs/Lib.pm @@ -0,0 +1,90 @@ +package VNWeb::Docs::Lib; + +use VNWeb::Prelude; +use Text::MultiMarkdown 'markdown'; + +our @EXPORT = qw/md2html/; + + +# Lets you call TUWF::XML functions and returns a string, doesn't affect any existing TUWF::XML outputs. +# Nice idea for a TUWF::XML feature. +sub lexicalxml(&) { + my $f = shift; + my $buf = ''; + local $TUWF::XML::OBJ = TUWF::XML->new(write => sub { $buf .= shift }); + $f->(); + $buf +} + + +sub _moderators { + my $l = tuwf->dbAlli('SELECT id, username, perm FROM users WHERE (perm & ', \(auth->allPerms &~ auth->defaultPerms), ') > 0 ORDER BY id LIMIT 100'); + my @modperms = grep 0 == (auth->listPerms->{$_} & auth->defaultPerms), keys auth->listPerms->%*; + + lexicalxml { + dl_ sub { + for my $u (@$l) { + dt_ sub { a_ href => "/u$u->{id}", $u->{username} }; + dd_ auth->allPerms == ($u->{perm} & auth->allPerms) ? 'admin' + : join ', ', sort grep $u->{perm} & auth->listPerms->{$_}, @modperms; + } + } + } +} + + +sub _skincontrib { + my %users; + push $users{ tuwf->{skins}{$_}[1] }->@*, [ $_, tuwf->{skins}{$_}[0] ] + for sort { tuwf->{skins}{$a}[0] cmp tuwf->{skins}{$b}[0] } keys tuwf->{skins}->%*; + + my $u = tuwf->dbAlli('SELECT id, username FROM users WHERE id IN', [keys %users]); + + lexicalxml { + dl_ sub { + for my $u (@$u) { + dt_ sub { a_ href => "/u$u->{id}", $u->{username} }; + dd_ sub { + join_ ', ', sub { a_ href => "?skin=$_->[0]", $_->[1] }, $users{$u->{id}}->@* + } + } + } + } +} + + +sub md2html { + my $content = shift; + + $content =~ s{^:MODERATORS:$}{_moderators}me; + $content =~ s{^:SKINCONTRIB:$}{_skincontrib}me; + + my $html = markdown $content, { + strip_metadata => 1, + img_ids => 0, + disable_footnotes => 1, + disable_bibliography => 1, + }; + + # Number sections and turn them into links + my($sec, $subsec) = (0,0); + $html =~ s{<h([1-2])[^>]+>(.*?)</h\1>}{ + if($1 == 1) { + $sec++; + $subsec = 0; + qq{<h3><a href="#$sec" name="$sec">$sec. $2</a></h3>} + } elsif($1 == 2) { + $subsec++; + qq|<h4><a href="#$sec.$subsec" name="$sec.$subsec">$sec.$subsec. $2</a></h4>\n| + } + }ge; + + # Text::MultiMarkdown doesn't handle fenced code blocks properly. The + # following solution breaks inline code blocks, but I don't use those anyway. + $html =~ s/<code>/<pre>/g; + $html =~ s#</code>#</pre>#g; + + $html +} + +1; diff --git a/lib/VNWeb/Docs/Page.pm b/lib/VNWeb/Docs/Page.pm new file mode 100644 index 00000000..15d501a2 --- /dev/null +++ b/lib/VNWeb/Docs/Page.pm @@ -0,0 +1,67 @@ +package VNWeb::Docs::Page; + +use VNWeb::Prelude; +use VNWeb::Docs::Lib; + + +sub _index_ { + ul_ class => 'index', sub { + li_ sub { b_ 'Guidelines' }; + li_ sub { a_ href => '/d5', 'Editing Guidelines' }; + li_ sub { a_ href => '/d2', 'Visual Novels' }; + li_ sub { a_ href => '/d15', 'Special Games' }; + li_ sub { a_ href => '/d3', 'Releases' }; + li_ sub { a_ href => '/d4', 'Producers' }; + li_ sub { a_ href => '/d16', 'Staff' }; + li_ sub { a_ href => '/d12', 'Characters' }; + li_ sub { a_ href => '/d10', 'Tags & Traits' }; + li_ sub { a_ href => '/d13', 'Capturing Screenshots' }; + li_ sub { b_ 'About VNDB' }; + li_ sub { a_ href => '/d9', 'Discussion Board' }; + li_ sub { a_ href => '/d6', 'FAQ' }; + li_ sub { a_ href => '/d7', 'About Us' }; + li_ sub { a_ href => '/d17', 'Privacy Policy & Licensing' }; + li_ sub { a_ href => '/d11', 'Database API' }; + li_ sub { a_ href => '/d14', 'Database Dumps' }; + li_ sub { a_ href => '/d18', 'Database Querying' }; + li_ sub { a_ href => '/d8', 'Development' }; + } +} + + +sub _rev_ { + my $d = shift; + revision_ d => $d, sub {}, + [ title => 'Title' ], + [ content => 'Contents' ]; +} + + +# A little in-memory cache of the rendered HTML for the latest revision of each +# doc page. md2html() performance is "acceptable" for regular page loads but +# can still feel a little sluggish. +my %cache; # chid => html + + +TUWF::get qr{/$RE{drev}} => sub { + my $d = db_entry d => tuwf->capture('id'), tuwf->capture('rev'); + return tuwf->resNotFound if !$d; + + my $html = $cache{$d->{chid}} || md2html $d->{content}; + $cache{$d->{chid}} ||= $html if $d->{chrev} == $d->{maxrev}; + + framework_ title => $d->{title}, type => 'd', dbobj => $d, hiddenmsg => 1, + sub { + _rev_ $d if tuwf->capture('rev'); + div_ class => 'mainbox', sub { + h1_ $d->{title}; + div_ class => 'docs', sub { + _index_; + lit_ $html; + clearfloat_; + }; + }; + }; +}; + +1; |