taxonomy.module 30.2 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
Kjartan's avatar
Kjartan committed
2
// $Id$
Dries's avatar
   
Dries committed
3

4
function taxonomy_system($field){
Kjartan's avatar
Kjartan committed
5
  $system["description"] = t("Enables the organization of content into categories.");
6
7
8
  return $system[$field];
}

Kjartan's avatar
Kjartan committed
9
10
function taxonomy_feed() {
  global $id, $or, $and, $type;
Dries's avatar
   
Dries committed
11

Kjartan's avatar
Kjartan committed
12
13
14
15
16
17
18
  if ($type == "voc") {
    //TODO - vocabulary feed. How to represent an outline in XML?
  }
  else {
    if ($or) {
      foreach ((explode(",", $or)) as $t) {
        $terms[] = "'". check_query($t) ."'";
Dries's avatar
   
Dries committed
19
      }
Kjartan's avatar
Kjartan committed
20
21
22
23
24
25
      $result = db_query("SELECT DISTINCT(n.nid), type FROM node n LEFT JOIN term_node r ON n.nid = r.nid WHERE tid IN (". implode(",", $terms) .") AND status = '1' ORDER BY static DESC, created DESC LIMIT 15");
      $term = taxonomy_get_term($or);
    }
    else if ($and) {
      foreach ((explode(",", $and)) as $t) {
        $terms[] = "'". check_query($t) ."'";
Dries's avatar
   
Dries committed
26
      }
27
      $result = db_query("SELECT n.nid, type, count(*) AS c FROM node n LEFT JOIN term_node r ON n.nid = r.nid WHERE tid IN (". implode(",", $terms) .") AND status = '1' GROUP BY n.nid, n.type HAVING c = ". count($terms) ." ORDER BY static DESC, created DESC LIMIT 15");
Kjartan's avatar
Kjartan committed
28
29
30
31
32
      $term = taxonomy_get_term($and);
    }
    else {
      return node_feed();
    }
Dries's avatar
   
Dries committed
33

Kjartan's avatar
Kjartan committed
34
35
36
    $channel["title"] = variable_get("site_name", "drupal") ." - ". $term->name;
    $channel["link"] = path_uri() ."index.php?or=$or";
    $channel["description"] = $term->description;
Dries's avatar
   
Dries committed
37

Kjartan's avatar
Kjartan committed
38
    node_feed($result, $channel);
Dries's avatar
   
Dries committed
39
  }
Kjartan's avatar
Kjartan committed
40
}
Dries's avatar
   
Dries committed
41

Kjartan's avatar
Kjartan committed
42
43
44
function taxonomy_perm() {
  return array("administer taxonomy");
}
Dries's avatar
 
Dries committed
45

Kjartan's avatar
Kjartan committed
46
47
48
function taxonomy_link($type) {
  if ($type == "admin" && user_access("administer taxonomy")) {
    $links[] = la(t("taxonomy"), array("mod" => "taxonomy"));
Dries's avatar
 
Dries committed
49
50
  }

Kjartan's avatar
Kjartan committed
51
52
53
  return $links ? $links : array();
}

Dries's avatar
 
Dries committed
54
55
56
57
/*
** admin pages (form, save, overview)
*/

Kjartan's avatar
Kjartan committed
58
59
60
61
function taxonomy_form_vocabulary($edit = array()) {
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
      $nodetypes[$name] = $name;
Dries's avatar
 
Dries committed
62
    }
Kjartan's avatar
Kjartan committed
63
  }
Dries's avatar
   
Dries committed
64

Dries's avatar
   
Dries committed
65
66
67
68
69
70
71
  $form .= form_textfield(t("Vocabulary name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this vocabulary.  Example: 'Topic'") . ".");
  $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("Description of the vocabulary, can be used by modules."));
  $form .= form_select(t("Types"), "types", explode(",", $edit["types"]), $nodetypes, t("Required") . ". " . t("A list of node types you want to associate this vocabulary with."), "", 1);
  $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") . ". " . t("Allows ". la("related terms", array("mod" => "taxonomy", "op" => "help"), "relatedterms") ." in this vocabulary."));
  $form .= form_select(t("Hierarchy"), "hierarchy", $edit["hierarchy"], array(t("Disabled"), t("Single"), t("Multiple")), t("Optional") . ". ". t("Allows ". la("a tree-like hierarchy", array("mod" => "taxonomy", "op" => "help"), "hierarchy") ." between terms of this vocabulary."), "", 0);
  $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") . ". " . t("Allows nodes to have more than one term in this vocabulary."));
  $form .= form_checkbox(t("Required"), "required", 1, $edit["required"], t("If enabled every node <b>must</b> have at least one term in this vocabulary"));
Dries's avatar
   
Dries committed
72
  $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier vocabularies will sink and the lighter vocabularies will be positioned nearer the top."));
Dries's avatar
   
Dries committed
73
  $form .= form_submit(t("Submit"));
Dries's avatar
 
Dries committed
74

Kjartan's avatar
Kjartan committed
75
  if ($edit["vid"]) {
Dries's avatar
   
Dries committed
76
    $form .= form_submit(t("Delete"));
Kjartan's avatar
Kjartan committed
77
    $form .= form_hidden("vid", $edit["vid"]);
Dries's avatar
 
Dries committed
78
79
  }

Kjartan's avatar
Kjartan committed
80
81
  return form($form);
}
Kjartan's avatar
Kjartan committed
82

