Create multiple nodes with the same (persistent) taxonomy categories.
Say a site has a very deep taxonomy structure, and a user wants to create a number of nodes in the same category. This can be rather frustrating for them to have to scroll through and select the correct taxonomy for each node added.
This mini-module was based on the taxonomy_defaults.module but saves taxonomy submitted in a session variable for re-use rather than overriding all node creations with admin configured values. Of course, as a result you might get unwanted conflicts between the two (check their weights).
I called this taxonomy_session_defaults.module, but anything suitable will do.
1. Create a directory under modules named taxonomy_session_defaults.
2. Put the following in taxonomy_session_defaults.module:
<?php
/**
* Adds the last saved session values for active vocabularies as preselected terms to '$node->taxonomy'
* This requires a weight lower than taxonomy.module.
*
* This may well conflict with taxonomy_defaults.module, you may want to tweak the weights of these.
*/
function taxonomy_session_defaults_form_alter($form_id, &$form) {
// Only alter node forms
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
$node = $form['#node'];
// Do not override terms on nodes that already have been edited
if (!isset($node->nid)) {
// Add the default session terms to this form
foreach (taxonomy_get_vocabularies($node->type) as $vid => $vocab) {
if ($_SESSION["taxses_{$node->type}_{$vid}"]) {
$session_tids = split(",", $_SESSION["taxses_{$node->type}_{$vid}"]);
foreach ($session_tids as $tid) {
$term = taxonomy_get_term($tid);
$form['#node']->taxonomy[$tid] = $term;
}
}
}
}
}
}
/**
* Saves the selected taxonomy so it's used again in the next node created.
*/
function taxonomy_session_defaults_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($op == 'submit') {
$taxonomy = $node->taxonomy;
foreach ($taxonomy as $vid => $terms) {
if (is_array($terms)) {
// Save the array of terms
$_SESSION["taxses_{$node->type}_{$vid}"] = join(",", $terms);
} else if ($terms != 0) {
// Save a single term
$_SESSION["taxses_{$node->type}_{$vid}"] = $terms;
} else {
// Remove anything previously saved
unset($_SESSION["taxses_{$node->type}_{$vid}"]);
}
}
}
}
?>3. Put the following in taxonomy_session_defaults.info:
name = Taxonomy Session Defaults
description = Assign default taxonomy terms per node-type based on last saved node.
dependencies = taxonomy
version = "5.x-0.1"4. Put the following in taxonomy_session_defaults.install:
<?php
/**
* Hook sets taxonomy_session_defaults 'weight' to -2.
* This ensures that it's hook_form_alter runs before taxonomy & taxonomy_defaults.
* Admins may wish to tweak this weight.
*
*/
function taxonomy_session_defaults_install() {
$ret = array();
$ret[] = db_query("UPDATE {system} SET weight = -2 WHERE name = 'taxonomy_session_defaults'");
return $ret;
}
?>5. Visit modules admin page and enable the new module.

Revised code
Here is a revised version of this mini module as per this GHOP issue. It adheres more to the coding convention.
taxonomy_session_defaults.module
<?php
/**
* Adds the last saved session values for active vocabularies as preselected
* terms to '$node->taxonomy'.
* This requires a weight lower than taxonomy.module.
*
* This may well conflict with taxonomy_defaults.module, you may want to tweak
* the weights of these.
*/
function taxonomy_session_defaults_form_alter($form_id, &$form) {
// Only alter node forms
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
$node = $form['#node'];
// Do not override terms on nodes that already have been edited
if (!isset($node->nid)) {
// Add the default session terms to this form
foreach (taxonomy_get_vocabularies($node->type) as $vid => $vocab) {
$key = 'taxonomy_session_'. $node->type .'_'. $vid;
if ($_SESSION[$key]) {
$session_tids = split(',', $_SESSION[$key]);
foreach ($session_tids as $tid) {
$term = taxonomy_get_term($tid);
$form['#node']->taxonomy[$tid] = $term;
}
}
}
}
}
}
/**
* Saves the selected taxonomy so it's used again in the next node created.
*/
function taxonomy_session_defaults_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($op == 'submit') {
foreach ($node->taxonomy as $vid => $terms) {
$key = 'taxonomy_session_'. $node->type .'_'. $vid;
if (is_array($terms)) {
// Save the array of terms
$_SESSION[$key] = join(',', $terms);
}
else if ($terms != 0) {
// Save a single term
$_SESSION[$key] = $terms;
}
else {
// Remove anything previously saved
unset($_SESSION[$key]);
}
}
}
}
?>
Don't forget to leave out the
?>at the end, as it is known to cause problems.taxonomy_session_defaults.install
<?php/**
* Hook sets taxonomy_session_defaults 'weight' to -2.
* This ensures that its hook_form_alter runs before taxonomy and
* taxonomy_defaults.
* Admins may wish to tweak this weight.
*/
function taxonomy_session_defaults_install() {
$ret = array();
$ret[] = db_query("UPDATE {system} SET weight = -2 WHERE name = 'taxonomy_session_defaults'");
return $ret;
}
?>
Again, don't forget to leave out the
?>at the end, as it is known to cause problems.taxonomy_session_defaults.info can be left as it is.
I changed
I changed
taxonomy_session_defaults_form_alterfor being able to also set Taxonomy via GETs.E.g. it's useful for giving the user an oppurtunity to post a picture in the current gallery - without the need of selecting the gallery's term. Therefore just place a link like
node/add/picture?tax_1=23(1 is the number of the vocabulary and 23 the number of the gallery's taxonomy term.) in your gallery's node view.<?phpfunction taxonomy_session_defaults_form_alter($form_id, &$form) {
// Only alter node forms
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
$node = $form['#node'];
// Do not override terms on nodes that already have been edited
if (!isset($node->nid)) {
// Add the default session terms to this form
foreach (taxonomy_get_vocabularies($node->type) as $vid => $vocab) {
$key = 'taxonomy_session_'. $node->type .'_'. $vid;
$session_tids = array();
if ($_GET['tax_'.$vid]){// GET-request is handled before SESSION-value
$session_tids = split(',', $_GET['tax_'.$vid]);
}
elseif ($_SESSION[$key]) {
$session_tids = split(',', $_SESSION[$key]);
}
foreach ($session_tids as $tid) {
$term = taxonomy_get_term($tid);
$form['#node']->taxonomy[$tid] = $term;
}
}
}
}
}
?>
Some coding style issues
If you want to save session storage then simply use
t_unlikely someone else does the same with the same key structure. If you want to be readable then usetaxonomy_session_as prefix. Aka: "do or do not, there is no try". Useif (isset())instead ofif()to avoid notices. Finally,"t_{$node->type}_{$vid}"is just plain ugly, use single quotes and concat with a dot.--
The news is Now Public | Drupal development: making the world better, one patch at a time. | A bedroom without a teddy is like a face without a smile. |
Minor style
One last little style issue is that in Drupal code we prefer that
} else {actually be done:
}else {