[drupal-devel] Question on taxonomy_form() function

Scott Courtney scott at 4th.com
Wed Mar 30 14:12:52 UTC 2005

Good morning!

I've read the API docs on this, and even looked at the function's source code.
I understand how it works, but apparently not how to use it properly. :-)

My new image_import module (a feature that I'm developing in cooperation with
walkah's excellent work, and yes, I've emailed with him to discuss it first)
has code that looks like this:

  $html = '';
  $vocabs =& taxonomy_get_vocabularies(IMAGE_IMPORT_IMAGE_NODETYPE);
  // The above function orders by weight, so we don't have to sort
  $group = '';
  foreach ($vocabs as $vocab) {
     $group .= taxonomy_form($vocab->vid, $_POST['edit']['taxonomy'],NULL);
  $html .= form_group(t('Categories'),$group,t(' ... long help text here ...'));

The constant IMAGE_IMPORT_IMAGE_NODETYPE is just the string 'image'.

After submitting a form, the $_POST['edit']['taxonomy'] subarray looks like

array(3) { [0]=> string(1) "1"
           [1]=> array(1) { 
                    [0]=> string(1) "3" } 
           [2]=> array(1) { 
                    [0]=> string(1) "7" } 

The three selected term IDs are "1", "3", and "7".

My problem is that the second vocabulary (vid==2, tid=={3,7}) allows multiple
selection, whereas the first vocabulary (vid==1, tid==1) does not. The way
the underlying form_select() called by taxonomy_form() seems to work is that
it uses a subarray for the field only if multiple selection is allowed. This
puts the resulting tids at different levels in the array tree, and causes my
$_POST['edit']['taxonomy'] to fail as a way to pass the existing value(s) to
taxonomy_form() for a given vid.

My first thought was to try using a $name parameter for taxonomy_form(),
something akin to taxonomy_1 for vid 1, taxonomy_2 for vid 2, etc. That seems
awfully clumsy. I also tried passing $name as an array-like string, e.g.,
$name=="[taxonomy][1]" for vid 1, etc. That failed syntactically.

There isn't a good way to match up those sub-subarrays with the vid to which
they point, so simple conditional logic inside my foreach{} loop is not going
to be feasible if the site administrator has associated more than one multi-term-
allowed vocabulary with images.

There's probably a "right way" to do this, but I'll be damned if I see it. The
only method I can figure out looks like a hideous kludge. Can someone suggest
the correct approach to this, or point me to a module that does it for some
example code? The only place I could think of that does this is in node.module,
but the problem there is that is has a $node object and passes that to an
entirely different function instead of taxonomy_form. My module needs to pick
vocabulary terms in advance of the existence of a node object, then apply them
to multiple nodes as those nodes are created, so I don't have a $node to pass
as node.module and other node-type modules do. My module doesn't define any
new node types, but just adds a new way to create nodes of an existing type.

I'm probably going to feel stupid when I see the answer to this, but I'll risk
it. Any suggestions?

Is it worth considering a new core function like taxonomy_forms() that would
accept a node type as its parameter and return the HTML for all of the vocabs
associated with that node, in such a way that the resulting $_POST is easily
parsed by vid to support previews?



Scott Courtney         | "I don't mind Microsoft making money. I mind them
scott at 4th.com          | having a bad operating system."    -- Linus Torvalds
http://4th.com/        | ("The Rebel Code," NY Times, 21 February 1999)
                       | PGP Public Key at http://4th.com/keys/scott.pubkey

More information about the drupal-devel mailing list