Kjartan's avatar
Kjartan committed
83
84
85
86
function taxonomy_save_vocabulary($edit) {
  $data = array("name" => $edit["name"], "types" => @implode(",", $edit["types"]), "description" => $edit["description"], "multiple" => $edit["multiple"], "required" => $edit["required"], "hierarchy" => $edit["hierarchy"], "relations" => $edit["relations"], "weight" => $edit["weight"]);

  if ($edit["vid"] && $edit["name"]) {
Dries's avatar
   
Dries committed
87
    db_query("UPDATE vocabulary SET ". _prepare_update($data) ." WHERE vid = '". check_query($edit["vid"]) ."'");
Dries's avatar
   
Dries committed
88
    return t("update vocabulary '%name'.", array("%name" => $edit["name"]));
Dries's avatar
 
Dries committed
89
  }
Kjartan's avatar
Kjartan committed
90
  else if ($edit["vid"]) {
Dries's avatar
   
Dries committed
91
    return taxonomy_del_vocabulary($edit["vid"]);
Kjartan's avatar
Kjartan committed
92
93
94
  }
  else {
    db_query("INSERT INTO vocabulary ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
   
Dries committed
95
    return t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
96
  }
Dries's avatar
   
Dries committed
97
98

  cache_clear_all();
Kjartan's avatar
Kjartan committed
99
}
Dries's avatar
 
Dries committed
100

Kjartan's avatar
Kjartan committed
101
function taxonomy_del_vocabulary($vid) {
Dries's avatar
   
Dries committed
102
103
  $vocabulary = taxonomy_get_vocabulary($vid);

Dries's avatar
   
Dries committed
104
105
  db_query("DELETE FROM vocabulary WHERE vid = '%d'", $vid);
  $result = db_query("SELECT tid FROM term_data WHERE vid = '%d'", $vid);
Kjartan's avatar
Kjartan committed
106
107
  while ($term = db_fetch_object($result)) {
    taxonomy_del_term($term->tid);
Dries's avatar
 
Dries committed
108
  }
Dries's avatar
   
Dries committed
109

Dries's avatar
   
Dries committed
110
111
  cache_clear_all();

Dries's avatar
   
Dries committed
112
113
114
115
116
117
118
119
120
121
122
123
124
  return t("deleted vocabulary '%name'.", array("%name" => $vocabulary->name));
}

function _taxonomy_confirm_del_vocabulary($vid) {
  $vocabulary = taxonomy_get_vocabulary($vid);

  $form .= form_hidden("confirm", 1);
  $form .= form_hidden("type", "vocabulary");
  $form .= form_hidden("vid", $vid);
  $form .= form_submit(t("Delete"));
  $form .= form_submit(t("Cancel"));

  return form(form_item(t("Delete vocabulary '%name'", array("%name" => $vocabulary->name)), $form, t("Are you sure you want to delete the vocabulary and all its terms?")));
Kjartan's avatar
Kjartan committed
125
}
Dries's avatar
 
Dries committed
126

Kjartan's avatar
Kjartan committed
127
128
129
130
131
132
function taxonomy_form_term($edit = array()) {
  global $vocabulary_id;
  if (!$vocabulary_id) {
    $vocabulary_id = $edit["vid"];
  }
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
Dries's avatar
   
Dries committed
133
134
  $form = form_textfield(t("Term name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this term.  Example: 'Linux'."));
  $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("A description of the term."));
Dries's avatar
 
Dries committed
135

Kjartan's avatar
Kjartan committed
136
  if ($vocabulary->relations) {
Dries's avatar
   
Dries committed
137
    $form .= _taxonomy_term_select(t("Related terms"), "relations", array_keys(taxonomy_get_related($edit["tid"])), $vocabulary_id, t("Optional") . ". ", 1, "<" . t("none") . ">", array($edit["tid"]));
Kjartan's avatar
Kjartan committed
138
  }
Dries's avatar
 
Dries committed
139
140


Kjartan's avatar
Kjartan committed
141
142
  if ($vocabulary->hierarchy) {
    $parent = array_keys(taxonomy_get_parents($edit["tid"]));
Dries's avatar
   
Dries committed
143
    $children = taxonomy_get_tree($vocabulary_id, $edit["tid"]);
Kjartan's avatar
Kjartan committed
144
145
146
147
    // you can't be son of yourself or your children
    $exclude = array_keys($children);
    $exclude[] = $edit["tid"];
    if ($vocabulary->hierarchy == 1) {
Dries's avatar
   
Dries committed
148
      $form .= _taxonomy_term_select(t("Parent"), "parent", $parent, $vocabulary_id, t("Required") . ". " . la(t("Parent term"), array("mod" => "taxonomy", "op" => "help"), "parent") .".", 0, "<" . t("root") . ">", $exclude);
Dries's avatar
 
Dries committed
149
    }
Kjartan's avatar
Kjartan committed
150
    elseif ($vocabulary->hierarchy == 2) {
Dries's avatar
   
Dries committed
151
      $form .= _taxonomy_term_select(t("Parents"), "parent", $parent, $vocabulary_id, t("Required") . ". ". la(t("Parent terms"), array("mod" => "taxonomy", "op" => "help"), "parent") .".", 1, "<" . t("root") . ">", $exclude);
Dries's avatar
 
Dries committed
152
    }
Kjartan's avatar
Kjartan committed
153
  }
Dries's avatar
 
Dries committed
154

Dries's avatar
   
Dries committed
155
156
  $form .= form_textarea(t("Synonyms"), "synonyms", implode("\n", taxonomy_get_synonyms($edit["tid"])), 30, 5, t("Optional") . ". ". t(la("Synonyms", array("mod" => "taxonomy", "op" => "help"), "synonyms") ." of this term, one synonym per line."));
  $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top."));
Kjartan's avatar
Kjartan committed
157
  $form .= form_hidden("vid", $vocabulary->vid);
Dries's avatar
   
Dries committed
158
  $form .= form_submit(t("Submit"));
Kjartan's avatar
Kjartan committed
159
160

  if ($edit["tid"]) {
Dries's avatar
   
Dries committed
161
    $form .= form_submit(t("Delete"));
Kjartan's avatar
Kjartan committed
162
    $form .= form_hidden("tid", $edit["tid"]);
Dries's avatar
 
Dries committed
163
164
  }

Kjartan's avatar
Kjartan committed
165
166
  return form($form);
}
Dries's avatar
 
Dries committed
167

