[pmwiki-devel] handling of input arrays

sti at pooq.com sti at pooq.com
Fri Nov 23 17:18:15 CST 2007


Hans wrote:
> I am trying to work out a sensible general way to treat arrays of
> input values. Input controls can have names denoting the field as an
> element in an array, like: name[]
> If several of these are passed on as $_POST input for example, they
> will be indexed name[0], name[1], name[2] etc.
> 
> Fox so far has treated these kind of arrays special in its value
> substitutions by repeatedly applying all input to the array elements,
> thereby generating multiple lines or sets of output. This immediately
> runs into problems of there are two or more arrays.
> 
> Now I come to appreciate that an input array can be applied to several
> target pages, by mapping the array index to the target page index.
> But there may be occasions that an input array (or several) shall be
> applied to a single target page, i.e. multiple output on one page.
> But I cannot see any examples, so I am inclined to dismiss it.
> 
> The exception for this is when the input array fields have their keys
> defined: name[1], name[2], name[3], or name[a], name[b] etc. instead
> of name[]. Then it may be fair to map these to discrete substitution
> variables {$$name[1]} {$$name[2]} etc. i.e. treat such names as normal
> names. At least that's what I think so far.

My multilingual blog has run into needs for all of these, and I've ended up
experimentally extending fox in several ways to handle the issue. Here's what
I've done, as documented in the code.

#   {$$field}
#     When the value of the field 'field' is a single string, it is
#     substituted in place. When the field is an array of values, then
#     the value substituted is the same as if the replaced string had
#     been {$$field[{$$foxtindex}]}. The value of {$$foxtindex} is the
#     index of the current template being expanded, in the array of
#     templates, starting with zero.
#
#   {$$field[num]}
#     When the value of the field 'field' is an array, and 'num' is a
#     number, then the element with index 'num' in the array is
#     substituted. If the field is not an array, or if there is no
#     such element, then the markup is simply removed. Note that when
#     'num' is non-numeric, the markup is left unsubstituted, but do
#     not rely on that, as further extensions may make use of
#     non-numeric array indexes.
#
#   {$$(function args...)}
#     is replaced by the results of evaluating 'function' as if it
#     were an ordinary Markup Expression (ie, as if it were the string
#     '{(function args...)}' on a normal page). In order to provide
#     backward compatibility, Fox.php adds a 'date' function to the
#     list of valid markup extensions.
#
#   {$$field[]}
#     The existence of one or more special markups of this form cause
#     a special processing mode to be entered. For each element in the
#     longest array named by this form in the template, a duplicate of
#     the template is produced. The first duplicate contains all
#     values of the 0th element of the named arrays, the second
#     duplicate contains the 1st elements and so on. Missing elements
#     are treated as null strings. All of the duplicates are written
#     to the target, in order. The template can be broken into
#     multiple sections with {[foxsection]} markers, each such section
#     being treated independantly in this manner.

I discovered that it was necessary to split the template and handle the
{$$var[]} cases first, as I found myself writing things like this:

  {[foxsection]}
  {$$(if (test equal {$$foo[]} {$$bar[]}) "Same" "Different")}
  {[foxsection]}

And I needed the sections to be generated before the {$$(if...)} was expanded.

This handles many of the cases that I ran into, but I found I sometimes needed
to expand an array into a string within a single template, using something
like the 'implode' function from PHP, so I wrote a MarkupExpression function
that knows about $$ variables:

# FoxList
#
# handles {$$(list opt=xxx $$foo -$$bar -"foo" +bar ... )}
#
# Outputs a (by default) space separated list of array elements.
#
# OPTIONS:
#
#   sep=...
#     will separate the list of elements by this string instead.
#
#   pre=...
#     prefix each output element with this string.
#
#   post=...
#     postfix each output element with this string.
#
#   beg=...
#     if the list is non-empty, output this first.
#
#   end=...
#     if the list is non-empty, output this last.
#
# Variables of the form $$... can appear and are replaced by their
# expansion. If the variable is an array, its replaced by a list of
# its elements.
#
# An element without a + or - prefix is added to the list.
#
# Elements with a - prefix are removed from the list. The element can
# contain a glob pattern, and all matching elements are removed.
#
# Elements with a + prefix remove all non-matching entries from the
# list. The element can contain a glob pattern.

This allowed me to write PTVs that would allow translated versions of the same
blog entry to reference each other:

 Versions: {$$(list $$langtarget -{$$target} sep=", " pre="[[" post="]]")}

-- 
Stirling Westrup -- Visionary, Technology Analyst, Researcher, Software
Engineer, IT Generalist

LinkedIn Profile: https://www.linkedin.com/e/fpf/77228

Website:       http://www.pooq.com
Tech Blog:     http://technaut.livejournal.com
Business Blog: http://willcodeforfood.livejournal.com
--
Spread the word: Its all a HOAX, memes don't exist!



More information about the pmwiki-devel mailing list