stubs for rewrite of courses section
authorPaul Hänsch <paul@plutz.net>
Tue, 27 Aug 2019 05:57:07 +0000 (07:57 +0200)
committerPaul Hänsch <paul@plutz.net>
Tue, 27 Aug 2019 05:57:07 +0000 (07:57 +0200)
courses/courses.html.sh [deleted file]
courses/index.cgi [new file with mode: 0755]
courses/l10n.sh [new file with mode: 0755]
courses/list.sh [new file with mode: 0755]
courses/text_courses.sh [deleted file]
courses/widgets.sh [new file with mode: 0755]

diff --git a/courses/courses.html.sh b/courses/courses.html.sh
deleted file mode 100755 (executable)
index 99e3381..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2014 Paul Hänsch
-#
-# This file is part of Confetti.
-# 
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-# 
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
-
-edit="${_GET[edit]}"
-
-check_order(){
-  [ "${_GET[order]}" = "$1" ] && echo 'checked="checked"'
-}
-
-cat <<EOF
-<div class="sort">
-  <form class="search" action="?" method="GET">
-    <input type="hidden" name="page" value="courses"/>
-    <input type="hidden" name="edit" value="$edit"/>
-    <span class="label">$(l10n sort_order):</span>
-    <input type="radio" name="order" value="DOW" $(check_order DOW)>$(l10n order_DOW)</input>
-    <input type="radio" name="order" value="TOD" $(check_order TOD)>$(l10n order_TOD)</input>
-    <br>
-    <button type="submit" name="" value="">$(l10n order_apply)</button>
-  </form>
-</div>
-
-<div class="newcourse">
-  <form action="?action=new_course" method="POST">
-    <button type="submit">$(l10n newcourse)</button>
-  </form>
-</div>
-
-<div class="courselist">
-$(
-[ -f "ical/$edit" -o -f "temp/$edit" ] && edit_course "$edit"
-if [ "$?" = 0 ]; then
-  listcourses |grep -v "$edit"
-else
-  listcourses
-fi |while read card; do
-  view_course "$card"
-done
-)
-</div>
-EOF
-
-# vi:set filetype=html:
diff --git a/courses/index.cgi b/courses/index.cgi
new file mode 100755 (executable)
index 0000000..446cc9f
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+if [ "$_PATH" = "/courses/courses.css" ]; then
+  . $_EXEC/cgilite/file.sh
+  FILE $_EXEC/courses/courses.css
+  return 0
+fi
+
+. $_EXEC/pdiread.sh
+. $_EXEC/courses/l10n.sh
+. $_EXEC/courses/widgets.sh
+. $_EXEC/courses/list.sh
+
+unescape() { [ $# = 0 ] && sed -E 's;\\(.);\1;g' || printf %s "$*" |sed -E 's;\\(.);\1;g'; }
+upcase=' y;abcdefghijklmnopqrstuvwxyzäöüé;ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜÉ;; '
+
+order="$(GET o |grep -m1 -xE 'DOW|TOD')"
+edit="$(GET e |PATH)"
+
+[ "$order" ] || order=DOW
+edit="${edit##*/}"
+
+{ w_sort_courses
+  printf '
+  [form .newcourses action="/cards/new_course.sh" method="POST"
+    [button type="submit" %s]
+  ]' "$(l10n newcourse)"
+
+  [ "$edit" ] && edit_course "$edit"
+  printf '[div .courselist\n'
+    list_courses
+  printf ']'
+} | yield_page courses /courses/courses.css
diff --git a/courses/l10n.sh b/courses/l10n.sh
new file mode 100755 (executable)
index 0000000..711916e
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright 2014, 2016, 2019 Paul Hänsch
+#
+# This file is part of Confetti.
+# 
+# Confetti is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# Confetti is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
+
+l10n(){
+  local word
+  [ $# -eq 0 ] && read -r word || word="$1"
+
+  case $word in
+    SUMMARY) printf "Bezeichnung";;
+    COMMENT) printf "Kommentar";;
+    DTSTART) printf "Beginn";;
+    DURATION) printf "Dauer";;
+    RRULE) printf "Regelmäßigkeit";;
+    
+    DAILY) printf "Tage";;
+    WEEKLY) printf "Wochen";;
+    MONTHLY) printf "Monate";;
+    YEARLY) printf "Jahre";;
+    
+    sDAILY) printf "Täglich";;
+    sWEEKLY) printf "Wöchentlich";;
+    sMONTHLY) printf "Monatlich";;
+    sYEARLY) printf "Jährlich";;
+    
+    newcourse) printf "Neuen Eintrag anlegen";;
+    time) printf "Uhrzeit";;
+    edit_update) printf "Daten übernehmen";;
+    edit_cancel) printf "Abbrechen";;
+    edit_delete) printf "Eintrag löschen";;
+    edit_addfieldtext) printf "Neues Feld";;
+    edit_addfield) printf "+";;
+    edit_dtscal) printf "&#x2713;";;
+    edit) printf "Bearbeiten";;
+    ics_export) printf "ICal exportieren";;
+    courselist) printf "Kursliste (PDF)";;
+    
+    course_attendance) printf "Teilnahme";;
+    course_mail) printf "Mail an Teilnehmende";;
+    
+    sort_order) printf "Sortierung";;
+    order_DOW) printf "Wochentag";;
+    order_TOD) printf "Uhrzeit";;
+    order_apply) printf "Sortieren";;
+    
+    t_every) printf "Alle";;
+    t_eternal) printf "ewig";;
+    t_times) printf "mal";;
+    t_until) printf "Bis";;
+    t_oclock) printf "Uhr";;
+  esac
+}
diff --git a/courses/list.sh b/courses/list.sh
new file mode 100755 (executable)
index 0000000..a0eb6d1
--- /dev/null
@@ -0,0 +1,131 @@
+#!/bin/sh
+
+. "${_EXEC}"/pdiread.sh
+
+edit_card(){
+  local cardfile="$_DATA/vcard/$1" 
+  local tempfile card
+
+  . $_EXEC/session_lock.sh
+
+  if ! tempfile="$(CHECK_SLOCK "$cardfile")"; then
+    printf '[div .message %s]' "$(l10n "This card is not set up for editing within this session.")"
+  else
+    card="$(pdi_load "$tempfile")"
+    cat <<-EOF
+       [form .card #${cardfile##*/} action="/cards/update_card.sh" method="POST"
+         [input type="hidden" name="tid" value="$(transid ${tempfile})"]
+         [div .section .basic $(
+           edit_item "$card" N GENDER
+           [ "$(pdi_count "$card" NICKNAME)" -gt 0 ] \
+           && edit_item "$card" NICKNAME
+           edit_item "$card" BDAY
+           edit_item "$card" X-ZACK-JOINDATE
+           [ "$(pdi_count "$card" X-ZACK-LEAVEDATE)" -gt 0 ] \
+           && edit_item "$card" X-ZACK-LEAVEDATE
+           card_item "$card" SOUND PHOTO LOGO
+         )]
+         [div .section .phone   $(edit_item "$card" TEL)]
+         [div .section .message $(
+           edit_item "$card" EMAIL
+           [ $(pdi_count "$card" IMPP) -gt 0 ] && edit_item "$card" IMPP
+           [ $(pdi_count "$card" URL ) -gt 0 ] && edit_item "$card" URL
+         )]
+         [div .section .address $(edit_item "$card" ADR)]
+         [div .section .note    $(edit_item "$card" NOTE)]
+         [div .section .attendance
+           [h3 $(l10n course_attendance) ] $(
+           for course in "$_DATA"/ical/*.ics; do
+             printf '[label [input type="checkbox" name="attendance" value="%s" %s] %s]' \
+                    "${course##*/}" \
+                    "$(grep -qF "${course##*/} ${cardfile##*/}" "$_DATA/mappings/attendance" \
+                       && printf 'checked="checked"'
+                    )" \
+                    "$(pdi_value "$(pdi_load "$course")" SUMMARY |unescape |HTML)"
+           done)
+           [h3 $(l10n CATEGORIES) ] $(
+           grep -xE '[^ ]+' "$_DATA"/mappings/categories |while read -r cat; do
+             printf '[label [input type="checkbox" name="attendance" value="%s" %s] %s]' \
+                    "$(HTML "$cat")" \
+                    "$(seq 1 $(pdi_count "$card" CATEGORIES) |while read c; do
+                      pdi_value "$card" CATEGORIES $c |grep -qxF "$cat" \
+                      && printf 'checked="checked"' && break
+                    done)" \
+                    "$(HTML "$cat")"
+           done)
+         ]
+         [div .control
+           [select .item name="newfield"
+             [option value="" disabled="disabled" selected="selected" $(l10n edit_addfieldtext)]
+             $(for f in NICKNAME EMAIL TEL IMPP ADR URL NOTE; do
+               printf '[option value="%s" %s] ' "$f" "$(l10n "$f")"
+             done)
+          ][button .item type="submit" name="action" value="addfield" $(l10n edit_addfield)]
+           [button .item type="submit" name="action" value="update"   $(l10n edit_update)]
+           [input type="checkbox" #delete] [label .item for="delete" $(l10n edit_delete)]
+             [button .item type="submit" name="action" value="delete"]
+           [button .item type="submit" name="action" value="cancel"   $(l10n edit_cancel)]
+         ]
+         [input type="hidden" name="UID" value="$(pdi_value "$card" UID |HTML)"]
+         [input type="hidden" name="card" value="${cardfile##*/}"]
+       ]
+       EOF
+  fi
+}
+
+print_course(){
+  local coursefile="$1"
+  local course="$(pdi_load "$coursefile")"
+  cat <<-EOF
+    [div .course #${coursefile##*/}
+      [div .section .basic &shy;$(
+        cal_item "$course" SUMMARY DTSTART RRULE
+      )]
+      [div .section .COMMENT   &shy;$(cal_item "$course" COMMENT)]
+      [div .section .attendance [h3 $(l10n course_attendance) ] [ul &shy;
+        $(grep -F "    ${cardfile##*/}" "$_DATA/mappings/attendance" |while read each discard; do
+          printf '[li [a .item .attendance href="/courses#%s" &shy;%s]]' \
+                 "$each" \
+                 "$(pdi_value "$(pdi_load "$_DATA/ical/$each")" SUMMARY |unescape |HTML)"
+        done)]
+        $(cal_item "$card" CATEGORIES)
+      ]
+      [div .control
+        [a .item href="" $(l10n edit)]
+      ]
+    ]
+       EOF
+}
+
+print_courses(){
+  local calfile cachefile date size name ldate=0 lsize lname
+
+  while read calfile; do
+    cachefile="${_DATA}/cache/${calfile##*/}.cache"
+    if [ -s "$cachefile" -a "$cachefile" -nt "$calfile" ]; then
+      cat "$cachefile"
+    else
+      print_course "$calfile" |tee "$cachefile"
+    fi
+  done
+}
+
+order_courses() {
+  local calfile course
+
+  while read calfile; do
+    icstime="$(pdi_value "$(pdi_load "$calfile")" DTSTART |cal_date)"
+    case $order in
+      DOW) printf '%s  %s\n' "$(date -d "$icstime" "+%u %H:%M:%S")" "$calfile";;
+      TOD) printf '%s  %s\n' "$(date -d "$icstime" "+%H:%M:%S")" "$calfile";;
+    esac
+  done \
+  | sort \
+  | sed -E 's;^.*\t;;g'
+}
+
+list_courses(){
+  printf '%s\n' ${_DATA}/courses/*.ics \
+  | order_courses \
+  | print_courses
+}
diff --git a/courses/text_courses.sh b/courses/text_courses.sh
deleted file mode 100755 (executable)
index b86240a..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014, 2016 Paul Hänsch
-#
-# This file is part of Confetti.
-# 
-# Confetti is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# Confetti is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-# 
-# You should have received a copy of the GNU Affero General Public License
-# along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
-
-declare -A item_name
-
-item_name[SUMMARY]="Bezeichnung"
-item_name[COMMENT]="Kommentar"
-item_name[DTSTART]="Beginn"
-item_name[DURATION]="Dauer"
-item_name[RRULE]="Regelmäßigkeit"
-
-item_name[DAILY]="Tage"
-item_name[WEEKLY]="Wochen"
-item_name[MONTHLY]="Monate"
-item_name[YEARLY]="Jahre"
-
-item_name[sDAILY]="Täglich"
-item_name[sWEEKLY]="Wöchentlich"
-item_name[sMONTHLY]="Monatlich"
-item_name[sYEARLY]="Jährlich"
-
-item_name[newcourse]="Neuen Eintrag anlegen"
-item_name[time]="Uhrzeit"
-item_name[edit_update]="Daten übernehmen"
-item_name[edit_cancel]="Abbrechen"
-item_name[edit_delete]="Eintrag löschen"
-item_name[edit_addfieldtext]="Neues Feld"
-item_name[edit_addfield]="+"
-item_name[edit_dtscal]="&#x2713;"
-item_name[edit]="Bearbeiten"
-item_name[ics_export]="ICal exportieren"
-item_name[courselist]="Kursliste (PDF)"
-
-item_name[course_attendance]="Teilnahme"
-item_name[course_mail]="Mail an Teilnehmende"
-
-item_name[sort_order]="Sortierung"
-item_name[order_DOW]="Wochentag"
-item_name[order_TOD]="Uhrzeit"
-item_name[order_apply]="Sortieren"
-
-item_name[t_every]="Alle"
-item_name[t_eternal]="ewig"
-item_name[t_times]="mal"
-item_name[t_until]="Bis"
-item_name[t_oclock]="Uhr"
diff --git a/courses/widgets.sh b/courses/widgets.sh
new file mode 100755 (executable)
index 0000000..ec30a78
--- /dev/null
@@ -0,0 +1,207 @@
+# Copyright 2014, 2019 Paul Hänsch
+#
+# This file is part of Confetti.
+# 
+# Confetti is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# Confetti is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
+
+check(){
+  [ "$1" = "$2" ] && printf 'checked="checked"'
+}
+
+edit="$(GET e)"
+order="$(GET o |grep -m1 -xE 'DOW|TOD')"
+
+w_sort_courses(){
+  cat <<-EOF
+       [form .sort .search action="?" method="GET"
+         [span .label $(l10n sort_order):]
+         [radio "order" "DOW" $(check $order DOW) $(l10n order_DOW)]
+         [radio "order" "TOD" $(check $order TOD) $(l10n order_TOD)]
+         [submit "" "" $(l10n order_apply)]
+       ]
+       EOF
+}
+
+cal_date(){
+  { [ $# -eq 0 ] && cat || printf %s "$*"; } |sed -rnE '
+    2q
+    s/^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$/\1-\2-\3 \4:\5:\6 UTC/p;t
+    s/^TZID=(.+)\:([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$/TZ="\1" \2-\3-\4 \5:\6:\7/p;t
+    s/^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})$/\1-\2-\3 \4:\5:\6/p;t
+  '
+}
+
+cal_item(){
+  local course="$1"
+  local item cnt c
+  shift 1
+
+  for item in $@; do
+    cnt="$(pdi_count "$course" "$item")"
+
+    case $item in
+      SUMMARY)
+        printf '[h2 &shy%s]' "$(pdi_value "$course" SUMMARY)"
+        ;;
+      DTSTART)
+        printf '[span .text .DTSTART %s %s ]' \
+               "$(date -d "$(pdi_value "$course" DTSTART |cal_date)" '+%A %B %d, %Y - %H:%M')" \
+               "$(l10n t_oclock)"
+        ;;
+      RRULE)
+        dts_date="$(pdi_value "$course" DTSTART |cal_date)"
+        rrule=" $(pdi_value "$course" RRULE)"
+        rr_int="${rrule##*INTERVAL=}"; rr_int="${rr_int%%;*}"
+        rr_count="${rrule##*COUNT=}"; rr_count="${rr_count%%;*}"
+        rr_freq="${rrule##*FREQ=}"; rr_freq="${rr_freq%%;*}"
+        rr_until="${rrule##*UNTIL=}"; rr_until="${rr_until%%;*}"
+        rr_until="$(cal_date "${rr_until}")"
+
+        [ "$rr_int" -eq 1 ] \
+        && printf '[span .text .RRULE %s]' "$(l10n "s$rr_freq")" \
+        || printf '[span .text .RRULE %s %s %s]' "$(l10n t_every)" "${rr_int}" "$(l10n $rr_freq)"
+        case "$rrule $rr_freq" in
+          *COUNT*DAILY*)
+            printf '[span .text %s %s]' "$(l10n t_until)" "$(date -d "$dts_date + $((rr_int * rr_count)) day" "+%A %B %d, %Y - %H:%M")"
+            ;;
+          *COUNT*WEEKLY*)
+            printf '[span .text %s %s]' "$(l10n t_until)" "$(date -d "$dts_date + $((rr_int * rr_count)) week" "+%A %B %d, %Y - %H:%M")"
+            ;;
+          *COUNT*MONTHLY*)
+            printf '[span .text %s %s]' "$(l10n t_until)" "$(date -d "$dts_date + $((rr_int * rr_count)) month" "+%A %B %d, %Y - %H:%M")"
+            ;;
+          *COUNT*YEARLY*)
+            printf '[span .text %s %s]' "$(l10n t_until)" "$(date -d "$dts_date + $((rr_int * rr_count)) year" "+%A %B %d, %Y - %H:%M")"
+            ;;
+          *UNTIL*)
+            printf '[span .text %s %s]' "$(l10n t_until)" "$(date -d "$rr_until" "+%A %B %d, %Y - %H:%M")"
+            ;;
+        esac
+        ;;
+      attendance);;
+      COMMENT)[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[p .item .%s &shy;%s]' "$item" \
+                 "$(pdi_value "$course" "$item" $c |unescape |HTML)"
+        done
+        ;;
+      *)[ $cnt -gt 0 ] && printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[span .item .%s &shy;%s]' "$item" \
+                 "$(pdi_value "$course" "$item" $c |unescape |HTML)"
+        done
+        ;;
+    esac
+  done
+}
+
+edit_item(){
+  local card="$1"
+  local item cnt c
+  shift 1
+
+  for item in $@; do
+    cnt="$(pdi_count "$card" "$item")"
+    [ $cnt -lt 1 ] && cnt=1
+
+    case $item in
+      N)N="$(pdi_value "$card" N)"
+        if [ "$N" ]; then
+          IFS=\; read n1 n2 n3 n4 n5 <<-EOF
+               $N
+               EOF
+        else
+         N="$(pdi_value "$card" FN |unescape)"
+          n1="${N%%[a-z]*}" n1="${N#$n1}"
+          [ "$n1" ] || n1="${N##* }"
+          n2="${N%$n1}"
+        fi
+        printf '
+        [h3 %s]
+        [input .item .N name="4N" placeholder="%s" value="%s"]
+        [input .item .N name="2N" placeholder="%s" value="%s"]
+        [input .item .N name="1N" placeholder="%s" value="%s"]
+        [input .item .N name="5N" placeholder="%s" value="%s"]
+        ' "$(l10n "$item")" \
+        "$(l10n n_pre)"   "$(HTML "$n4")" \
+        "$(l10n n_first)" "$(HTML "$n2" "$n3")" \
+        "$(l10n n_last)"  "$(HTML "$n1")" \
+        "$(l10n n_post)"  "$(HTML "$n5")"
+        ;;
+      GENDER)
+        gender="$(pdi_value "$card" GENDER)"
+        printf '
+        [select .item .GENDER name="GENDER"
+          [option value="" disabled="disabled" %s %s]
+          [option value="female" %s %s]
+          [option value="male"   %s %s]
+          [option value="other"  %s %s]
+          [option value="none"   %s %s]
+        ]\n' \
+        "$([ "$gender" = ''       ] && printf 'selected="selected"')" "$(l10n GENDER)" \
+        "$([ "$gender" = 'female' ] && printf 'selected="selected"')" "$(l10n gender_female)" \
+        "$([ "$gender" = 'male'   ] && printf 'selected="selected"')" "$(l10n gender_male)" \
+        "$([ "$gender" = 'other'  ] && printf 'selected="selected"')" "$(l10n gender_other)" \
+        "$([ "$gender" = 'none'   ] && printf 'selected="selected"')" "$(l10n gender_none)"
+        ;;
+      BDAY|X-ZACK-JOINDATE|X-ZACK-LEAVEDATE)
+        printf '[h3 %s]
+        [input .item .%s name="%s" value="%s" placeholder="YYYY-MM-DD"]' \
+        "$(l10n "$item")" "$item" "$item" "$(pdi_value "$card" "$item" |grep -xE '[0-9-]+')"
+        ;;
+      ADR|NOTE)
+        printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete_%i" "true" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          printf '<textarea class="item %s" name="%s">%s</textarea>' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)"
+        done
+        printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
+        ;;
+      TEL) printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete_%i" "true" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          teltype="$(pdi_attrib "$card" TEL $c TYPE)"
+          printf '[select .item .teltype name="teltype"
+                    [option value="" disabled="disabled" %s %s]
+                    [option value="HOME" %s %s]
+                    [option value="WORK" %s %s]
+                    [option value="CELL" %s %s]
+                    [option value="FAX"  %s %s]
+                  ]\n' \
+                  "$([ "$teltype" = ''     ] && printf 'selected="selected"')" "$(l10n teltype)" \
+                  "$([ "$teltype" = 'HOME' ] && printf 'selected="selected"')" "$(l10n TYPE=HOME)" \
+                  "$([ "$teltype" = 'WORK' ] && printf 'selected="selected"')" "$(l10n TYPE=WORK)" \
+                  "$([ "$teltype" = 'CELL' ] && printf 'selected="selected"')" "$(l10n TYPE=CELL)" \
+                  "$([ "$teltype" = 'FAX'  ] && printf 'selected="selected"')" "$(l10n TYPE=FAX)"
+
+          printf '[input .item .%s name="%s" value="%s" placeholder="%s"]' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)" "$(l10n "$item")"
+        done
+        printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
+        ;;
+      *)printf '[h3 %s]' "$(l10n "$item")"
+        seq 1 $cnt |while read c; do
+          printf '[checkbox "%s_delete_%i" "true" .delete #%s_delete_%i][label for="%s_delete_%i" %s]' \
+            "$item" $c "$item" $c "$item" $c "$(l10n delete)"
+          printf '[input .item .%s name="%s" value="%s" placeholder="%s"]' \
+            "$item" "$item" "$(pdi_value "$card" "$item" $c |unescape |HTML)" "$(l10n "$item")"
+        done
+        printf '[button type="submit" name="action" value="addfield %s" %s ]' "$item" "$(l10n edit_addfield)"
+        ;;
+    esac
+  done
+}