Kjartan's avatar
Kjartan committed
168
169
170
function taxonomy_save_term($edit) {
 if ($edit["tid"] && $edit["name"]) {
    $data = array("name" => $edit["name"], "description" => $edit["description"], "weight" => $edit["weight"]);
Dries's avatar
 
Dries committed
171

Dries's avatar
   
Dries committed
172
    db_query("UPDATE term_data SET ". _prepare_update($data) ." WHERE tid = '%d'", $edit["tid"]);
Dries's avatar
   
Dries committed
173
    $message = t("Term <b>%a</b> updated.", array("%a" => $edit["name"]));
Kjartan's avatar
Kjartan committed
174
175
  }
  else if ($edit["tid"]) {
Dries's avatar
   
Dries committed
176
    return taxonomy_del_term($edit["tid"]);
Kjartan's avatar
Kjartan committed
177
178
  }
  else {
Dries's avatar
   
Dries committed
179
    $edit["tid"] = db_next_id("term_data");
Kjartan's avatar
Kjartan committed
180
181
    $data = array("tid" => $edit["tid"], "name" => $edit["name"], "description" => $edit["description"], "vid" => $edit["vid"], "weight" => $edit["weight"]);
    db_query("INSERT INTO term_data ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
   
Dries committed
182
183

    $message = t("created new term '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
184
  }
Dries's avatar
 
Dries committed
185

Kjartan's avatar
Kjartan committed
186
  // relations (seem very powerful, but I have to understand it completely)
Dries's avatar
   
Dries committed
187
  db_query("DELETE FROM term_relation WHERE tid1 = '%d' OR tid2 = '%d'", $edit["tid"], $edit["tid"]);
Kjartan's avatar
Kjartan committed
188
189
190
  if ($edit["relations"]) {
    foreach ($edit["relations"] as $related_id) {
      if ($related_id != 0) {
Dries's avatar
   
Dries committed
191
        db_query("INSERT INTO term_relation (tid1, tid2) VALUES ('%d', '%d')", $edit["tid"], $related_id);
Dries's avatar
 
Dries committed
192
      }
Kjartan's avatar
Kjartan committed
193
    }
Kjartan's avatar
Kjartan committed
194
  }
Dries's avatar
 
Dries committed
195

Kjartan's avatar
Kjartan committed
196
  // hierarchy
Dries's avatar
   
Dries committed
197
  db_query("DELETE FROM term_hierarchy WHERE tid = '%d'", $edit["tid"]);
Kjartan's avatar
Kjartan committed
198
199
200
201
202
  if (!isset($edit["parent"])) {
    $edit["parent"] = 0;
  }
  if (is_array($edit["parent"])) {
    foreach ($edit["parent"] as $parent) {
Dries's avatar
   
Dries committed
203
      db_query("INSERT INTO term_hierarchy (tid, parent) VALUES ('%d', '%d')", $edit["tid"], $parent);
Dries's avatar
 
Dries committed
204
    }
Kjartan's avatar
Kjartan committed
205
206
  }
  else {
Dries's avatar
   
Dries committed
207
    db_query("INSERT INTO term_hierarchy (tid, parent) VALUES ('%d', '%d')", $edit["tid"], $edit["parent"][0]);
Dries's avatar
 
Dries committed
208
209
  }

Kjartan's avatar
Kjartan committed
210
  // synonyms (very cool idea indeed)
Dries's avatar
   
Dries committed
211
  db_query("DELETE FROM term_synonym WHERE tid = '%d'", $edit["tid"]);
Kjartan's avatar
Kjartan committed
212
  if ($edit["synonyms"]) {
Dries's avatar
   
Dries committed
213
214
215
216
    foreach (explode ("\n", str_replace("\r", "", $edit["synonyms"])) as $synonym) {
      if ($synonym) {
        db_query("INSERT INTO term_synonym (tid, name) VALUES ('%d', '%s')", $edit["tid"], chop($synonym));
      }
Kjartan's avatar
Kjartan committed
217
    }
Dries's avatar
 
Dries committed
218
  }
Dries's avatar
   
Dries committed
219

Dries's avatar
   
Dries committed
220
221
  cache_clear_all();

Dries's avatar
   
Dries committed
222
  return $message;
Kjartan's avatar
Kjartan committed
223
}
Dries's avatar
 
Dries committed
224

Kjartan's avatar
Kjartan committed
225
function taxonomy_del_term($tid) {
Dries's avatar
   
Dries committed
226
227
  $term = taxonomy_get_term($tid);

Dries's avatar
   
Dries committed
228
229
230
231
232
  db_query("DELETE FROM term_data WHERE tid = '%d'", $tid);
  db_query("DELETE FROM term_hierarchy WHERE tid = '%d'", $tid);
  db_query("DELETE FROM term_relation WHERE tid1 = '%d' OR tid2 = '%d'", $tid, $tid);
  db_query("DELETE FROM term_synonym WHERE tid = '%d'", $tid);
  db_query("DELETE FROM term_node WHERE tid = '%d'", $tid);
Dries's avatar
   
Dries committed
233

Dries's avatar
   
Dries committed
234
235
  cache_clear_all();

Dries's avatar
   
Dries committed
236
237
238
239
240
241
242
243
244
245
246
247
248
  return t("deleted term '%name'.", array("%name" => $term->name));
}

function _taxonomy_confirm_del_term($tid) {
  $term = taxonomy_get_term($tid);

  $form .= form_hidden("confirm", 1);
  $form .= form_hidden("type", "term");
  $form .= form_hidden("tid", $tid);
  $form .= form_submit(t("Delete"));
  $form .= form_submit(t("Cancel"));

  return form(form_item(t("Delete term '%name'", array("%name" => $term->name)), $form, t("Are you sure you want to delete the term?")));
Kjartan's avatar
Kjartan committed
249
}
Dries's avatar
 
Dries committed
250

Kjartan's avatar
Kjartan committed
251
252
function taxonomy_overview() {
  global $tree;
Dries's avatar
 
Dries committed
253

Dries's avatar
   
Dries committed
254
  $output .= "<h3>" . t("Vocabularies overview") . "</h3>";
Kjartan's avatar
Kjartan committed
255
  $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
Dries's avatar
   
Dries committed
256
  $output .= " <tr><th>" . t("name") . "</th><th>" . t("node types") . "</th><th>" . t("operations") . "</th></tr>\n";
Dries's avatar
   
Dries committed
257

Kjartan's avatar
Kjartan committed
258
259
260
261
262
263
  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies as $vocabulary) {
    $links = array();
    $links[] = la(t("edit vocabulary"), array("mod" => "taxonomy", "type" => "vocabulary", "op" => "edit", "id" => $vocabulary->vid));
    $links[] = la(t("add term"), array("mod" => "taxonomy", "op" => "add", "type" => "leaf", "vocabulary_id" => $vocabulary->vid));
    $links[] = la(t("preview form"), array("mod" => "taxonomy", "type" => "vocabulary", "op" => "preview", "id" => $vocabulary->vid));
Dries's avatar
 
Dries committed
264

Dries's avatar
   
Dries committed
265
    $output .= " <tr><td>". check_output($vocabulary->name) ."</td><td align=\"center\">". check_output($vocabulary->types) ."</td><td>". implode(" | ", $links) ."</td></tr>\n";
Kjartan's avatar
Kjartan committed
266

Dries's avatar
   
Dries committed
267
    $tree = taxonomy_get_tree($vocabulary->vid);
Kjartan's avatar
Kjartan committed
268
269
270
271
    if ($tree) {
      $output .= "<tr><td colspan=\"3\"><table><tr><td>";
      foreach ($tree as $term) {
        $output .= "<tr><td>". la(_taxonomy_depth($term->depth) . check_output($term->name), array("mod" => "taxonomy", "op" => "edit", "type" => "term", "id" => check_output($term->tid))) ."</td></tr>";
Dries's avatar
 
Dries committed
272
      }
Kjartan's avatar
Kjartan committed
273
      $output .= "</td></tr></table></td></tr>\n";
Dries's avatar
 
Dries committed
274
275
    }
  }
Kjartan's avatar
Kjartan committed
276
  $output .= "</table>\n";
Dries's avatar
 
Dries committed
277

Kjartan's avatar
Kjartan committed
278
279
280
281
282
283
284
285
286
287
288
  return $output;
}

function taxonomy_form($vocabulary_id, $value = 0) {
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
  if ($vocabulary->required) {
    $verb = "must";
    $blank = 0;
  }
  else {
    $verb = "can";
Dries's avatar
   
Dries committed
289
    $blank = "<" . t("none") . ">";
Kjartan's avatar
Kjartan committed
290
  }
Dries's avatar
   
Dries committed
291

Kjartan's avatar
Kjartan committed
292
  if ($vocabulary->multiple) {
Dries's avatar
   
Dries committed
293
    $description = t("You $verb choose one or more terms for this node.");
Kjartan's avatar
Kjartan committed
294
    $multiple = 1;
Dries's avatar
 
Dries committed
295
  }
Kjartan's avatar
Kjartan committed
296
  else {
Dries's avatar
   
Dries committed
297
    $description = t("You $verb choose one term for this node.");
Kjartan's avatar
Kjartan committed
298
299
300
301
    $multiple = 0;
  }
  return _taxonomy_term_select($vocabulary->name, "taxonomy", $value, $vocabulary_id, $description, $multiple, $blank);
}
Dries's avatar
 
Dries committed
302
303
304
305
306

/*
** API functions
*/

Kjartan's avatar
Kjartan committed
307
308
309
310
311
312
313
314
315
316
317
// return array of vocabularies, as objects
function taxonomy_get_vocabularies($type = '', $key = "vid") {
  if ($type) {
    $result = db_query("SELECT * FROM vocabulary WHERE types LIKE '%%%s%%' ORDER BY weight, name", $type);
  }
  else {
    $result = db_query("SELECT * FROM vocabulary ORDER BY weight, name");
  }
  $vocabularies = array();
  while ($voc = db_fetch_object($result)) {
    $vocabularies[$voc->$key] = $voc;
Dries's avatar
 
Dries committed
318
  }
Kjartan's avatar
Kjartan committed
319
320
  return $vocabularies;
}
Dries's avatar
 
Dries committed
321

Kjartan's avatar
Kjartan committed
322
323
324
325
326
// return form with current term
function taxonomy_node_form($type, $node = '') {
  if (!$node->taxonomy) {
    if ($node->nid) {
      $terms = array_keys(taxonomy_node_get_terms($node->nid));
Kjartan's avatar
Kjartan committed
327
328
    }
    else {
Kjartan's avatar
Kjartan committed
329
      $terms = 0;
Dries's avatar
 
Dries committed
330
    }
Kjartan's avatar
Kjartan committed
331
332
333
334
  }
  else {
    $terms = $node->taxonomy;
  }
Dries's avatar
 
Dries committed
335

Kjartan's avatar
Kjartan committed
336
337
338
  $c = db_query("SELECT * FROM vocabulary WHERE types LIKE '%%%s%%' ORDER BY weight, name", $type);
  while ($vocabulary = db_fetch_object($c)) {
    $result[] .= taxonomy_form($vocabulary->vid, $terms);
Dries's avatar
 
Dries committed
339
  }
Kjartan's avatar
Kjartan committed
340
341
  return $result ? $result : array();
}
Dries's avatar
 
Dries committed
342

Kjartan's avatar
Kjartan committed
343
344
345
// return 1 if node identified by $nid contains a taxonomy term identified by $tid in his body or title
function taxonomy_node_has_term($nid, $tid) {
  $term_name = db_result(db_query("SELECT name FROM term_data WHERE tid = '%s'", $tid));
Dries's avatar
 
Dries committed
346

Dries's avatar
   
Dries committed
347
  return db_result(db_query("SELECT COUNT(n.nid) FROM node n WHERE n.nid = '%d' AND ((n.body LIKE '%%%s%%') OR (n.body LIKE '%%%s%%'))", $nid, $term_name, $term_name));
Kjartan's avatar
Kjartan committed
348
349
350
351
}

// return array of terms of a node beloging to a particular vocabulary identified by $vid
function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = "tid") {
Dries's avatar
   
Dries committed
352
  $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE t.tid = r.tid AND t.vid = '%d' AND r.nid = '%d' ORDER BY weight", $vid, $nid);
Kjartan's avatar
Kjartan committed
353
354
355
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries's avatar
 
Dries committed
356
  }
