I've been trying to figure out a way for Child nodes (using the Node Relativity module) to inherit the parent taxonomy terms.
After trying to get this to work for a couple of days without success, and realizing that I was having problems with Node Auto Term NG. I found your Taxonomy defaults module that allows you to specify default taxonomy terms for nodes which I thought was a good start.
Unfortunately, the terms are not dynamic. What I was able to do was edit this module to allow optional dynamic default terms via passing a nid in the node create URL although I've only tested using the Node Auto Term NG module which adds the parent nid in the URL.
The code is most likely a bit messy as I have very little experience in module development (I haven't actually made a module), and I don't know how to make a patch file.
But here is the code that can replace the taxonomy_defaults.module and taxonomy_defaults.admin.inc files using Taxonomy Defaults module version 6.x-1.0
It would be good for someone to look at this code and test and or clean up a bit more. I thought I would post it here as this could be the start of a feature in future versions, unless it'd be best to create a standalone module.
<?php
// $Id: taxonomy_defaults.module,v 1.11.2.3.2.4 2008/12/04 04:20:44 sleepcamel Exp $
/**
* @file
* Taxonomy defaults - allows assignment of default terms to node types, either
* - hidden, added after node submission. Change is not possible.
* - preselected in the category form for vocabularies assigned to the node type. Change is allowed.
*/
/**
* Implementation of hook_help().
*
*/
function taxonomy_defaults_help($path, $arg) {
switch ($path) {
case 'admin/content/taxonomy/taxonomy_defaults':
$output = '<p>'. t("Below you may select default terms for each content type. Check the 'Enabled' box next to the vocabulary, then select the terms.") .'</p>' ;
// dean - added extra output
$output .= '<div class="help-insert"><p>'. t("<strong>Note:</strong> Used for taxonomy term inheritance and <a href='http://drupal.org/project/nat_ng' title='Node Auto Term NG'><strong>Node Auto Term NG</strong></a> module compatibility.") .'</p>' ;
$output .= '<p>'. t("If an arg() is given (e.g. 0, 1, 2, 3 etc.), this will make the node inherit the terms from the parent node (only from that vocab) via the relavent nid passed in the URL argment. This will override any default term specified in the 'Default Terms' select list. <strong>arg() must be empty (or 'Enabled' unchecked) to disable.</strong>") .'</p>' ;
$output .= '<p>'. t("If the parent nodes taxonomy term is stored using the Node Auto Term NG module, select 'nat_ng' as the term will is not stored in the parents 'taxonomy' array, but rather the nat_ng array. It will however, still be stored in the created nodes taxonomy array.") .'</p>' ;
$output .= '</div>';
// - fin
return $output;
}
}
/**
* Define a custom callback to assign default terms menu at a tab on admin/taxonomy.
*
* Implementation of hook_menu.
*/
function taxonomy_defaults_menu() {
$items['admin/content/taxonomy/taxonomy_defaults'] = array(
'type' => MENU_LOCAL_TASK,
'title' => 'Default terms',
'page callback' => 'drupal_get_form',
'page arguments' => array('taxonomy_defaults_form'),
'access arguments' => array('administer site configuration'),
'file' => 'taxonomy_defaults.admin.inc',
);
return $items;
}
/**
* Implementation of hook_theme.
*
* @return unknown
*/
function taxonomy_defaults_theme() {
return array(
'taxonomy_defaults_form' => array(
'arguments' => array('form'),
'file' => 'taxonomy_defaults.admin.inc',
),
);
}
/**
* Adds the defaults for active vocabularies as preselected terms to '$node->taxonomy'
* This requires a weight lower than taxonomy.module.
*/
function taxonomy_defaults_form_alter(&$form, &$form_state, $form_id) {
// Only alter node forms
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id && !isset($form_state['node_preview'])) {
$node = $form['#node']; $prenode = node_load($node->nid);
// Do not preselect terms on nodes that already have been edited
if (!isset($node->nid)) {
// dean - get node parent terms
// - fin
// Add the default 'pre-selected' terms to $node->taxonomy
foreach (taxonomy_get_vocabularies($node->type) as $vid => $vocab) {
if (variable_get("taxdef_{$node->type}_{$vid}_active", FALSE)) {
// -----------------------------------------------------------------------------------------------
// dean - check if arg() specified in admin settings
$tax_arg = variable_get("taxdef_{$node->type}_{$vid}_argument", FALSE);
if ($tax_arg != FALSE) {
// dean - check arg() is valid
$default_tids = array();
if (is_numeric(arg($tax_arg))) {
// dean - load parent node
$parent_node = node_load(arg($tax_arg));
// dean - check if nat_ng checked else use regular taxonomy field
if (variable_get("taxdef_{$node->type}_{$vid}_nat_ng", FALSE)) {
foreach ($parent_node->nat_ng as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
} else {
foreach ($parent_node->taxonomy as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
}
// dean - apply taxonomy to node
foreach ($default_tids as $default_tid) {
$term = taxonomy_get_term($default_tid);
$form['#node']->taxonomy[$default_tid] = $term;
}
} else {
/*
* If no argument, check if updating node and therfore carry over existing terms
*/
foreach ($prenode->taxonomy as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
foreach ($default_tids as $default_tid) {
$term = taxonomy_get_term($default_tid);
$form['#node']->taxonomy[$default_tid] = $term;
}
}
} else {
// -----------------------------------------------------------------------------------------------
$default_tids = variable_get("taxdef_{$node->type}_{$vid}", array());
foreach ($default_tids as $default_tid) {
$term = taxonomy_get_term($default_tid);
$form['#node']->taxonomy[$default_tid] = $term;
}
}
}
}
}
}
}
/**
* Adds selected default terms from non-active vocabularies to newly created nodes
*/
function taxonomy_defaults_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($op == 'presave') {
$taxonomy = $node->taxonomy; if ($node->nid) { $prenode = node_load($node->nid); }
$type_vocabularies = taxonomy_get_vocabularies($node->type);
foreach (taxonomy_get_vocabularies() as $vid => $vocab) {
$activevocab = array_key_exists($vid, $type_vocabularies);
// Active vocabs have been inserted via the form already and may have been modified by the user
if (!$activevocab && variable_get("taxdef_{$node->type}_{$vid}_active", FALSE)) {
// dean - check if arg() specified in admin settings
$tax_arg = variable_get("taxdef_{$node->type}_{$vid}_argument", FALSE);
if ($tax_arg != FALSE) {
// dean - check arg() is valid
$default_tids = array();
if (is_numeric(arg($tax_arg))) {
// dean - load parent node
$parent_node = node_load(arg($tax_arg));
// dean - check if nat_ng checked else use regular taxonomy field
if (variable_get("taxdef_{$node->type}_{$vid}_nat_ng", FALSE)) {
foreach ($parent_node->nat_ng as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
} else {
foreach ($parent_node->taxonomy as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
}
// dean - apply taxonomy to node
$taxonomy[$vid] = $vocab->multiple ? $default_tids : $default_tids[0];
} else {
/*
* If no argument, check if updating node and therfore carry over existing terms
*/
if ($prenode) {
foreach ($prenode->taxonomy as $term) {
if ($term->vid == $vid) {
$default_tids[] = $term->tid;
}
}
$taxonomy[$vid] = $vocab->multiple ? $default_tids : $default_tids[0];
}
}
} else {
$default_tids = variable_get("taxdef_{$node->type}_{$vid}", array());
$taxonomy[$vid] = $vocab->multiple ? $default_tids : $default_tids[0];
}
}
}
if (isset($taxonomy)) {
//$node->taxonomy = $taxonomy;
$node->taxonomy = array_unique($taxonomy);
}
}
}<?php
// $Id: taxonomy_defaults.admin.inc,v 1.1.2.4 2008/12/20 18:11:52 sleepcamel Exp $
/**
* Defines the page at admin/content/taxonomy/taxonomy_defaults.
*/
function taxonomy_defaults_form() {
// For each node type we generate per vocabulary a checkbox & term select.
$form['#tree'] = TRUE;
$vocabularies = taxonomy_get_vocabularies();
foreach (node_get_types() as $type => $name) {
$type_vocabularies = taxonomy_get_vocabularies($type);
// Loop over all vocabularies
foreach ($vocabularies as $vid => $vocab) {
$activevocab = array_key_exists($vid, $type_vocabularies);
$form[$type][$vid]['active'] = array(
'#type' => 'checkbox',
'#default_value' => variable_get("taxdef_{$type}_{$vid}_active", FALSE),
'#weight' => -16,
);
// dean - insert arg() and nat_ng text field and checkbox
$form[$type][$vid]['argument'] = array(
'#type' => 'textfield',
'#default_value' => variable_get("taxdef_{$type}_{$vid}_argument", FALSE),
'#size' => 2,
'#maxlength' => 2,
'#required' => FALSE,
);
$form[$type][$vid]['nat_ng'] = array(
'#type' => 'checkbox',
'#default_value' => variable_get("taxdef_{$type}_{$vid}_nat_ng", FALSE),
'#weight' => -15,
);
// - fin
$form[$type][$vid]['name'] = array('#value' => t( $vocab->name ) );
if ($vocab->tags) {
$form[$type][$vid]['tags'] = array('#type' => 'textfield',
/* '#title' => $vocabulary->name,
'#description' => $help,
'#required' => $vocabulary->required,
'#default_value' => $typed_string,*/
'#autocomplete_path' => 'taxonomy/autocomplete/'. $vocabulary->vid,
'#weight' => $vocabulary->weight,
'#maxlength' => 255,
);
} else {
$form[$type][$vid]['select'] = taxonomy_form($vid, variable_get("taxdef_{$type}_{$vid}", 0));
}
$form[$type][$vid]['tip'] = array('#value' => $activevocab ? '' : '<p>'. t('The <strong>!vocab</strong> vocabulary is not enabled for the <strong>!type</strong> content type. Default terms will be added to the content without appearing on the add and edit pages.</p>', array('!vocab'=>$vocab->name, '!type'=>$name->name) ) );
}
if (count($vocabularies) > 0) {
$form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration') );
$form['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset to defaults') );
}
else {
$form['text'] = array(
'#value' => t('Before you can assign default terms to node types, go to !link to create and fill vocabularies.', array('!link' => l(t('add vocabulary'), 'admin/content/taxonomy/add/vocabulary'))),
);
}
}
return $form;
}
/**
* Store settings in the variable table.
*/
function taxonomy_defaults_form_submit($form, &$form_state) {
$op = $form_state['clicked_button']['op'];
// dean - Note: for some reason, Reseting to defaults does not work -- Needs fixing
if ($op == t('Reset to defaults')) {
foreach (node_get_types() as $type => $name) {
foreach ($form_state['values'][$type] as $vid => $values) {
variable_del("taxdef_{$type}_{$vid}_active");
// Dean - 31-03-10
variable_del("taxdef_{$type}_{$vid}_argument");
variable_del("taxdef_{$type}_{$vid}_nat_ng");
// - fin
variable_del("taxdef_{$type}_{$vid}");
}
}
drupal_set_message(t('The configuration options have been reset to their default values.'));
}
else {
foreach (node_get_types() as $type => $name) {
foreach ($form_state['values'][$type] as $vid => $values) {
variable_set("taxdef_{$type}_{$vid}_active", $values['active']);
// Dean - 31-03-10
variable_set("taxdef_{$type}_{$vid}_argument", $values['argument']);
variable_set("taxdef_{$type}_{$vid}_nat_ng", $values['nat_ng']);
// - fin
if ($values['active']) {
variable_set("taxdef_{$type}_{$vid}", is_array($values['select']) ? $values['select'] : array($values['select']));
}
}
}
drupal_set_message(t('The configuration options have been saved.'));
}
}
/**
* Renders the settings form in a table.
*/
function theme_taxonomy_defaults_form($form) {
drupal_add_css(drupal_get_path('module', 'taxonomy_defaults') .'/taxonomy_defaults.css', 'module', 'all', FALSE);
$output = '';
foreach (node_get_types() as $type => $name) {
$rowcount = 0;
foreach (element_children($form[$type]) as $key) {
$form[$type][$key]['select']['#title']='';
$vocabtable[$rowcount][] = drupal_render($form[$type][$key]['name']);
$vocabtable[$rowcount][] = drupal_render($form[$type][$key]['active']);
// Dean
$vocabtable[$rowcount][] = drupal_render($form[$type][$key]['argument']);
$vocabtable[$rowcount][] = drupal_render($form[$type][$key]['nat_ng']);
// - fin
$vocabtable[$rowcount][] = drupal_render($form[$type][$key]['select']);
$vocabtable[$rowcount][] = array( 'data' => drupal_render($form[$type][$key]['tip']) );
$rowcount++;
}
// dean - insert argument in subtable
// old - $subtable = theme('table', array(t('Vocabulary'),t('Enabled'),t('Default Terms'), t('Notes')), $vocabtable);
$subtable = theme('table', array(t('Vocabulary'),t('Enabled'),t('arg()'),t('nat_ng'),t('Default Terms'), t('Notes')), $vocabtable);
// - fin
unset($vocabtable);
$fieldset = array(
'#title' => $name->name,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#value' => $subtable,
);
$output .= theme('fieldset', $fieldset);
}
// Render remaining fields
$output .= drupal_render($form);
return $output;
}
Admin screen-shot attached.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | taxonomy_defaults.module.patch | 7.59 KB | dean.p |
| #2 | taxonomy_defaults.admin_.inc_.patch | 3.32 KB | dean.p |
| Picture 5.png | 110.18 KB | dean.p |
Comments
Comment #1
bradweikel commentedDean,
I appreciate your desire to contribute new features to this module, but it's really time consuming for a module maintainer to work with anything but patch files, and many flat refuse to do so.
I'd highly suggest using this as a chance to learn to create patch files. You can get started at http://drupal.org/patch/create
Thanks,
Brad
Comment #2
dean.p commentedHey, thanks for the heads up Brad. Sorry about that, making a patch file turned out to be quite simple ;)
Patch files attached.
Comment #3
summit commentedSubscribing, greetings, Martijn