Content type specific taxonomy settings.

public
group: Taxonomy
Alan D. - Thu, 2008-06-26 11:26

Hi all

Just wondering if anyone has played with the idea of content type specific taxonomy settings.

Currently, the only way to implement a 1-1 and a 1-n relationship between two different content types that I know of would be to do this manually via CCK or the fapi for the two types. Similar situation for required fields.

A quick look at the code, albeit a very very short look, seems that this would not be to hard to implement this. Free tagging could be more interesting. Has anyone tried this in the past?

A use case for this would be a sports classification. A book could optionally cover any number of sports, but a race must be assigned a singular sport.

This has probably been covered in the past, but the search simply returned far to many hits to read them all.

Thx.

I may be having a related problem

alexevasion's picture
alexevasion - Wed, 2008-07-02 21:48

Please tell me if this makes sense and if the solution is obvious to you? I'm building a fitness site and I have a few different types of content. I want to be able to browse the content types (exercises, routines, articles) separately. I can browse exercises by taxonomy terms using the vocabulary index module, but I can't seem to find a way to do so separately for the other content types. Exercises and routines share some common vocabulary, but articles are off on their own. I tried using wiki modules to wall off articles, but failed there too. Do you have any idea how I could accomplish this seemingly easy task? How does this relate to what you are proposing above? Thanks,
ALEX
www.youfitter.org


Have a look at views

Alan D. - Thu, 2008-07-03 10:49

Views provide the easiest solution to do what you want. Create a view for each content type that is linked to the taxonomic section. If you're really keen, try writing your own views via a custom module, but requires a reasonable level of Drupal expertise.

My interest is in the desire/need to actually specify individual taxonomy settings per content type, rather than having to share these between all content types. Another example is a region vocabulary. A locatin would have a single term assigned, a trip would have multiple.

hook_form_alter

catch's picture
catch - Thu, 2008-07-03 12:06

You could do single/multiple etc. with hook_form_alter - I think forum.module does this in core to change required settings depending on whether the node is a forum topic or something else.


Required taxonomy settings per content-type

ArjanLikesDrupa... - Wed, 2008-07-09 13:58

You mention this in the first post. I have been looking for this, found a few references of people asking about this, but no solutions. Would this be hard to accomplish? I would for example make choosing a term from 'Project' vocabulary required for content-type Project, but optional for content-type Images, or News, etc. Seems like a must-have feature to me!

Custom coding required

Alan D. - Wed, 2008-07-09 22:15

The only way to do this currently is to code this up yourself using hook_form_alter or via a programmed content type.

For example, one of my types is using this in the hook_form

<?php
  $vocabulary
= taxonomy_vocabulary_load(RCTOPOS_VOCAB_REGION);
 
$form['taxonomy']['regions'] = _taxonomy_term_select(check_plain($vocabulary->name), 'not used', $node->regions, RCTOPOS_VOCAB_REGION, $vocabulary->help, 1, t('- None -'));
 
$form['taxonomy']['regions']['#weight'] = -1;
?>

This loads up the vocabulary and uses the taxonomy select (standard FAPI select element) to insert it into the fieldset that has the other "standard" taxonomy elements. This way I am able to modify it as a multi-select rather than a single select which is the default for that vocabulary.

The next step is to save the data you collect. Using hook_form_alter, you would either hook into node_insert and node_update, or add a submit handler to update a custom field in one of your tables. For a single field or two, this is how I would usually do it.

The following is overkill unless you have a large project.

In this example, I'm adding a lot of extra fields (10+), so without looking to deeply into the taxonomy module, I duplicated the code from the taxonomy module to handle the database queries, using a new table to store the data. I done this as I was worried that if I reused the taxonomy tables, the data may have been overwritten/deleted. (Notice how the taxonomy node_save works, deletes then inserts)

So I created a new table to save my data;

CREATE TABLE term_node_custom (
  nid int(10) unsigned NOT NULL default '0',
  vid int(10) unsigned NOT NULL default '0',
  tid int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (tid,vid),
  KEY vid (vid),
  KEY nid (nid)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

and cloned the following code to do the inserts/updates

<?php
function rctopos_node_load_taxomony_extras($node, $vid) {
 
$result = db_query(db_rewrite_sql('SELECT t.tid FROM {term_data} t INNER JOIN {term_node_custom} r ON r.tid = t.tid WHERE t.vid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $node->vid);
 
$terms = array();
  while (
$term = db_fetch_object($result)) {
   
$terms[] = $term->tid;
  }
  return
$terms;
}

/**
* Save term associations for a given node.
<em>/
function rctopos_node_save($node, $terms) {
  rctopos_node_delete_revision($node);

  if (is_array($terms)) {
    foreach ($terms as $term) {
      if (is_array($term)) {
        foreach ($term as $tid) {
          if ($tid) {
            db_query('INSERT INTO {term_node_custom} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $tid);
          }
        }
      }
      else if (is_object($term)) {
        db_query('INSERT INTO {term_node_custom} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term->tid);
      }
      else if ($term) {
        db_query('INSERT INTO {term_node_custom} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $term);
      }
    }
  }
}

/</em>*
* Remove associations of a node to its terms.
<em>/
function rctopos_node_delete($node) {
  db_query('DELETE FROM {term_node_custom} WHERE nid = %d', $node->nid);
}

/</em>*
* Remove associations of a node to its terms.
*/
function rctopos_node_delete_revision($node) {
 
db_query('DELETE FROM {term_node_custom} WHERE vid = %d', $node->vid);
}
?>

Then these are called via the respective node hooks, load, save, delete, update, and hook_nodeapi operation "delete revision".

It would be nice to simply check a check box on a content type specific taxonomy setting to do all this automatically! Thus the nature of the post wondering about how much interest there is in this to help motivate the taxonomy authors to consider it.

simple work around for required

Alan D. - Wed, 2008-07-09 22:21

If the vocab is not required as a whole, simply use hook_form_alter to flag the tax element as required for each node type that requires it. The node is usually in $form['#node'], and add a check on $form['#node']->type to set the elements required field.

The relevant element to set

jumpfightgo@gro... - Mon, 2008-10-20 20:49

The relevant element to set is '#required'. Print out the $form array and then find the taxonomy you want to be required. Here is an example for Drupal 6:

function YOURMODULE_form_alter(&$form, $form_state, $form_id) {
  // check form id to apply only to specific node type, in this example story node type
  if($form_id == 'story_node_form'){
    // uncomment the next line to view the entire form array
    //print_r($form); 
    // here's where you set the required element, in this case I am requiring the vocabulary 3, you'll have to find the vocabulary you want to require yourself by looking in the form array
    $form['taxonomy'][3]['#required'] = 1;
  }
}