Kjartan's avatar
Kjartan committed
357
358
359
360
361
362
  return $terms;
}

// return array of terms of a node
function taxonomy_node_get_terms($nid, $key = "tid") {
  static $terms;
Dries's avatar
 
Dries committed
363

Dries's avatar
   
Dries committed
364
  if (!isset($terms[$nid])) {
Dries's avatar
   
Dries committed
365
    $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE r.tid = t.tid AND r.nid = '%d' ORDER BY weight, name", $nid);
Kjartan's avatar
Kjartan committed
366
    $terms[$nid] = array();
Dries's avatar
 
Dries committed
367
    while ($term = db_fetch_object($result)) {
Kjartan's avatar
Kjartan committed
368
      $terms[$nid][$term->$key] = $term;
Dries's avatar
 
Dries committed
369
370
    }
  }
Kjartan's avatar
Kjartan committed
371
372
  return $terms[$nid];
}
Dries's avatar
 
Dries committed
373

Kjartan's avatar
Kjartan committed
374
375
376
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries's avatar
 
Dries committed
377

Kjartan's avatar
Kjartan committed
378
  if ($terms) {
Dries's avatar
   
Dries committed
379
380
    foreach ($terms as $term) {
      db_query("INSERT INTO term_node (nid, tid) VALUES ('%d', '%d')", $nid, $term);
Dries's avatar
 
Dries committed
381
382
    }
  }
