summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/global.pl14
-rw-r--r--data/lang.txt134
-rw-r--r--data/notes/chardb3
-rw-r--r--lib/VNDB/DB/Traits.pm7
-rw-r--r--lib/VNDB/Handler/Traits.pm115
-rw-r--r--lib/VNDB/Util/CommonHTML.pm4
6 files changed, 257 insertions, 20 deletions
diff --git a/data/global.pl b/data/global.pl
index 30feb436..0e4b02e8 100644
--- a/data/global.pl
+++ b/data/global.pl
@@ -31,13 +31,13 @@ our %S = (%S,
scr_size => [ 136, 102 ], # w*h of screenshot thumbnails
cv_size => [ 256, 400 ], # max. w*h of cover images
user_ranks => [
- # allowed actions # DB number
- [qw| hist |], # 0
- [qw| hist |], # 1
- [qw| hist board |], # 2
- [qw| hist board edit tag |], # 3
- [qw| hist board boardmod edit tag mod lock del tagmod |], # 4
- [qw| hist board boardmod edit tag mod lock del tagmod usermod |], # 5
+ # allowed actions # DB number
+ [qw| hist |], # 0
+ [qw| hist |], # 1
+ [qw| hist board |], # 2
+ [qw| hist board edit tag |], # 3
+ [qw| hist board boardmod edit charedit tag mod lock del tagmod |], # 4
+ [qw| hist board boardmod edit charedit tag mod lock del tagmod usermod |], # 5
],
languages => [qw|cs da de en es fi fr hu it ja ko nl no pl pt-br pt-pt ru sk sv tr vi zh|],
producer_types => [qw|co in ng|],
diff --git a/data/lang.txt b/data/lang.txt
index d3120f4b..3674bd2a 100644
--- a/data/lang.txt
+++ b/data/lang.txt
@@ -4779,6 +4779,13 @@ cs*:
hu*:
nl : Dit kenmerk is nog niet goedgekeurd door een moderator.
+:_traitp_addchild
+en : Create child trait
+ru*:
+cs*:
+hu*:
+nl : Voeg een subkenmerk toe
+
:_traitp_indexlink
en : Traits
ru*:
@@ -4808,6 +4815,133 @@ hu*:
nl : nog [_1] [quant,_1,kenmerk,kenmerken]
+# Trait add/edit form (/i+/edit, /i+/add, /i/add)
+
+:_traite_title_add
+en : Add child trait to [_1]
+ru*:
+cs*:
+hu*:
+nl : Voeg subkenmerk toe aan [_1]
+
+:_traite_title_edit
+en : Edit trait: [_1]
+ru*:
+cs*:
+hu*:
+nl : Wijzig kenmerk [_1]
+
+:_traite_title_new
+en : Add new trait
+ru*:
+cs*:
+hu*:
+nl : Voeg nieuw kenmerk toe
+
+:_traite_req_title
+en : Requesting new trait
+ru*:
+cs*:
+hu*:
+nl : Vraag nieuwe trait aan
+
+:_traite_req_subtitle
+en : Your trait must be approved
+ru*:
+cs*:
+hu*:
+nl : Je kenmerk moet goedgekeurd worden
+
+:_traite_req_msg
+en : Because all traits have to be approved by moderators, it can take a while before your trait will show up in the listings or can be used on character entries.
+ru*:
+cs*:
+hu*:
+nl : Omdat alle kenmerken goedgekeurd moeten worden door een moderator, kan het even duren voordat je kenmerk te zien is op de site of gebruikt kan worden voor karakters.
+
+:_traite_frm_name
+en : Primary name
+ru : Основное название
+cs : Hlavní jméno
+hu : Elsődleges név
+nl : Primaire naam
+
+:_traite_frm_by
+en : Added by
+ru : Добавлено
+cs : Přidal
+hu : Hozzáadta
+nl : Toegevoegd door
+
+:_traite_frm_state
+en : State
+ru : Состояние
+cs : Stav
+hu : Állapot
+nl : Status
+
+:_traite_frm_state0
+en : Awaiting moderation
+ru : Ожидает модерации
+cs : Čeká na schválení
+hu : Moderálásra vár
+nl : Wacht op goedkeuring
+
+:_traite_frm_state1
+en : Deleted/hidden
+ru : Удалён/скрыт
+cs : Smazán/skryt
+hu : Rejtett/törölve
+nl : Verwijderd
+
+:_traite_frm_state2
+en : Approved
+ru : Одобрен
+cs : Schválen
+hu : Elfogadva
+nl : Goedgekeurd
+
+:_traite_frm_meta
+en : This is a meta trait (only to be used as parent for other traits, not for direct use with characters)
+ru*:
+cs*:
+hu*:
+nl : Dit is een metakenmerk (kan alleen gebruikt worden als houder voor andere kenmerken, niet voor karakters)
+
+:_traite_frm_alias
+en : Aliases
+ (separated by newlines)
+ru : Прочие названия
+ (каждое с новой строки)
+cs : Aliasy
+ (odděleny novou řádkou)
+hu : Más nevek
+ (új sorokkal elválasztva)
+nl : Aliassen
+ (gescheiden door enters)
+
+:_traite_frm_desc
+en : Description
+ru : Описание
+cs : Popis
+hu : Leírás
+nl : Beschrijving
+
+:_traite_frm_parents
+en : Parent traits
+ru*:
+cs*:
+hu*:
+nl : Hoofdkenmerk
+
+:_traite_frm_parents_msg
+en : Comma separated list of trait names to be used as parent for this trait.
+ru*:
+cs*:
+hu*:
+nl : Kommagescheiden lijst van hoofdkenmerken.
+
+
#############################################################################
diff --git a/data/notes/chardb b/data/notes/chardb
index 4f828ae8..0a42bcd8 100644
--- a/data/notes/chardb
+++ b/data/notes/chardb
@@ -259,6 +259,9 @@ User interface considerations:
Trait edit:
URI: /i+/edit, /i/new
The regular add/edit form.
+ - What to do with the linked characters when a trait is marked as deleted
+ or meta? Batch-edit all character entries to remove the trait? Sounds
+ painful...
Trait listing / overview:
URI: /i
diff --git a/lib/VNDB/DB/Traits.pm b/lib/VNDB/DB/Traits.pm
index 81ac95e1..8b9849ed 100644
--- a/lib/VNDB/DB/Traits.pm
+++ b/lib/VNDB/DB/Traits.pm
@@ -13,7 +13,7 @@ use Exporter 'import';
our @EXPORT = qw|dbTraitGet dbTraitTree dbTraitEdit dbTraitAdd|;
-# Options: id what results page sort reverse
+# Options: id noid name what results page sort reverse
# what: parents childs(n) aliases addedby
# sort: id name added
sub dbTraitGet {
@@ -26,7 +26,10 @@ sub dbTraitGet {
);
my %where = (
- $o{id} ? ('t.id = ?' => $o{id}) : (),
+ $o{id} ? ('t.id = ?' => $o{id}) : (),
+ $o{noid} ? ('t.id <> ?' => $o{noid}) : (),
+ $o{name} ? (
+ 't.id = (SELECT id FROM traits LEFT JOIN traits_aliases ON id = trait WHERE lower(name) = ? OR lower(alias) = ? LIMIT 1)' => [ lc $o{name}, lc $o{name} ]) : (),
);
my @select = (
diff --git a/lib/VNDB/Handler/Traits.pm b/lib/VNDB/Handler/Traits.pm
index 640af81e..d505b6c7 100644
--- a/lib/VNDB/Handler/Traits.pm
+++ b/lib/VNDB/Handler/Traits.pm
@@ -8,7 +8,10 @@ use VNDB::Func;
TUWF::register(
- qr{i([1-9]\d*)}, \&traitpage,
+ qr{i([1-9]\d*)}, \&traitpage,
+ qr{i([1-9]\d*)/(edit)}, \&traitedit,
+ qr{i([1-9]\d*)/(add)}, \&traitedit,
+ qr{i/new}, \&traitedit,
);
@@ -20,6 +23,7 @@ sub traitpage {
my $title = mt '_traitp_title', $t->{meta}?0:1, $t->{name};
$self->htmlHeader(title => $title, noindex => $t->{state} != 2);
+ $self->htmlMainTabs('i', $t);
if($t->{state} != 2) {
div class => 'mainbox';
@@ -41,6 +45,7 @@ sub traitpage {
}
div class => 'mainbox';
+ a class => 'addnew', href => "/i$trait/add", mt '_traitp_addchild' if $self->authCan('charedit') && $t->{state} != 1;
h1 $title;
parenttags($t, mt('_traitp_indexlink'), 'i');
@@ -67,16 +72,108 @@ sub traitpage {
}
-1;
+sub traitedit {
+ my($self, $trait, $act) = @_;
+
+ my($frm, $par);
+ if($act && $act eq 'add') {
+ $par = $self->dbTraitGet(id => $trait)->[0];
+ return $self->resNotFound if !$par;
+ $frm->{parents} = $par->{name};
+ $trait = undef;
+ }
-__END__
+ return $self->htmlDenied if !$self->authCan('charedit') || $trait && !$self->authCan('tagmod');
+
+ my $t = $trait && $self->dbTraitGet(id => $trait, what => 'parents(1) aliases addedby')->[0];
+ return $self->resNotFound if $trait && !$t;
+
+ if($self->reqMethod eq 'POST') {
+ return if !$self->authCheckCode;
+ $frm = $self->formValidate(
+ { post => 'name', required => 1, maxlength => 250, regex => [ qr/^[^,]+$/, 'A comma is not allowed in trait names' ] },
+ { post => 'state', required => 0, default => 0, enum => [ 0..2 ] },
+ { post => 'meta', required => 0, default => 0 },
+ { post => 'alias', required => 0, maxlength => 1024, default => '', regex => [ qr/^[^,]+$/s, 'No comma allowed in aliases' ] },
+ { post => 'description', required => 0, maxlength => 10240, default => '' },
+ { post => 'parents', required => !$self->authCan('tagmod'), default => '' },
+ );
+ my @aliases = split /[\t\s]*\n[\t\s]*/, $frm->{alias};
+ my @parents = split /[\t\s]*,[\t\s]*/, $frm->{parents};
+ if(!$frm->{_err}) {
+ my $c = $self->dbTraitGet(name => $frm->{name}, noid => $trait);
+ push @{$frm->{_err}}, [ 'name', 'tagexists', $c->[0] ] if @$c; # should be traitexists... but meh
+ for (@aliases) {
+ $c = $self->dbTraitGet(name => $_, noid => $trait);
+ push @{$frm->{_err}}, [ 'alias', 'tagexists', $c->[0] ] if @$c;
+ }
+ for(@parents) {
+ $c = $self->dbTraitGet(name => $_, noid => $trait);
+ push @{$frm->{_err}}, [ 'parents', 'func', [ 0, mt '_tagedit_err_notfound', $_ ]] if !@$c;
+ $_ = $c->[0]{id};
+ }
+ }
+
+ if(!$frm->{_err}) {
+ $frm->{state} = $frm->{meta} = 0 if !$self->authCan('tagmod');
+ my %opts = (
+ name => $frm->{name},
+ state => $frm->{state},
+ description => $frm->{description},
+ meta => $frm->{meta}?1:0,
+ aliases => \@aliases,
+ parents => \@parents,
+ );
+ if(!$trait) {
+ $trait = $self->dbTraitAdd(%opts);
+ } else {
+ $self->dbTraitEdit($trait, %opts, upddate => $frm->{state} == 2 && $t->{state} != 2) if $trait;
+ }
+ $self->resRedirect("/i$trait", 'post');
+ return;
+ }
+ }
-Simple test database:
+ if($t) {
+ $frm->{$_} ||= $t->{$_} for (qw|name meta description state|);
+ $frm->{alias} ||= join "\n", @{$t->{aliases}};
+ $frm->{parents} ||= join ', ', map $_->{name}, @{$t->{parents}};
+ }
- INSERT INTO traits (name, description, state, meta, addedby) VALUES
- ('Blood Type', 'Describes the blood type of the character', 2, true, 2),
- ('Blood Type O', '', 2, true, 2),
- ('Blood Type B', '', 2, true, 2);
- INSERT INTO traits_parents (trait, parent) VALUES (2, 1), (3, 1);
+ my $title = $par ? mt('_traite_title_add', $par->{name}) : $t ? mt('_traite_title_edit', $t->{name}) : mt '_traite_title_new';
+ $self->htmlHeader(title => $title, noindex => 1);
+ $self->htmlMainTabs('i', $par || $t, 'edit') if $t || $par;
+ if(!$self->authCan('tagmod')) {
+ div class => 'mainbox';
+ h1 mt '_traite_req_title';
+ div class => 'notice';
+ h2 mt '_traite_req_subtitle';
+ p;
+ lit mt '_traite_req_msg';
+ end;
+ end;
+ end;
+ }
+
+ $self->htmlForm({ frm => $frm, action => $par ? "/i$par->{id}/add" : $t ? "/i$trait/edit" : '/i/new' }, 'traitedit' => [ $title,
+ [ input => short => 'name', name => mt '_traite_frm_name' ],
+ $self->authCan('tagmod') ? (
+ $t ?
+ [ static => label => mt('_traite_frm_by'), content => $self->{l10n}->userstr($t->{addedby}, $t->{username}) ] : (),
+ [ select => short => 'state', name => mt('_traite_frm_state'), options => [
+ map [$_, mt '_traite_frm_state'.$_], 0..2 ] ],
+ [ checkbox => short => 'meta', name => mt '_traite_frm_meta' ]
+ ) : (),
+ [ textarea => short => 'alias', name => mt('_traite_frm_alias'), cols => 30, rows => 4 ],
+ [ textarea => short => 'description', name => mt '_traite_frm_desc' ],
+ [ input => short => 'parents', name => mt '_traite_frm_parents' ],
+ [ static => content => mt '_traite_frm_parents_msg' ],
+ ]);
+
+ $self->htmlFooter;
+}
+
+
+1;
diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm
index 1872c083..ce086e55 100644
--- a/lib/VNDB/Util/CommonHTML.pm
+++ b/lib/VNDB/Util/CommonHTML.pm
@@ -17,7 +17,7 @@ our @EXPORT = qw|
# generates the "main tabs". These are the commonly used tabs for
# 'objects', i.e. VN/producer/release entries and users
-# Arguments: u/v/r/p/g, object, currently selected item (empty=main)
+# Arguments: u/v/r/p/g/i, object, currently selected item (empty=main)
sub htmlMainTabs {
my($self, $type, $obj, $sel) = @_;
$sel ||= '';
@@ -73,7 +73,7 @@ sub htmlMainTabs {
if( $type eq 'u' && ($self->authInfo->{id} && $obj->{id} == $self->authInfo->{id} || $self->authCan('usermod'))
|| $type =~ /[vrp]/ && $self->authCan('edit') && (!$obj->{locked} || $self->authCan('lock')) && (!$obj->{hidden} || $self->authCan('del'))
- || $type eq 'g' && $self->authCan('tagmod')
+ || $type =~ /[gi]/ && $self->authCan('tagmod')
) {
li $sel eq 'edit' ? (class => 'tabselected') : ();
a href => "/$id/edit", mt '_mtabs_edit';