Kjartan's avatar
Kjartan committed
383
}
Dries's avatar
 
Dries committed
384

Kjartan's avatar
Kjartan committed
385
386
// clean up terms
function taxonomy_node_delete($nid) {
Dries's avatar
   
Dries committed
387
  db_query("DELETE FROM term_node WHERE nid = '%d'", $nid);
Kjartan's avatar
Kjartan committed
388
}
Dries's avatar
 
Dries committed
389

Kjartan's avatar
Kjartan committed
390
391
392
// relations: return array of related terms
function taxonomy_get_related($tid, $key = "tid") {
  if ($tid) {
Dries's avatar
   
Dries committed
393
    $result = db_query("SELECT t.*, tid1, tid2 FROM term_relation, term_data t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = '%d' OR tid2 = '%d') AND t.tid != '%d' ORDER BY weight, name", $tid, $tid, $tid);
Kjartan's avatar
Kjartan committed
394
395
396
    $related = array();
    while ($term = db_fetch_object($result)) {
      $related[$term->$key] = $term;
Dries's avatar
 
Dries committed
397
    }
Kjartan's avatar
Kjartan committed
398
    return $related;
Dries's avatar
 
Dries committed
399
  }
Kjartan's avatar
Kjartan committed
400
401
  else {
    return array();
Dries's avatar
 
Dries committed
402
  }
Kjartan's avatar
Kjartan committed
403
}
Dries's avatar
 
Dries committed
404

Kjartan's avatar
Kjartan committed
405
406
407
// hierarchy: get parent terms
function taxonomy_get_parents($tid, $key = "tid") {
  if ($tid) {
Dries's avatar
   
Dries committed
408
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.parent = t.tid AND h.tid = '%d' ORDER BY weight, name", $tid);
Kjartan's avatar
Kjartan committed
409
410
411
    $parents = array();
    while ($parent = db_fetch_object($result)) {
      $parents[$parent->$key] = $parent;
Dries's avatar
   
Dries committed
412
    }
Kjartan's avatar
Kjartan committed
413
    return $parents;
Dries's avatar
 
Dries committed
414
  }
Kjartan's avatar
Kjartan committed
415
416
417
418
  else {
    return array();
  }
}
Dries's avatar
 
Dries committed
419

Kjartan's avatar
Kjartan committed
420
421
422
// hierarchy: get children
function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
  if ($vid) {
Dries's avatar
   
Dries committed
423
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE t.vid = '%d' AND h.tid = t.tid AND h.parent = '%d' ORDER BY weight, name", $vid, $tid);
Dries's avatar
 
Dries committed
424
  }
Kjartan's avatar
Kjartan committed
425
  else {
Dries's avatar
   
Dries committed
426
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.tid = t.tid AND parent = '%d' ORDER BY weight", $tid);
Kjartan's avatar
Kjartan committed
427
428
429
430
431
432
433
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries's avatar
 
Dries committed
434

Kjartan's avatar
Kjartan committed
435
// hierarchy: get whole family, with tid, parent and depth; useful to show
Dries's avatar
   
Dries committed
436
437
function taxonomy_get_tree($vocabulary_id, $parent = 0, $depth = -1, $key = "tid") {
  static $children, $parents, $terms, $tree;
Kjartan's avatar
Kjartan committed
438
  if ($depth == -1) {
Dries's avatar
 
Dries committed
439
    $children = array();
Dries's avatar
   
Dries committed
440
441
    $parents = array();
    $terms = array();
Kjartan's avatar
Kjartan committed
442
    $tree = array();
Dries's avatar
 
Dries committed
443
  }
Dries's avatar
   
Dries committed
444

Kjartan's avatar
Kjartan committed
445
  $depth++;
Dries's avatar
   
Dries committed
446
447
448
449
450
451
452

  if (!count($children)) {
    $result = db_query("SELECT t.*, parent FROM term_data t, term_hierarchy h WHERE t.tid = h.tid AND t.vid = '%d' ORDER BY weight, name", $vocabulary_id);
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
      $parents[$term->tid][] = $term->parent;
      $terms[$term->tid] = $term;
Dries's avatar
 
Dries committed
453
454
    }
  }
Dries's avatar
   
Dries committed
455
456
457
458
459
460
461
462
463
464

  if ($children[$parent]) {
    foreach ($children[$parent] as $child) {
      $terms[$child]->depth = $depth;
      unset($terms[$child]->parent); // this would show just one parent
      $terms[$child]->parents = $parents[$child];
      $tree[] = $terms[$child];

      taxonomy_get_tree($vocabulary_id, $child, $depth, $key);
    }
Kjartan's avatar
Kjartan committed
465
  }
Dries's avatar
   
Dries committed
466
467

  return $tree;
Kjartan's avatar
Kjartan committed
468
}
Dries's avatar
 
Dries committed
469

Kjartan's avatar
Kjartan committed
470
471
472
// synonyms: return array of synonyms
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries's avatar
   
Dries committed
473
    $result = db_query("SELECT name FROM term_synonym WHERE tid = '%d'", $tid);
Kjartan's avatar
Kjartan committed
474
475
    while ($synonym = db_fetch_array($result)) {
      $synonyms[] = $synonym["name"];
Dries's avatar
 
Dries committed
476
    }
Kjartan's avatar
Kjartan committed
477
    return $synonyms ? $synonyms : array();
Dries's avatar
 
Dries committed
478
  }
Kjartan's avatar
Kjartan committed
479
480
  else {
    return array();
Dries's avatar
   
Dries committed
481
  }
Kjartan's avatar
Kjartan committed
482
}
Dries's avatar
   
Dries committed
483

Kjartan's avatar
Kjartan committed
484
485
486
487
// synonyms: return original term
function taxonomy_get_synonym_root($term) {
  return db_fetch_object(db_query("SELECT * FROM term_synonym s, term_data t WHERE t.tid = s.tid AND s.name = '%s'", $term));
}
Dries's avatar
   
Dries committed
488

Kjartan's avatar
Kjartan committed
489
// given a term id, count number of nodes in it
Dries's avatar
   
Dries committed
490
function taxonomy_term_count_nodes($tid, $type = 0) {
Kjartan's avatar
Kjartan committed
491
  static $count;
Dries's avatar
   
Dries committed
492

Dries's avatar
   
Dries committed
493
494
495
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries's avatar
   
Dries committed
496
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t GROUP BY t.tid");
Dries's avatar
   
Dries committed
497
498
    }
    else {
Dries's avatar
   
Dries committed
499
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t, node n WHERE t.nid = n.nid AND n.type = '%s' GROUP BY t.tid", $type);
Dries's avatar
   
Dries committed
500
    }
Kjartan's avatar
Kjartan committed
501
    while ($term = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
502
      $count[$type][$term->tid] = $term->c;
Dries's avatar
   
Dries committed
503
504
505
    }
  }

Kjartan's avatar
Kjartan committed
506
  foreach (_taxonomy_term_children($tid) as $c) {
Dries's avatar
   
Dries committed
507
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan's avatar
Kjartan committed
508
  }
Dries's avatar
   
Dries committed
509
  return $count[$type][$tid] + $children_count;
Kjartan's avatar
Kjartan committed
510
511
512
513
514
}

// helper for above function
function _taxonomy_term_children($tid) {
  static $children;
Dries's avatar
   
Dries committed
515

Dries's avatar
   
Dries committed
516
  if (!isset($children)) {
Kjartan's avatar
Kjartan committed
517
518
519
    $result = db_query("SELECT tid, parent FROM term_hierarchy");
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries's avatar
   
Dries committed
520
    }
Dries's avatar
 
Dries committed
521
  }
Kjartan's avatar
Kjartan committed
522
523
  return $children[$tid] ? $children[$tid] : array();
}
Dries's avatar
 
Dries committed
524

Dries's avatar
   
Dries committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
/**
 * Try to map a string to existing vocabularies
 * Provide case insensitive and trimmed map so as to
 * maximize likelihood of successful mapping.
 *
 * @param   string  $name  Name of the vocabulary to search
 * @return  array   array of matching vocabularies, as objects
 */
function taxonomy_get_vocabulary_by_name($name) {
  // LOWER is ANSI SQL-92
  $db_result = db_query("SELECT * FROM vocabulary WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
  $result = array();
  while ($vocabulary = db_fetch_object($db_result)) {
    $result[] = $vocabulary;
  }

  return $result;
}

/**
 * Try to map a string to existing terms
 * Provide case insensitive and trimmed map so as to
 * maximize likelihood of successful mapping.
 *
 * @param   string  $name  Name of the term to search
 * @return  array   array of matching terms, as objects
 */
function taxonomy_get_term_by_name($name) {
  // LOWER is ANSI SQL-92
  $db_result = db_query("SELECT * FROM term_data WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
  $result = array();
  while ($term = db_fetch_object($db_result)) {
    $result[] = $term;
  }

  return $result;
}

Kjartan's avatar
Kjartan committed
563
564
function taxonomy_get_vocabulary($vid) {
  // simple cache using a static var?
Dries's avatar
   
Dries committed
565
  return db_fetch_object(db_query("SELECT * FROM vocabulary WHERE vid = '%d'", $vid));
Kjartan's avatar
Kjartan committed
566
}
Dries's avatar
 
Dries committed
567

Kjartan's avatar
Kjartan committed
568
569
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries's avatar
   
Dries committed
570
  return db_fetch_object(db_query("SELECT * FROM term_data WHERE tid = '%d'", $tid));
Kjartan's avatar
Kjartan committed
571
}
Dries's avatar
 
Dries committed
572
573
574
575
576

/*
** service functions
*/

Kjartan's avatar
Kjartan committed
577
function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
Dries's avatar
   
Dries committed
578
  $tree = taxonomy_get_tree($vocabulary_id);
Dries's avatar
 
Dries committed
579

Kjartan's avatar
Kjartan committed
580
581
582
  if ($blank) {
    $options[0] = $blank;
  }
Dries's avatar
 
Dries committed
583

Kjartan's avatar
Kjartan committed
584
585
586
587
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
        $options[$term->tid] = _taxonomy_depth($term->depth, '-').$term->name;
Dries's avatar
 
Dries committed
588
589
      }
    }
Kjartan's avatar
Kjartan committed
590
591
592
593
594
    if (!$blank && !$value) {
      // required but without a predefined value, so set first as predefined
      $value = $tree[0]->tid;
    }
  }
Dries's avatar
 
Dries committed
595

Kjartan's avatar
Kjartan committed
596
597
598
599
  if (count($options) > 0) {
    foreach ($options as $key=>$choice) {
      $select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
    }
Dries's avatar
 
Dries committed
600

Dries's avatar
   
Dries committed
601
    $size = min(12, count($options));
Dries's avatar
 
Dries committed
602

Kjartan's avatar
Kjartan committed
603
    return form_item($title, "<select name=\"edit[$name][]\"". ($multiple ? " multiple size=\"$size\"" : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries's avatar
 
Dries committed
604
  }
Kjartan's avatar
Kjartan committed
605
}
Dries's avatar
 
Dries committed
606

Kjartan's avatar
Kjartan committed
607
608
609
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries's avatar
 
Dries committed
610
  }
Kjartan's avatar
Kjartan committed
611
612
  return $result;
}
Dries's avatar
 
Dries committed
613

Kjartan's avatar
Kjartan committed
614
615
616
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries's avatar
 
Dries committed
617
  }
Kjartan's avatar
Kjartan committed
618
619
620
  $result = implode(", ", $q);
  return $result;
}
Dries's avatar
 
Dries committed
621

Kjartan's avatar
Kjartan committed
622
623
624
625
626
627
628
function _prepare_insert($data, $stage) {
  if ($stage == 1) {
    $result = implode(", ", array_keys($data));
  }
  else {
    foreach (array_values($data) as $value) {
      $q[] = "'". check_query($value) ."'";
Dries's avatar
 
Dries committed
629
    }
Kjartan's avatar
Kjartan committed
630
    $result = implode(", ", $q);
Dries's avatar
 
Dries committed
631
  }
Kjartan's avatar
Kjartan committed
632
633
  return "($result)";
}
Dries's avatar
   
Dries committed
634

Kjartan's avatar
Kjartan committed
635
636
function taxonomy_page() {
  global $op;
Dries's avatar
   
Dries committed
637

Kjartan's avatar
Kjartan committed
638
639
640
641
642
643
  switch ($op) {
    case "feed":
      taxonomy_feed();
      break;
    default:
       // TODO: pretty display of all vocabularies
Dries's avatar
   
Dries committed
644
  }
Kjartan's avatar
Kjartan committed
645
}
Dries's avatar
   
Dries committed
646

Kjartan's avatar
Kjartan committed
647
/*
Dries's avatar
 
Dries committed
648
649
650
** admin
*/

Kjartan's avatar
Kjartan committed
651
function taxonomy_admin() {
Dries's avatar
   
Dries committed
652
  global $edit, $type, $op, $id, $theme;
Kjartan's avatar
Kjartan committed
653
654
655
656
657
658
659

  if (user_access("administer taxonomy")) {
    $links[] = la(t("add new vocabulary"), array("mod" => "taxonomy", "op" => "add", "type" => "vocabulary"));
    $links[] = la(t("overview"), array("mod" => "taxonomy"));
    $links[] = la(t("help"), array("mod" => "taxonomy", "op" => "help"));

    print "<small>". implode(" | ", $links) ."</small><hr>\n";
Dries's avatar
 
Dries committed
660

Kjartan's avatar
Kjartan committed
661
662
    switch ($op) {
      case "add":
Kjartan's avatar
Kjartan committed
663
        if ($type == "vocabulary") {
Kjartan's avatar
Kjartan committed
664
          print taxonomy_form_vocabulary();
Kjartan's avatar
Kjartan committed
665
666
        }
        else {
Kjartan's avatar
Kjartan committed
667
          print taxonomy_form_term();
Kjartan's avatar
Kjartan committed
668
        }
Kjartan's avatar
Kjartan committed
669
670
        break;
      case "edit":
Kjartan's avatar
Kjartan committed
671
        if ($type == "vocabulary") {
Kjartan's avatar
Kjartan committed
672
          print taxonomy_form_vocabulary(object2array(taxonomy_get_vocabulary($id)));
Kjartan's avatar
Kjartan committed
673
674
        }
        else {
Kjartan's avatar
Kjartan committed
675
          print taxonomy_form_term(object2array(taxonomy_get_term($id)));
Kjartan's avatar
Kjartan committed
676
        }
Kjartan's avatar
Kjartan committed
677
678
        break;
      case "preview":
Kjartan's avatar
Kjartan committed
679
        print taxonomy_form($id);
Kjartan's avatar
Kjartan committed
680
681
682
683
        break;
      case "help":
        print taxonomy_help();
        break;
Dries's avatar
   
Dries committed
684
      case t("Delete"):
Dries's avatar
   
Dries committed
685
686
687
688
689
690
691
692
693
694
695
696
697
        if (!$edit["confirm"]) {
          if ($type == "vocabulary") {
            echo _taxonomy_confirm_del_vocabulary($edit["vid"]);
          }
          else {
            echo _taxonomy_confirm_del_term($edit["tid"]);
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries's avatar
   
Dries committed
698
      case t("Submit"):
Kjartan's avatar
Kjartan committed
699
        if ($type == "vocabulary") {
Kjartan's avatar
Kjartan committed
700
          print status(taxonomy_save_vocabulary($edit));
Kjartan's avatar
Kjartan committed
701
702
        }
        else {
Kjartan's avatar
Kjartan committed
703
          print status(taxonomy_save_term($edit));
Dries's avatar
   
Dries committed
704
705
706
707
708
709
          if (!$edit["tid"]) {
            // if INSERT show form again
            print taxonomy_form_term();
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan's avatar
Kjartan committed
710
        }
Kjartan's avatar
Kjartan committed
711
712
713
714
715
716
717
718
719
720
721
722
        // fall through:
      default:
        print taxonomy_overview();
    }
  }
  else {
    print message_access();
  }
}

function taxonomy_help() {
  ?>
Dries's avatar
   
Dries committed
723
724
725
726
727
728

  <h3>Background</h3>
  <p>Classifying nodes allows for the organization of content into categories and subcategories of description. These categories can be used to organize and retrieve similarly described content. Drupal's <i>taxonomy.module</i> is an extremely flexible classification system that allows for multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms) and taxonomies (controlled vocabularies where relationships are indicated hierarchically). For details about <a href="http://www.eleganthack.com/archives/002165.html#002165">classification types</a> and insight into the development of <i>taxonomy.module</i>, see this <a href="http://www.drupal.org/node.php?id=55">drupal.org discussion</a>.</p>

  <h3>An example taxonomy: food</h3>
  <p>Dairy <br />
Kjartan's avatar
Kjartan committed
729
730
731
732
733
734
735
736
737
738
739
  --Milk <br />
  Drink <br />
  --Alchohol <br />
  --Pop <br />
  --Milk<br />
  Meat <br />
  --Beef <br />
  --Chicken <br />
  --Lamb <br />
  Spices <br />
  --Sugar</p>
Dries's avatar
   
Dries committed
740
741
742
743
744
745
  <p><b>Notes</b></p>
   <ul>
   <li>The term <i>Milk</i> appears within both <i>Dairy</i> and <i>Drink</i>.  This is an example of <i>nmultiple parents</i> for a term.</li>
   <li>The order of siblings (e.g. <i>Beef</i>, <i>Chicken</i>, <i>Lamb</i>) in the taxonomy may be controlled with the <i>weight</i> parameter. </li>
  </ul>

Kjartan's avatar
Kjartan committed
746
  <h3>Vocabularies</h3>
Dries's avatar
   
Dries committed
747
  <p>When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each node of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to <a href="http://www.slashdot.com/">Slashdot's</a> sections.  For more complex implementations, you might create a hierarchical list of categories such as the example <i>Food</i> taxonomy above.</p>
Kjartan's avatar
Kjartan committed
748
749

  <h4>Setting up a vocabulary</h4>
Dries's avatar
   
Dries committed
750
751
752
  <p>When you set up a controlled vocabulary, you will be asked to enter some descriptive data and define the attributes of this vocabulary. For example, if you select the <i>hierarchy</i> option, you will be defining a taxonomy or a thesaurus. If you select <i>related terms</i> option, you are allowing the definition of related terms as in a thesaurus. Selecting <i>multiple select</i> will allow you to describe a node using more than one term. That node will then appear in each term's page, thus increasing the chance that a user will find it.</p>

  <i>Vocabulary name</i><br />Required. The name for this vocabulary. Example: <i>Dairy</i>.<br />
Kjartan's avatar
Kjartan committed
753
  <br />
Dries's avatar
   
Dries committed
754
  <i>Description</i><br />Optional. Description of the vocabulary, can be used by modules and feeds.<br />
Kjartan's avatar
Kjartan committed
755
  <br />
Dries's avatar
   
Dries committed
756
  <i>Types</i><br />Required. The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.<br />
Kjartan's avatar
Kjartan committed
757
  <br />
Dries's avatar
   
Dries committed
758
  <i><a name="relatedterms"></a>Related terms</i><br />Allows relationships between terms within this vocabulary. Think of these as <i>see also</i>-references.<br />
Kjartan's avatar
Kjartan committed
759
  <br />
Dries's avatar
   
Dries committed
760
  <i><a name="hierarchy"></a>Hierarchy</i><br />Allows a tree-like taxonomy, as in our <i>Foods</i> example above<br />
Kjartan's avatar
Kjartan committed
761
  <br />
Dries's avatar
   
Dries committed
762
763
  <i>Multiple select</i><br />Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.<br />

Kjartan's avatar
Kjartan committed
764
  <h4>Adding terms to a vocabulary</h4>
Dries's avatar
   
Dries committed
765
766
767
<p>The options you see when adding a term to a vocabulary will depend on what you selected for <i>related terms</i>, <i>hierarchy </i>and <i>multiple select</i> when you created the corrosponding vocabulary.</p>

  <i>Term name</i><br />Required. The name for this term. Example: <i>Milk</i><br />
Kjartan's avatar
Kjartan committed
768
  <br />
Dries's avatar
   
Dries committed
769
  <i>Description</i><br />Optional. Description of the term that may be used by modules and RSS feeds.  This is synonymous with a 'scope note'.<br />
Kjartan's avatar
Kjartan committed
770
  <br />
Dries's avatar
   
Dries committed
771
  <i><a name="parent"></a>Parent</i><br />Required. Select the term under which this term is a subset -- the branch of the hierarchy that this term belongs under. This is also known as the "Broader term" indicator used in thesauri.<br />
Kjartan's avatar
Kjartan committed
772
  <br />
Dries's avatar
   
Dries committed
773
774
775
  <i><a name="synonyms"></a>Synonyms</i><br />Optional. Enter synonyms for this term, one synonym per line. Synonyms can be used for variant spellings, acronyms, and other terms that have the same meaning as the added term, but which are not explicitly listed in this thesaurus (i.e. <i>unauthorized terms</i>).<br />

  <h3>Displaying nodes organized by term(s)</h3>
Dries's avatar
   
Dries committed
776
  <p>In order to view the nodes associated with a term or a collection of terms, you should browse to a properly formed URL. For example, see <a href="<?php print path_uri().drupal_url(array("mod" => "node", "or" => "1,2"), "module"); ?>"><?php print path_uri().drupal_url(array("mod" => "node", "or" => "1,2"), "module"); ?></a>.  Taxonomy URLs always contain  a term ID or list of term IDs at the end of the URL (aka <i>querystring</i>). You may learn the term ID for a given term by hovering over that term in the <?php echo la("taxonomy overview", array("mod" => "taxonomy")) ?> page in the Admin and noting the number after the querystring parameter called <i>tid</i>.  If you wish to see nodes from a collection of term IDs, separate each term ID with a comma.  Also, the name of the querystring parameter may be <i>or</i> or <i>and</i>: <i>or</i> shows nodes which appear in <b>any</b> of the term IDs while <i>and</i> shows nodes in <b>all</b> the specified term IDs.  Thus, <i>or</i> is less specific than <i>and</i>.</p>
Dries's avatar
   
Dries committed
777
778
779
780

  <h3>RSS feeds</h3>
  <p>Every term, or collection of terms, provides an <a href="http://backend.userland.com/stories/rss091">RSS</a> feed to which interested users may subscribe. The URL format for an sample RSS feed is <a href="<?php print path_uri().drupal_url(array("mod" => "node", "op" => "feed", "or" => "1,2"), "module"); ?>"><?php print path_uri().drupal_url(array("mod" => "node", "op" => "feed", "or" => "1,2"), "module"); ?></a>.</p>
 <?php
Kjartan's avatar
Kjartan committed
781
}
Dries's avatar
   
Dries committed
782
?>